Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 18 Feb 2013 21:34:11 +0000 (22:34 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 18 Feb 2013 21:34:11 +0000 (22:34 +0100)
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: (35 commits)
  PM idle: remove global declaration of pm_idle
  unicore32 idle: delete stray pm_idle comment
  openrisc idle: delete pm_idle
  mn10300 idle: delete pm_idle
  microblaze idle: delete pm_idle
  m32r idle: delete pm_idle, and other dead idle code
  ia64 idle: delete pm_idle
  cris idle: delete idle and pm_idle
  ARM64 idle: delete pm_idle
  ARM idle: delete pm_idle
  blackfin idle: delete pm_idle
  sparc idle: rename pm_idle to sparc_idle
  sh idle: rename global pm_idle to static sh_idle
  x86 idle: rename global pm_idle to static x86_idle
  APM idle: register apm_cpu_idle via cpuidle
  tools/power turbostat: display SMI count by default
  intel_idle: export both C1 and C1E
  cpuidle: remove vestage definition of cpuidle_state_usage.driver_data
  x86 idle: remove 32-bit-only "no-hlt" parameter, hlt_works_ok flag
  x86 idle: remove mwait_idle() and "idle=mwait" cmdline param
  ...

Conflicts:
arch/x86/kernel/process.c (with PM / tracing commit 43720bd)
drivers/acpi/processor_idle.c (with ACPICA commit 4f84291)

539 files changed:
Documentation/ABI/testing/sysfs-devices-power_resources_D0 [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-power_resources_D1 [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-power_resources_D2 [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-power_resources_D3hot [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-power_state [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-real_power_state [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-resource_in_use [new file with mode: 0644]
Documentation/acpi/enumeration.txt
Documentation/acpi/scan_handlers.txt [new file with mode: 0644]
Documentation/cpu-freq/cpu-drivers.txt
Documentation/cpu-freq/user-guide.txt
Documentation/devicetree/bindings/arm/kirkwood.txt [new file with mode: 0644]
Documentation/kernel-parameters.txt
Documentation/power/freezing-of-tasks.txt
Documentation/power/runtime_pm.txt
Documentation/trace/events-power.txt
Documentation/x86/boot.txt
MAINTAINERS
Makefile
arch/arm/boot/dts/highbank.dts
arch/arm/common/gic.c
arch/arm/include/asm/memory.h
arch/arm/kernel/smp_twd.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/include/mach/cpufreq.h
arch/arm/mach-highbank/Kconfig
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-realview/include/mach/irqs-eb.h
arch/arm/mach-tegra/cpu-tegra.c
arch/arm/mm/dma-mapping.c
arch/avr32/include/asm/dma-mapping.h
arch/blackfin/include/asm/dma-mapping.h
arch/c6x/include/asm/dma-mapping.h
arch/cris/include/asm/dma-mapping.h
arch/frv/include/asm/dma-mapping.h
arch/ia64/hp/common/aml_nfw.c
arch/ia64/include/asm/acpi.h
arch/m68k/include/asm/dma-mapping.h
arch/mn10300/include/asm/dma-mapping.h
arch/parisc/include/asm/dma-mapping.h
arch/powerpc/mm/hash_low_64.S
arch/x86/Kconfig
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/acpi.h
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_p6.c
arch/x86/kernel/process.c
arch/x86/platform/olpc/olpc-xo15-sci.c
arch/x86/tools/insn_sanity.c
arch/xtensa/include/asm/dma-mapping.h
block/genhd.c
drivers/Kconfig
drivers/Makefile
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/ac.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/acpi_pad.c
drivers/acpi/acpi_platform.c
drivers/acpi/acpica/Makefile
drivers/acpi/acpica/accommon.h
drivers/acpi/acpica/acdebug.h
drivers/acpi/acpica/acdispat.h
drivers/acpi/acpica/acevents.h
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/achware.h
drivers/acpi/acpica/acinterp.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acmacros.h
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/acobject.h
drivers/acpi/acpica/acopcode.h
drivers/acpi/acpica/acparser.h
drivers/acpi/acpica/acpredef.h
drivers/acpi/acpica/acresrc.h
drivers/acpi/acpica/acstruct.h
drivers/acpi/acpica/actables.h
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/amlcode.h
drivers/acpi/acpica/amlresrc.h
drivers/acpi/acpica/dsargs.c
drivers/acpi/acpica/dscontrol.c
drivers/acpi/acpica/dsfield.c
drivers/acpi/acpica/dsinit.c
drivers/acpi/acpica/dsmethod.c
drivers/acpi/acpica/dsmthdat.c
drivers/acpi/acpica/dsobject.c
drivers/acpi/acpica/dsopcode.c
drivers/acpi/acpica/dsutils.c
drivers/acpi/acpica/dswexec.c
drivers/acpi/acpica/dswload.c
drivers/acpi/acpica/dswload2.c
drivers/acpi/acpica/dswscope.c
drivers/acpi/acpica/dswstate.c
drivers/acpi/acpica/evevent.c
drivers/acpi/acpica/evglock.c
drivers/acpi/acpica/evgpe.c
drivers/acpi/acpica/evgpeblk.c
drivers/acpi/acpica/evgpeinit.c
drivers/acpi/acpica/evgpeutil.c
drivers/acpi/acpica/evhandler.c [new file with mode: 0644]
drivers/acpi/acpica/evmisc.c
drivers/acpi/acpica/evregion.c
drivers/acpi/acpica/evrgnini.c
drivers/acpi/acpica/evsci.c
drivers/acpi/acpica/evxface.c
drivers/acpi/acpica/evxfevnt.c
drivers/acpi/acpica/evxfgpe.c
drivers/acpi/acpica/evxfregn.c
drivers/acpi/acpica/exconfig.c
drivers/acpi/acpica/exconvrt.c
drivers/acpi/acpica/excreate.c
drivers/acpi/acpica/exdebug.c
drivers/acpi/acpica/exdump.c
drivers/acpi/acpica/exfield.c
drivers/acpi/acpica/exfldio.c
drivers/acpi/acpica/exmisc.c
drivers/acpi/acpica/exmutex.c
drivers/acpi/acpica/exnames.c
drivers/acpi/acpica/exoparg1.c
drivers/acpi/acpica/exoparg2.c
drivers/acpi/acpica/exoparg3.c
drivers/acpi/acpica/exoparg6.c
drivers/acpi/acpica/exprep.c
drivers/acpi/acpica/exregion.c
drivers/acpi/acpica/exresnte.c
drivers/acpi/acpica/exresolv.c
drivers/acpi/acpica/exresop.c
drivers/acpi/acpica/exstore.c
drivers/acpi/acpica/exstoren.c
drivers/acpi/acpica/exstorob.c
drivers/acpi/acpica/exsystem.c
drivers/acpi/acpica/exutils.c
drivers/acpi/acpica/hwacpi.c
drivers/acpi/acpica/hwesleep.c
drivers/acpi/acpica/hwgpe.c
drivers/acpi/acpica/hwpci.c
drivers/acpi/acpica/hwregs.c
drivers/acpi/acpica/hwsleep.c
drivers/acpi/acpica/hwtimer.c
drivers/acpi/acpica/hwvalid.c
drivers/acpi/acpica/hwxface.c
drivers/acpi/acpica/hwxfsleep.c
drivers/acpi/acpica/nsaccess.c
drivers/acpi/acpica/nsalloc.c
drivers/acpi/acpica/nsdump.c
drivers/acpi/acpica/nsdumpdv.c
drivers/acpi/acpica/nseval.c
drivers/acpi/acpica/nsinit.c
drivers/acpi/acpica/nsload.c
drivers/acpi/acpica/nsnames.c
drivers/acpi/acpica/nsobject.c
drivers/acpi/acpica/nsparse.c
drivers/acpi/acpica/nspredef.c
drivers/acpi/acpica/nsprepkg.c [new file with mode: 0644]
drivers/acpi/acpica/nsrepair.c
drivers/acpi/acpica/nsrepair2.c
drivers/acpi/acpica/nssearch.c
drivers/acpi/acpica/nsutils.c
drivers/acpi/acpica/nswalk.c
drivers/acpi/acpica/nsxfeval.c
drivers/acpi/acpica/nsxfname.c
drivers/acpi/acpica/nsxfobj.c
drivers/acpi/acpica/psargs.c
drivers/acpi/acpica/psloop.c
drivers/acpi/acpica/psobject.c [new file with mode: 0644]
drivers/acpi/acpica/psopcode.c
drivers/acpi/acpica/psopinfo.c [new file with mode: 0644]
drivers/acpi/acpica/psparse.c
drivers/acpi/acpica/psscope.c
drivers/acpi/acpica/pstree.c
drivers/acpi/acpica/psutils.c
drivers/acpi/acpica/pswalk.c
drivers/acpi/acpica/psxface.c
drivers/acpi/acpica/rsaddr.c
drivers/acpi/acpica/rscalc.c
drivers/acpi/acpica/rscreate.c
drivers/acpi/acpica/rsdump.c
drivers/acpi/acpica/rsdumpinfo.c [new file with mode: 0644]
drivers/acpi/acpica/rsinfo.c
drivers/acpi/acpica/rsio.c
drivers/acpi/acpica/rsirq.c
drivers/acpi/acpica/rslist.c
drivers/acpi/acpica/rsmemory.c
drivers/acpi/acpica/rsmisc.c
drivers/acpi/acpica/rsserial.c
drivers/acpi/acpica/rsutils.c
drivers/acpi/acpica/rsxface.c
drivers/acpi/acpica/tbfadt.c
drivers/acpi/acpica/tbfind.c
drivers/acpi/acpica/tbinstal.c
drivers/acpi/acpica/tbutils.c
drivers/acpi/acpica/tbxface.c
drivers/acpi/acpica/tbxfload.c
drivers/acpi/acpica/tbxfroot.c
drivers/acpi/acpica/utaddress.c
drivers/acpi/acpica/utalloc.c
drivers/acpi/acpica/utcache.c
drivers/acpi/acpica/utcopy.c
drivers/acpi/acpica/utdebug.c
drivers/acpi/acpica/utdecode.c
drivers/acpi/acpica/utdelete.c
drivers/acpi/acpica/uteval.c
drivers/acpi/acpica/utexcep.c
drivers/acpi/acpica/utglobal.c
drivers/acpi/acpica/utids.c
drivers/acpi/acpica/utinit.c
drivers/acpi/acpica/utlock.c
drivers/acpi/acpica/utmath.c
drivers/acpi/acpica/utmisc.c
drivers/acpi/acpica/utmutex.c
drivers/acpi/acpica/utobject.c
drivers/acpi/acpica/utosi.c
drivers/acpi/acpica/utownerid.c [new file with mode: 0644]
drivers/acpi/acpica/utresrc.c
drivers/acpi/acpica/utstate.c
drivers/acpi/acpica/utstring.c [new file with mode: 0644]
drivers/acpi/acpica/uttrack.c
drivers/acpi/acpica/utxface.c
drivers/acpi/acpica/utxferror.c
drivers/acpi/acpica/utxfinit.c
drivers/acpi/acpica/utxfmutex.c
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/container.c
drivers/acpi/csrt.c [new file with mode: 0644]
drivers/acpi/custom_method.c
drivers/acpi/device_pm.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/hed.c
drivers/acpi/internal.h
drivers/acpi/numa.c
drivers/acpi/osl.c
drivers/acpi/pci_bind.c [deleted file]
drivers/acpi/pci_link.c
drivers/acpi/pci_root.c
drivers/acpi/pci_slot.c
drivers/acpi/power.c
drivers/acpi/proc.c
drivers/acpi/processor_driver.c
drivers/acpi/sbs.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/sleep.h
drivers/acpi/sysfs.c
drivers/acpi/tables.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/ata/libata-acpi.c
drivers/atm/iphase.h
drivers/base/power/domain.c
drivers/base/power/opp.c
drivers/base/power/wakeup.c
drivers/bcma/bcma_private.h
drivers/bcma/driver_chipcommon_nflash.c
drivers/bcma/driver_gpio.c
drivers/bcma/main.c
drivers/block/drbd/drbd_req.c
drivers/block/drbd/drbd_req.h
drivers/block/drbd/drbd_state.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkfront.c
drivers/char/hpet.c
drivers/char/sonypi.c
drivers/char/virtio_console.c
drivers/clk/Makefile
drivers/clk/clk-highbank.c
drivers/clk/mvebu/clk-gating-ctrl.c
drivers/clk/x86/Makefile [new file with mode: 0644]
drivers/clk/x86/clk-lpss.c [new file with mode: 0644]
drivers/clk/x86/clk-lpss.h [new file with mode: 0644]
drivers/clk/x86/clk-lpt.c [new file with mode: 0644]
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Kconfig.x86
drivers/cpufreq/Makefile
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/cpufreq-cpu0.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/db8500-cpufreq.c
drivers/cpufreq/exynos-cpufreq.c
drivers/cpufreq/exynos4210-cpufreq.c
drivers/cpufreq/exynos4x12-cpufreq.c
drivers/cpufreq/exynos5250-cpufreq.c
drivers/cpufreq/freq_table.c
drivers/cpufreq/highbank-cpufreq.c [new file with mode: 0644]
drivers/cpufreq/imx6q-cpufreq.c [new file with mode: 0644]
drivers/cpufreq/intel_pstate.c [new file with mode: 0644]
drivers/cpufreq/kirkwood-cpufreq.c [new file with mode: 0644]
drivers/cpufreq/maple-cpufreq.c
drivers/cpufreq/omap-cpufreq.c
drivers/cpufreq/powernow-k8.c
drivers/cpufreq/spear-cpufreq.c
drivers/cpuidle/cpuidle.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/reg_srcs/cayman
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/ttm/ttm_bo_util.c
drivers/hwmon/acpi_power_meter.c
drivers/hwmon/asus_atk0110.c
drivers/i2c/busses/i2c-scmi.c
drivers/infiniband/hw/qib/qib_qp.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/input/misc/atlas_btns.c
drivers/mailbox/Kconfig [new file with mode: 0644]
drivers/mailbox/Makefile [new file with mode: 0644]
drivers/mailbox/pl320-ipc.c [new file with mode: 0644]
drivers/media/radio/radio-keene.c
drivers/media/radio/radio-si4713.c
drivers/media/radio/radio-wl1273.c
drivers/media/radio/wl128x/fmdrv_v4l2.c
drivers/mtd/devices/Kconfig
drivers/mtd/maps/physmap_of.c
drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/nand_base.c
drivers/net/bonding/bond_sysfs.c
drivers/net/can/c_can/c_can.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/intel/e1000e/defines.h
drivers/net/ethernet/intel/e1000e/e1000.h
drivers/net/ethernet/intel/e1000e/ethtool.c
drivers/net/ethernet/intel/e1000e/hw.h
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/via/via-rhine.c
drivers/net/tun.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/usbnet.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/brcm80211/brcmsmac/pub.h
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/xen-netback/common.h
drivers/net/xen-netback/interface.c
drivers/net/xen-netback/netback.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/pci-acpi.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/probe.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/pinctrl-sirf.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/classmate-laptop.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/fujitsu-laptop.c
drivers/platform/x86/fujitsu-tablet.c
drivers/platform/x86/hp_accel.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel_menlow.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/topstar-laptop.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/toshiba_bluetooth.c
drivers/platform/x86/wmi.c
drivers/platform/x86/xo15-ebook.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpbios/Kconfig
drivers/regulator/max77686.c
drivers/regulator/max8907-regulator.c
drivers/regulator/max8997.c
drivers/regulator/max8998.c
drivers/regulator/of_regulator.c
drivers/regulator/s2mps11.c
drivers/regulator/tps65217-regulator.c
drivers/regulator/tps65910-regulator.c
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-vt8500.c
drivers/ssb/driver_gpio.c
drivers/ssb/main.c
drivers/ssb/ssb_private.h
drivers/staging/quickstart/quickstart.c
drivers/target/target_core_device.c
drivers/target/target_core_fabric_configfs.c
drivers/target/target_core_sbc.c
drivers/target/target_core_spc.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci-timer.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/uhci-hub.c
drivers/usb/host/xhci-ring.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/storage/initializers.c
drivers/usb/storage/initializers.h
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usual-tables.c
drivers/vhost/net.c
drivers/vhost/tcm_vhost.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/backlight/apple_bl.c
drivers/xen/events.c
drivers/xen/xen-acpi-pad.c
drivers/xen/xen-pciback/pciback_ops.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_map.c
fs/btrfs/file.c
fs/btrfs/ioctl.c
fs/btrfs/ordered-data.c
fs/btrfs/scrub.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/dlm/user.c
fs/nilfs2/ioctl.c
fs/sysfs/group.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
include/acpi/acbuffer.h
include/acpi/acconfig.h
include/acpi/acexcep.h
include/acpi/acnames.h
include/acpi/acoutput.h
include/acpi/acpi.h
include/acpi/acpi_bus.h
include/acpi/acpiosxf.h
include/acpi/acpixf.h
include/acpi/acrestyp.h
include/acpi/actbl.h
include/acpi/actbl1.h
include/acpi/actbl2.h
include/acpi/actbl3.h
include/acpi/actypes.h
include/acpi/container.h [deleted file]
include/acpi/platform/acenv.h
include/acpi/platform/acgcc.h
include/acpi/platform/aclinux.h
include/linux/acpi.h
include/linux/cpufreq.h
include/linux/freezer.h
include/linux/llist.h
include/linux/mailbox.h [new file with mode: 0644]
include/linux/memcontrol.h
include/linux/mmu_notifier.h
include/linux/pm_runtime.h
include/linux/suspend.h
include/linux/sysfs.h
include/linux/usb.h
include/linux/usb/hcd.h
include/linux/usb/usbnet.h
include/net/transp_v6.h
include/trace/events/power.h
include/uapi/linux/usb/ch9.h
kernel/events/core.c
kernel/power/autosleep.c
kernel/power/main.c
kernel/power/process.c
kernel/power/qos.c
kernel/power/suspend.c
kernel/rcutree_plugin.h
kernel/sched/debug.c
kernel/sched/fair.c
kernel/sched/rt.c
kernel/trace/Kconfig
kernel/trace/power-traces.c
lib/digsig.c
mm/huge_memory.c
mm/hugetlb.c
mm/migrate.c
mm/mmap.c
net/bluetooth/hci_conn.c
net/bluetooth/smp.c
net/core/pktgen.c
net/core/skbuff.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv6/addrconf.c
net/ipv6/datagram.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_gre.c
net/ipv6/ipv6_sockglue.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_ip6.c
net/l2tp/l2tp_ppp.c
net/openvswitch/vport-netdev.c
net/packet/af_packet.c
net/sched/sch_netem.c
net/sctp/auth.c
net/sctp/endpointola.c
net/sctp/socket.c
net/sunrpc/svcsock.c
net/wireless/scan.c
samples/seccomp/Makefile
scripts/checkpatch.pl
sound/soc/fsl/Kconfig
sound/soc/fsl/Makefile
sound/soc/fsl/imx-pcm-dma.c
sound/soc/fsl/imx-pcm-fiq.c
sound/soc/fsl/imx-pcm.c
sound/soc/fsl/imx-pcm.h
tools/power/acpi/Makefile
tools/vm/.gitignore [new file with mode: 0644]

diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D0 b/Documentation/ABI/testing/sysfs-devices-power_resources_D0
new file mode 100644 (file)
index 0000000..73b77a6
--- /dev/null
@@ -0,0 +1,13 @@
+What:          /sys/devices/.../power_resources_D0/
+Date:          January 2013
+Contact:       Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+               The /sys/devices/.../power_resources_D0/ directory is only
+               present for device objects representing ACPI device nodes that
+               use ACPI power resources for power management.
+
+               If present, it contains symbolic links to device directories
+               representing ACPI power resources that need to be turned on for
+               the given device node to be in ACPI power state D0.  The names
+               of the links are the same as the names of the directories they
+               point to.
diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D1 b/Documentation/ABI/testing/sysfs-devices-power_resources_D1
new file mode 100644 (file)
index 0000000..30c2070
--- /dev/null
@@ -0,0 +1,14 @@
+What:          /sys/devices/.../power_resources_D1/
+Date:          January 2013
+Contact:       Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+               The /sys/devices/.../power_resources_D1/ directory is only
+               present for device objects representing ACPI device nodes that
+               use ACPI power resources for power management and support ACPI
+               power state D1.
+
+               If present, it contains symbolic links to device directories
+               representing ACPI power resources that need to be turned on for
+               the given device node to be in ACPI power state D1.  The names
+               of the links are the same as the names of the directories they
+               point to.
diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D2 b/Documentation/ABI/testing/sysfs-devices-power_resources_D2
new file mode 100644 (file)
index 0000000..fd9d84b
--- /dev/null
@@ -0,0 +1,14 @@
+What:          /sys/devices/.../power_resources_D2/
+Date:          January 2013
+Contact:       Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+               The /sys/devices/.../power_resources_D2/ directory is only
+               present for device objects representing ACPI device nodes that
+               use ACPI power resources for power management and support ACPI
+               power state D2.
+
+               If present, it contains symbolic links to device directories
+               representing ACPI power resources that need to be turned on for
+               the given device node to be in ACPI power state D2.  The names
+               of the links are the same as the names of the directories they
+               point to.
diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D3hot b/Documentation/ABI/testing/sysfs-devices-power_resources_D3hot
new file mode 100644 (file)
index 0000000..3df32c2
--- /dev/null
@@ -0,0 +1,14 @@
+What:          /sys/devices/.../power_resources_D3hot/
+Date:          January 2013
+Contact:       Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+               The /sys/devices/.../power_resources_D3hot/ directory is only
+               present for device objects representing ACPI device nodes that
+               use ACPI power resources for power management and support ACPI
+               power state D3hot.
+
+               If present, it contains symbolic links to device directories
+               representing ACPI power resources that need to be turned on for
+               the given device node to be in ACPI power state D3hot.  The
+               names of the links are the same as the names of the directories
+               they point to.
diff --git a/Documentation/ABI/testing/sysfs-devices-power_state b/Documentation/ABI/testing/sysfs-devices-power_state
new file mode 100644 (file)
index 0000000..7ad9546
--- /dev/null
@@ -0,0 +1,20 @@
+What:          /sys/devices/.../power_state
+Date:          January 2013
+Contact:       Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+               The /sys/devices/.../power_state attribute is only present for
+               device objects representing ACPI device nodes that provide power
+               management methods.
+
+               If present, it contains a string representing the current ACPI
+               power state of the given device node.  Its possible values,
+               "D0", "D1", "D2", "D3hot", and "D3cold", reflect the power state
+               names defined by the ACPI specification (ACPI 4 and above).
+
+               If the device node uses shared ACPI power resources, this state
+               determines a list of power resources required not to be turned
+               off.  However, some power resources needed by the device node in
+               higher-power (lower-number) states may also be ON because of
+               some other devices using them at the moment.
+
+               This attribute is read-only.
diff --git a/Documentation/ABI/testing/sysfs-devices-real_power_state b/Documentation/ABI/testing/sysfs-devices-real_power_state
new file mode 100644 (file)
index 0000000..8b3527c
--- /dev/null
@@ -0,0 +1,23 @@
+What:          /sys/devices/.../real_power_state
+Date:          January 2013
+Contact:       Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+               The /sys/devices/.../real_power_state attribute is only present
+               for device objects representing ACPI device nodes that provide
+               power management methods and use ACPI power resources for power
+               management.
+
+               If present, it contains a string representing the real ACPI
+               power state of the given device node as returned by the _PSC
+               control method or inferred from the configuration of power
+               resources.  Its possible values, "D0", "D1", "D2", "D3hot", and
+               "D3cold", reflect the power state names defined by the ACPI
+               specification (ACPI 4 and above).
+
+               In some situations the value of this attribute may be different
+               from the value of the /sys/devices/.../power_state attribute for
+               the same device object.  If that happens, some shared power
+               resources used by the device node are only ON because of some
+               other devices using them at the moment.
+
+               This attribute is read-only.
diff --git a/Documentation/ABI/testing/sysfs-devices-resource_in_use b/Documentation/ABI/testing/sysfs-devices-resource_in_use
new file mode 100644 (file)
index 0000000..b4a3bc5
--- /dev/null
@@ -0,0 +1,12 @@
+What:          /sys/devices/.../resource_in_use
+Date:          January 2013
+Contact:       Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+               The /sys/devices/.../resource_in_use attribute is only present
+               for device objects representing ACPI power resources.
+
+               If present, it contains a number (0 or 1) representing the
+               current status of the given power resource (0 means that the
+               resource is not in use and therefore it has been turned off).
+
+               This attribute is read-only.
index 54469bc..94a6561 100644 (file)
@@ -63,8 +63,8 @@ from ACPI tables.
 Currently the kernel is not able to automatically determine from which ACPI
 device it should make the corresponding platform device so we need to add
 the ACPI device explicitly to acpi_platform_device_ids list defined in
-drivers/acpi/scan.c. This limitation is only for the platform devices, SPI
-and I2C devices are created automatically as described below.
+drivers/acpi/acpi_platform.c. This limitation is only for the platform
+devices, SPI and I2C devices are created automatically as described below.
 
 SPI serial bus support
 ~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/acpi/scan_handlers.txt b/Documentation/acpi/scan_handlers.txt
new file mode 100644 (file)
index 0000000..3246ccf
--- /dev/null
@@ -0,0 +1,77 @@
+ACPI Scan Handlers
+
+Copyright (C) 2012, Intel Corporation
+Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+During system initialization and ACPI-based device hot-add, the ACPI namespace
+is scanned in search of device objects that generally represent various pieces
+of hardware.  This causes a struct acpi_device object to be created and
+registered with the driver core for every device object in the ACPI namespace
+and the hierarchy of those struct acpi_device objects reflects the namespace
+layout (i.e. parent device objects in the namespace are represented by parent
+struct acpi_device objects and analogously for their children).  Those struct
+acpi_device objects are referred to as "device nodes" in what follows, but they
+should not be confused with struct device_node objects used by the Device Trees
+parsing code (although their role is analogous to the role of those objects).
+
+During ACPI-based device hot-remove device nodes representing pieces of hardware
+being removed are unregistered and deleted.
+
+The core ACPI namespace scanning code in drivers/acpi/scan.c carries out basic
+initialization of device nodes, such as retrieving common configuration
+information from the device objects represented by them and populating them with
+appropriate data, but some of them require additional handling after they have
+been registered.  For example, if the given device node represents a PCI host
+bridge, its registration should cause the PCI bus under that bridge to be
+enumerated and PCI devices on that bus to be registered with the driver core.
+Similarly, if the device node represents a PCI interrupt link, it is necessary
+to configure that link so that the kernel can use it.
+
+Those additional configuration tasks usually depend on the type of the hardware
+component represented by the given device node which can be determined on the
+basis of the device node's hardware ID (HID).  They are performed by objects
+called ACPI scan handlers represented by the following structure:
+
+struct acpi_scan_handler {
+       const struct acpi_device_id *ids;
+       struct list_head list_node;
+       int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
+       void (*detach)(struct acpi_device *dev);
+};
+
+where ids is the list of IDs of device nodes the given handler is supposed to
+take care of, list_node is the hook to the global list of ACPI scan handlers
+maintained by the ACPI core and the .attach() and .detach() callbacks are
+executed, respectively, after registration of new device nodes and before
+unregistration of device nodes the handler attached to previously.
+
+The namespace scanning function, acpi_bus_scan(), first registers all of the
+device nodes in the given namespace scope with the driver core.  Then, it tries
+to match a scan handler against each of them using the ids arrays of the
+available scan handlers.  If a matching scan handler is found, its .attach()
+callback is executed for the given device node.  If that callback returns 1,
+that means that the handler has claimed the device node and is now responsible
+for carrying out any additional configuration tasks related to it.  It also will
+be responsible for preparing the device node for unregistration in that case.
+The device node's handler field is then populated with the address of the scan
+handler that has claimed it.
+
+If the .attach() callback returns 0, it means that the device node is not
+interesting to the given scan handler and may be matched against the next scan
+handler in the list.  If it returns a (negative) error code, that means that
+the namespace scan should be terminated due to a serious error.  The error code
+returned should then reflect the type of the error.
+
+The namespace trimming function, acpi_bus_trim(), first executes .detach()
+callbacks from the scan handlers of all device nodes in the given namespace
+scope (if they have scan handlers).  Next, it unregisters all of the device
+nodes in that scope.
+
+ACPI scan handlers can be added to the list maintained by the ACPI core with the
+help of the acpi_scan_add_handler() function taking a pointer to the new scan
+handler as an argument.  The order in which scan handlers are added to the list
+is the order in which they are matched against device nodes during namespace
+scans.
+
+All scan handles must be added to the list before acpi_bus_scan() is run for the
+first time and they cannot be removed from it.
index c436096..72f70b1 100644 (file)
@@ -111,6 +111,12 @@ policy->governor           must contain the "default policy" for
 For setting some of these values, the frequency table helpers might be
 helpful. See the section 2 for more information on them.
 
+SMP systems normally have same clock source for a group of cpus. For these the
+.init() would be called only once for the first online cpu. Here the .init()
+routine must initialize policy->cpus with mask of all possible cpus (Online +
+Offline) that share the clock. Then the core would copy this mask onto
+policy->related_cpus and will reset policy->cpus to carry only online cpus.
+
 
 1.3 verify
 ------------
index 04f6b32..ff2f283 100644 (file)
@@ -190,11 +190,11 @@ scaling_max_freq          show the current "policy limits" (in
                                first set scaling_max_freq, then
                                scaling_min_freq.
 
-affected_cpus :                        List of CPUs that require software coordination
-                               of frequency.
+affected_cpus :                        List of Online CPUs that require software
+                               coordination of frequency.
 
-related_cpus :                 List of CPUs that need some sort of frequency
-                               coordination, whether software or hardware.
+related_cpus :                 List of Online + Offline CPUs that need software
+                               coordination of frequency.
 
 scaling_driver :               Hardware driver for cpufreq.
 
diff --git a/Documentation/devicetree/bindings/arm/kirkwood.txt b/Documentation/devicetree/bindings/arm/kirkwood.txt
new file mode 100644 (file)
index 0000000..98cce9a
--- /dev/null
@@ -0,0 +1,27 @@
+Marvell Kirkwood Platforms Device Tree Bindings
+-----------------------------------------------
+
+Boards with a SoC of the Marvell Kirkwood
+shall have the following property:
+
+Required root node property:
+
+compatible: must contain "marvell,kirkwood";
+
+In order to support the kirkwood cpufreq driver, there must be a node
+cpus/cpu@0 with three clocks, "cpu_clk", "ddrclk" and "powersave",
+where the "powersave" clock is a gating clock used to switch the CPU
+between the "cpu_clk" and the "ddrclk".
+
+Example:
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                     device_type = "cpu";
+                     compatible = "marvell,sheeva-88SV131";
+                     clocks = <&core_clk 1>, <&core_clk 3>, <&gate_clk 11>;
+                     clock-names = "cpu_clk", "ddrclk", "powersave";
+               };
index 109ee45..4c5b3f9 100644 (file)
@@ -1126,6 +1126,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        0       disables intel_idle and fall back on acpi_idle.
                        1 to 6  specify maximum depth of C-state.
 
+       intel_pstate=  [X86]
+                      disable
+                        Do not enable intel_pstate as the default
+                        scaling driver for the supported processors
+
        intremap=       [X86-64, Intel-IOMMU]
                        on      enable Interrupt Remapping (default)
                        off     disable Interrupt Remapping
@@ -2429,7 +2434,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        real-time workloads.  It can also improve energy
                        efficiency for asymmetric multiprocessors.
 
-       rcu_nocbs_poll  [KNL,BOOT]
+       rcu_nocb_poll   [KNL,BOOT]
                        Rather than requiring that offloaded CPUs
                        (specified by rcu_nocbs= above) explicitly
                        awaken the corresponding "rcuoN" kthreads,
index 6ec291e..85894d8 100644 (file)
@@ -223,3 +223,8 @@ since they ask the freezer to skip freezing this task, since it is anyway
 only after the entire suspend/hibernation sequence is complete.
 So, to summarize, use [un]lock_system_sleep() instead of directly using
 mutex_[un]lock(&pm_mutex). That would prevent freezing failures.
+
+V. Miscellaneous
+/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
+all user space processes or all freezable kernel threads, in unit of millisecond.
+The default value is 20000, with range of unsigned integer.
index 03591a7..6c9f5d9 100644 (file)
@@ -426,6 +426,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
       'power.runtime_error' is set or 'power.disable_depth' is greater than
       zero)
 
+  bool pm_runtime_active(struct device *dev);
+    - return true if the device's runtime PM status is 'active' or its
+      'power.disable_depth' field is not equal to zero, or false otherwise
+
   bool pm_runtime_suspended(struct device *dev);
     - return true if the device's runtime PM status is 'suspended' and its
       'power.disable_depth' field is equal to zero, or false otherwise
index cf794af..e1498ff 100644 (file)
@@ -17,7 +17,7 @@ Cf. include/trace/events/power.h for the events definitions.
 1. Power state switch events
 ============================
 
-1.1 New trace API
+1.1 Trace API
 -----------------
 
 A 'cpu' event class gathers the CPU-related events: cpuidle and
@@ -41,31 +41,6 @@ The event which has 'state=4294967295' in the trace is very important to the use
 space tools which are using it to detect the end of the current state, and so to
 correctly draw the states diagrams and to calculate accurate statistics etc.
 
-1.2 DEPRECATED trace API
-------------------------
-
-A new Kconfig option CONFIG_EVENT_POWER_TRACING_DEPRECATED with the default value of
-'y' has been created. This allows the legacy trace power API to be used conjointly
-with the new trace API.
-The Kconfig option, the old trace API (in include/trace/events/power.h) and the
-old trace points will disappear in a future release (namely 2.6.41).
-
-power_start            "type=%lu state=%lu cpu_id=%lu"
-power_frequency                "type=%lu state=%lu cpu_id=%lu"
-power_end              "cpu_id=%lu"
-
-The 'type' parameter takes one of those macros:
- . POWER_NONE  = 0,
- . POWER_CSTATE        = 1,    /* C-State */
- . POWER_PSTATE        = 2,    /* Frequency change or DVFS */
-
-The 'state' parameter is set depending on the type:
- . Target C-state for type=POWER_CSTATE,
- . Target frequency for type=POWER_PSTATE,
-
-power_end is used to indicate the exit of a state, corresponding to the latest
-power_start event.
-
 2. Clocks events
 ================
 The clock events are used for clock enable/disable and for
index 3edb4c2..e540fd6 100644 (file)
@@ -57,7 +57,7 @@ Protocol 2.10:        (Kernel 2.6.31) Added a protocol for relaxed alignment
 Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
                protocol entry point.
 
-Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields
+Protocol 2.12: (Kernel 3.8) Added the xloadflags field and extension fields
                to struct boot_params for for loading bzImage and ramdisk
                above 4G in 64bit.
 
index 212c255..35a56bc 100644 (file)
@@ -1489,7 +1489,7 @@ AVR32 ARCHITECTURE
 M:     Haavard Skinnemoen <hskinnemoen@gmail.com>
 M:     Hans-Christian Egtvedt <egtvedt@samfundet.no>
 W:     http://www.atmel.com/products/AVR32/
-W:     http://avr32linux.org/
+W:     http://mirror.egtvedt.no/avr32linux.org/
 W:     http://avrfreaks.net/
 S:     Maintained
 F:     arch/avr32/
index 54dfde5..08ef9bd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 8
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index 5927a8d..6aad34a 100644 (file)
                        next-level-cache = <&L2>;
                        clocks = <&a9pll>;
                        clock-names = "cpu";
+                       operating-points = <
+                               /* kHz    ignored */
+                                1300000  1000000
+                                1200000  1000000
+                                1100000  1000000
+                                 800000  1000000
+                                 400000  1000000
+                                 200000  1000000
+                       >;
+                       clock-latency = <100000>;
                };
 
                cpu@901 {
index 36ae03a..87dfa90 100644 (file)
@@ -351,6 +351,25 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
        irq_set_chained_handler(irq, gic_handle_cascade_irq);
 }
 
+static u8 gic_get_cpumask(struct gic_chip_data *gic)
+{
+       void __iomem *base = gic_data_dist_base(gic);
+       u32 mask, i;
+
+       for (i = mask = 0; i < 32; i += 4) {
+               mask = readl_relaxed(base + GIC_DIST_TARGET + i);
+               mask |= mask >> 16;
+               mask |= mask >> 8;
+               if (mask)
+                       break;
+       }
+
+       if (!mask)
+               pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
+
+       return mask;
+}
+
 static void __init gic_dist_init(struct gic_chip_data *gic)
 {
        unsigned int i;
@@ -369,7 +388,9 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
        /*
         * Set all global interrupts to this CPU only.
         */
-       cpumask = readl_relaxed(base + GIC_DIST_TARGET + 0);
+       cpumask = gic_get_cpumask(gic);
+       cpumask |= cpumask << 8;
+       cpumask |= cpumask << 16;
        for (i = 32; i < gic_irqs; i += 4)
                writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
 
@@ -400,7 +421,7 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
         * Get what the GIC says our CPU mask is.
         */
        BUG_ON(cpu >= NR_GIC_CPU_IF);
-       cpu_mask = readl_relaxed(dist_base + GIC_DIST_TARGET + 0);
+       cpu_mask = gic_get_cpumask(gic);
        gic_cpu_map[cpu] = cpu_mask;
 
        /*
index 73cf03a..1c4df27 100644 (file)
@@ -37,7 +37,7 @@
  */
 #define PAGE_OFFSET            UL(CONFIG_PAGE_OFFSET)
 #define TASK_SIZE              (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000))
-#define TASK_UNMAPPED_BASE     (UL(CONFIG_PAGE_OFFSET) / 3)
+#define TASK_UNMAPPED_BASE     ALIGN(TASK_SIZE / 3, SZ_16M)
 
 /*
  * The maximum size of a 26-bit user space task.
index 49f335d..ae0c7bb 100644 (file)
@@ -31,7 +31,6 @@ static void __iomem *twd_base;
 
 static struct clk *twd_clk;
 static unsigned long twd_timer_rate;
-static bool common_setup_called;
 static DEFINE_PER_CPU(bool, percpu_setup_called);
 
 static struct clock_event_device __percpu **twd_evt;
@@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
        return IRQ_NONE;
 }
 
-static struct clk *twd_get_clock(void)
+static void twd_get_clock(struct device_node *np)
 {
-       struct clk *clk;
        int err;
 
-       clk = clk_get_sys("smp_twd", NULL);
-       if (IS_ERR(clk)) {
-               pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
-               return clk;
+       if (np)
+               twd_clk = of_clk_get(np, 0);
+       else
+               twd_clk = clk_get_sys("smp_twd", NULL);
+
+       if (IS_ERR(twd_clk)) {
+               pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
+               return;
        }
 
-       err = clk_prepare_enable(clk);
+       err = clk_prepare_enable(twd_clk);
        if (err) {
                pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
-               clk_put(clk);
-               return ERR_PTR(err);
+               clk_put(twd_clk);
+               return;
        }
 
-       return clk;
+       twd_timer_rate = clk_get_rate(twd_clk);
 }
 
 /*
@@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
        }
        per_cpu(percpu_setup_called, cpu) = true;
 
-       /*
-        * This stuff only need to be done once for the entire TWD cluster
-        * during the runtime of the system.
-        */
-       if (!common_setup_called) {
-               twd_clk = twd_get_clock();
-
-               /*
-                * We use IS_ERR_OR_NULL() here, because if the clock stubs
-                * are active we will get a valid clk reference which is
-                * however NULL and will return the rate 0. In that case we
-                * need to calibrate the rate instead.
-                */
-               if (!IS_ERR_OR_NULL(twd_clk))
-                       twd_timer_rate = clk_get_rate(twd_clk);
-               else
-                       twd_calibrate_rate();
-
-               common_setup_called = true;
-       }
+       twd_calibrate_rate();
 
        /*
         * The following is done once per CPU the first time .setup() is
@@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
        .stop   = twd_timer_stop,
 };
 
-static int __init twd_local_timer_common_register(void)
+static int __init twd_local_timer_common_register(struct device_node *np)
 {
        int err;
 
@@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void)
        if (err)
                goto out_irq;
 
+       twd_get_clock(np);
+
        return 0;
 
 out_irq:
@@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
        if (!twd_base)
                return -ENOMEM;
 
-       return twd_local_timer_common_register();
+       return twd_local_timer_common_register(NULL);
 }
 
 #ifdef CONFIG_OF
@@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void)
                goto out;
        }
 
-       err = twd_local_timer_common_register();
+       err = twd_local_timer_common_register(np);
 
 out:
        WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
index e103c29..85afb03 100644 (file)
@@ -414,7 +414,7 @@ config MACH_EXYNOS4_DT
        select CPU_EXYNOS4210
        select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
        select PINCTRL
-       select PINCTRL_EXYNOS4
+       select PINCTRL_EXYNOS
        select USE_OF
        help
          Machine support for Samsung Exynos4 machine with device tree enabled.
index 7517c3f..b5d39dd 100644 (file)
@@ -18,12 +18,25 @@ enum cpufreq_level_index {
        L20,
 };
 
+#define APLL_FREQ(f, a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, m, p, s) \
+       { \
+               .freq = (f) * 1000, \
+               .clk_div_cpu0 = ((a0) | (a1) << 4 | (a2) << 8 | (a3) << 12 | \
+                       (a4) << 16 | (a5) << 20 | (a6) << 24 | (a7) << 28), \
+               .clk_div_cpu1 = (b0 << 0 | b1 << 4 | b2 << 8), \
+               .mps = ((m) << 16 | (p) << 8 | (s)), \
+       }
+
+struct apll_freq {
+       unsigned int freq;
+       u32 clk_div_cpu0;
+       u32 clk_div_cpu1;
+       u32 mps;
+};
+
 struct exynos_dvfs_info {
        unsigned long   mpll_freq_khz;
        unsigned int    pll_safe_idx;
-       unsigned int    pm_lock_idx;
-       unsigned int    max_support_idx;
-       unsigned int    min_support_idx;
        struct clk      *cpu_clk;
        unsigned int    *volt_table;
        struct cpufreq_frequency_table  *freq_table;
index 551c97e..44b12f9 100644 (file)
@@ -1,5 +1,7 @@
 config ARCH_HIGHBANK
        bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
+       select ARCH_HAS_CPUFREQ
+       select ARCH_HAS_OPP
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_AMBA
        select ARM_GIC
@@ -11,5 +13,7 @@ config ARCH_HIGHBANK
        select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU
        select HAVE_SMP
+       select MAILBOX
+       select PL320_MBOX
        select SPARSE_IRQ
        select USE_OF
index 7be3622..2d93d8b 100644 (file)
@@ -351,12 +351,10 @@ static void omap3_pm_idle(void)
        if (omap_irq_pending())
                goto out;
 
-       trace_power_start(POWER_CSTATE, 1, smp_processor_id());
        trace_cpu_idle(1, smp_processor_id());
 
        omap_sram_idle();
 
-       trace_power_end(smp_processor_id());
        trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
 
 out:
index d6b5073..4475423 100644 (file)
 /*
  * Only define NR_IRQS if less than NR_IRQS_EB
  */
-#define NR_IRQS_EB             (IRQ_EB_GIC_START + 96)
+#define NR_IRQS_EB             (IRQ_EB_GIC_START + 128)
 
 #if defined(CONFIG_MACH_REALVIEW_EB) \
        && (!defined(NR_IRQS) || (NR_IRQS < NR_IRQS_EB))
index a74d3c7..a36a03d 100644 (file)
@@ -243,8 +243,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
        /* FIXME: what's the actual transition time? */
        policy->cpuinfo.transition_latency = 300 * 1000;
 
-       policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
-       cpumask_copy(policy->related_cpus, cpu_possible_mask);
+       cpumask_copy(policy->cpus, cpu_possible_mask);
 
        if (policy->cpu == 0)
                register_pm_notifier(&tegra_cpu_pm_notifier);
index 076c26d..dda3904 100644 (file)
@@ -640,7 +640,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 
        if (is_coherent || nommu())
                addr = __alloc_simple_buffer(dev, size, gfp, &page);
-       else if (gfp & GFP_ATOMIC)
+       else if (!(gfp & __GFP_WAIT))
                addr = __alloc_from_pool(size, &page);
        else if (!IS_ENABLED(CONFIG_CMA))
                addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
index aaf5199..b3d18f9 100644 (file)
@@ -336,4 +336,14 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 
+/* drivers/base/dma-mapping.c */
+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
+extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size);
+
+#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
+#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
+
 #endif /* __ASM_AVR32_DMA_MAPPING_H */
index bbf4610..054d9ec 100644 (file)
@@ -154,4 +154,14 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
        _dma_sync((dma_addr_t)vaddr, size, dir);
 }
 
+/* drivers/base/dma-mapping.c */
+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
+extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size);
+
+#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
+#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
+
 #endif                         /* _BLACKFIN_DMA_MAPPING_H */
index 3c69406..88bd0d8 100644 (file)
@@ -89,4 +89,19 @@ extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
 #define dma_free_noncoherent(d, s, v, h)  dma_free_coherent((d), (s), (v), (h))
 
+/* Not supported for now */
+static inline int dma_mmap_coherent(struct device *dev,
+                                   struct vm_area_struct *vma, void *cpu_addr,
+                                   dma_addr_t dma_addr, size_t size)
+{
+       return -EINVAL;
+}
+
+static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size)
+{
+       return -EINVAL;
+}
+
 #endif /* _ASM_C6X_DMA_MAPPING_H */
index 8588b2c..2f0f654 100644 (file)
@@ -158,5 +158,15 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 {
 }
 
+/* drivers/base/dma-mapping.c */
+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
+extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size);
+
+#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
+#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
+
 
 #endif
index dfb8110..1746a2b 100644 (file)
@@ -132,4 +132,19 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
        flush_write_buffers();
 }
 
+/* Not supported for now */
+static inline int dma_mmap_coherent(struct device *dev,
+                                   struct vm_area_struct *vma, void *cpu_addr,
+                                   dma_addr_t dma_addr, size_t size)
+{
+       return -EINVAL;
+}
+
+static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size)
+{
+       return -EINVAL;
+}
+
 #endif  /* _ASM_DMA_MAPPING_H */
index 6192f71..916ffe7 100644 (file)
@@ -191,7 +191,7 @@ static int aml_nfw_add(struct acpi_device *device)
        return aml_nfw_add_global_handler();
 }
 
-static int aml_nfw_remove(struct acpi_device *device, int type)
+static int aml_nfw_remove(struct acpi_device *device)
 {
        return aml_nfw_remove_global_handler();
 }
index 359e68a..faa1bf0 100644 (file)
 
 /* Asm macros */
 
-#define ACPI_ASM_MACROS
-#define BREAKPOINT3
-#define ACPI_DISABLE_IRQS() local_irq_disable()
-#define ACPI_ENABLE_IRQS()  local_irq_enable()
 #define ACPI_FLUSH_CPU_CACHE()
 
 static inline int
index 3e6b844..292805f 100644 (file)
@@ -115,4 +115,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
 #include <asm-generic/dma-mapping-broken.h>
 #endif
 
+/* drivers/base/dma-mapping.c */
+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+                          void *cpu_addr, dma_addr_t dma_addr, size_t size);
+extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size);
+
+#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
+#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
+
 #endif  /* _M68K_DMA_MAPPING_H */
index c1be439..a18abfc 100644 (file)
@@ -168,4 +168,19 @@ void dma_cache_sync(void *vaddr, size_t size,
        mn10300_dcache_flush_inv();
 }
 
+/* Not supported for now */
+static inline int dma_mmap_coherent(struct device *dev,
+                                   struct vm_area_struct *vma, void *cpu_addr,
+                                   dma_addr_t dma_addr, size_t size)
+{
+       return -EINVAL;
+}
+
+static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size)
+{
+       return -EINVAL;
+}
+
 #endif
index 467bbd5..106b395 100644 (file)
@@ -238,4 +238,19 @@ void * sba_get_iommu(struct parisc_device *dev);
 /* At the moment, we panic on error for IOMMU resource exaustion */
 #define dma_mapping_error(dev, x)      0
 
+/* This API cannot be supported on PA-RISC */
+static inline int dma_mmap_coherent(struct device *dev,
+                                   struct vm_area_struct *vma, void *cpu_addr,
+                                   dma_addr_t dma_addr, size_t size)
+{
+       return -EINVAL;
+}
+
+static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size)
+{
+       return -EINVAL;
+}
+
 #endif
index 5658508..7443481 100644 (file)
@@ -115,11 +115,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
        sldi    r29,r5,SID_SHIFT - VPN_SHIFT
        rldicl  r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
        or      r29,r28,r29
-
-       /* Calculate hash value for primary slot and store it in r28 */
-       rldicl  r5,r5,0,25              /* vsid & 0x0000007fffffffff */
-       rldicl  r0,r3,64-12,48          /* (ea >> 12) & 0xffff */
-       xor     r28,r5,r0
+       /*
+        * Calculate hash value for primary slot and store it in r28
+        * r3 = va, r5 = vsid
+        * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
+        */
+       rldicl  r0,r3,64-12,48
+       xor     r28,r5,r0               /* hash */
        b       4f
 
 3:     /* Calc vpn and put it in r29 */
@@ -130,11 +132,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
        /*
         * calculate hash value for primary slot and
         * store it in r28 for 1T segment
+        * r3 = va, r5 = vsid
         */
-       rldic   r28,r5,25,25            /* (vsid << 25) & 0x7fffffffff */
-       clrldi  r5,r5,40                /* vsid & 0xffffff */
-       rldicl  r0,r3,64-12,36          /* (ea >> 12) & 0xfffffff */
-       xor     r28,r28,r5
+       sldi    r28,r5,25               /* vsid << 25 */
+       /* r0 =  (va >> 12) & ((1ul << (40 - 12)) -1) */
+       rldicl  r0,r3,64-12,36
+       xor     r28,r28,r5              /* vsid ^ ( vsid << 25) */
        xor     r28,r28,r0              /* hash */
 
        /* Convert linux PTE bits into HW equivalents */
@@ -407,11 +410,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
         */
        rldicl  r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
        or      r29,r28,r29
-
-       /* Calculate hash value for primary slot and store it in r28 */
-       rldicl  r5,r5,0,25              /* vsid & 0x0000007fffffffff */
-       rldicl  r0,r3,64-12,48          /* (ea >> 12) & 0xffff */
-       xor     r28,r5,r0
+       /*
+        * Calculate hash value for primary slot and store it in r28
+        * r3 = va, r5 = vsid
+        * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
+        */
+       rldicl  r0,r3,64-12,48
+       xor     r28,r5,r0               /* hash */
        b       4f
 
 3:     /* Calc vpn and put it in r29 */
@@ -426,11 +431,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
        /*
         * Calculate hash value for primary slot and
         * store it in r28  for 1T segment
+        * r3 = va, r5 = vsid
         */
-       rldic   r28,r5,25,25            /* (vsid << 25) & 0x7fffffffff */
-       clrldi  r5,r5,40                /* vsid & 0xffffff */
-       rldicl  r0,r3,64-12,36          /* (ea >> 12) & 0xfffffff */
-       xor     r28,r28,r5
+       sldi    r28,r5,25               /* vsid << 25 */
+       /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
+       rldicl  r0,r3,64-12,36
+       xor     r28,r28,r5              /* vsid ^ ( vsid << 25) */
        xor     r28,r28,r0              /* hash */
 
        /* Convert linux PTE bits into HW equivalents */
@@ -752,25 +758,27 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
        rldicl  r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
        or      r29,r28,r29
 
-       /* Calculate hash value for primary slot and store it in r28 */
-       rldicl  r5,r5,0,25              /* vsid & 0x0000007fffffffff */
-       rldicl  r0,r3,64-16,52          /* (ea >> 16) & 0xfff */
-       xor     r28,r5,r0
+       /* Calculate hash value for primary slot and store it in r28
+        * r3 = va, r5 = vsid
+        * r0 = (va >> 16) & ((1ul << (28 - 16)) -1)
+        */
+       rldicl  r0,r3,64-16,52
+       xor     r28,r5,r0               /* hash */
        b       4f
 
 3:     /* Calc vpn and put it in r29 */
        sldi    r29,r5,SID_SHIFT_1T - VPN_SHIFT
        rldicl  r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
        or      r29,r28,r29
-
        /*
         * calculate hash value for primary slot and
         * store it in r28 for 1T segment
+        * r3 = va, r5 = vsid
         */
-       rldic   r28,r5,25,25            /* (vsid << 25) & 0x7fffffffff */
-       clrldi  r5,r5,40                /* vsid & 0xffffff */
-       rldicl  r0,r3,64-16,40          /* (ea >> 16) & 0xffffff */
-       xor     r28,r28,r5
+       sldi    r28,r5,25               /* vsid << 25 */
+       /* r0 = (va >> 16) & ((1ul << (40 - 16)) -1) */
+       rldicl  r0,r3,64-16,40
+       xor     r28,r28,r5              /* vsid ^ ( vsid << 25) */
        xor     r28,r28,r0              /* hash */
 
        /* Convert linux PTE bits into HW equivalents */
index 1b63586..c03309f 100644 (file)
@@ -454,6 +454,16 @@ config X86_MDFLD
 
 endif
 
+config X86_INTEL_LPSS
+       bool "Intel Low Power Subsystem Support"
+       depends on ACPI
+       select COMMON_CLK
+       ---help---
+         Select to build support for Intel Low Power Subsystem such as
+         found on Intel Lynxpoint PCH. Selecting this option enables
+         things like clock tree (common clock framework) which are needed
+         by the LPSS peripheral drivers.
+
 config X86_RDC321X
        bool "RDC R-321x SoC"
        depends on X86_32
index 102ff7c..142c4ce 100644 (file)
@@ -207,7 +207,7 @@ sysexit_from_sys_call:
        testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
        jnz ia32_ret_from_sys_call
        TRACE_IRQS_ON
-       sti
+       ENABLE_INTERRUPTS(CLBR_NONE)
        movl %eax,%esi          /* second arg, syscall return value */
        cmpl $-MAX_ERRNO,%eax   /* is it an error ? */
        jbe 1f
@@ -217,7 +217,7 @@ sysexit_from_sys_call:
        call __audit_syscall_exit
        movq RAX-ARGOFFSET(%rsp),%rax   /* reload syscall return value */
        movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
-       cli
+       DISABLE_INTERRUPTS(CLBR_NONE)
        TRACE_IRQS_OFF
        testl %edi,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
        jz \exit
index 0c44630..b31bf97 100644 (file)
 
 /* Asm macros */
 
-#define ACPI_ASM_MACROS
-#define BREAKPOINT3
-#define ACPI_DISABLE_IRQS() local_irq_disable()
-#define ACPI_ENABLE_IRQS()  local_irq_enable()
 #define ACPI_FLUSH_CPU_CACHE() wbinvd()
 
 int __acpi_acquire_global_lock(unsigned int *lock);
index fe9edec..84c1309 100644 (file)
@@ -298,8 +298,7 @@ struct _cache_attr {
                         unsigned int);
 };
 
-#ifdef CONFIG_AMD_NB
-
+#if defined(CONFIG_AMD_NB) && defined(CONFIG_SYSFS)
 /*
  * L3 cache descriptors
  */
@@ -524,9 +523,9 @@ store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count,
 static struct _cache_attr subcaches =
        __ATTR(subcaches, 0644, show_subcaches, store_subcaches);
 
-#else  /* CONFIG_AMD_NB */
+#else
 #define amd_init_l3_cache(x, y)
-#endif /* CONFIG_AMD_NB */
+#endif  /* CONFIG_AMD_NB && CONFIG_SYSFS */
 
 static int
 __cpuinit cpuid4_cache_lookup_regs(int index,
index 93b9e11..4914e94 100644 (file)
@@ -2019,7 +2019,10 @@ __init int intel_pmu_init(void)
                break;
 
        case 28: /* Atom */
-       case 54: /* Cedariew */
+       case 38: /* Lincroft */
+       case 39: /* Penwell */
+       case 53: /* Cloverview */
+       case 54: /* Cedarview */
                memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
@@ -2084,6 +2087,7 @@ __init int intel_pmu_init(void)
                pr_cont("SandyBridge events, ");
                break;
        case 58: /* IvyBridge */
+       case 62: /* IvyBridge EP */
                memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
                memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
index f2af39f..4820c23 100644 (file)
@@ -19,7 +19,7 @@ static const u64 p6_perfmon_event_map[] =
 
 };
 
-static __initconst u64 p6_hw_cache_event_ids
+static u64 p6_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
index b11719e..14ae100 100644 (file)
@@ -369,7 +369,6 @@ void cpu_idle(void)
  */
 void default_idle(void)
 {
-       trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
        trace_cpu_idle_rcuidle(1, smp_processor_id());
        current_thread_info()->status &= ~TS_POLLING;
        /*
@@ -383,7 +382,6 @@ void default_idle(void)
        else
                local_irq_enable();
        current_thread_info()->status |= TS_POLLING;
-       trace_power_end_rcuidle(smp_processor_id());
        trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
 }
 #ifdef CONFIG_APM_MODULE
@@ -420,12 +418,10 @@ void stop_this_cpu(void *dummy)
  */
 static void poll_idle(void)
 {
-       trace_power_start_rcuidle(POWER_CSTATE, 0, smp_processor_id());
        trace_cpu_idle_rcuidle(0, smp_processor_id());
        local_irq_enable();
        while (!need_resched())
                cpu_relax();
-       trace_power_end_rcuidle(smp_processor_id());
        trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
 }
 
index 2fdca25..fef7d0b 100644 (file)
@@ -195,7 +195,7 @@ err_sysfs:
        return r;
 }
 
-static int xo15_sci_remove(struct acpi_device *device, int type)
+static int xo15_sci_remove(struct acpi_device *device)
 {
        acpi_disable_gpe(NULL, xo15_sci_gpe);
        acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
index cc2f8c1..872eb60 100644 (file)
@@ -55,7 +55,7 @@ static FILE           *input_file;    /* Input file name */
 static void usage(const char *err)
 {
        if (err)
-               fprintf(stderr, "Error: %s\n\n", err);
+               fprintf(stderr, "%s: Error: %s\n\n", prog, err);
        fprintf(stderr, "Usage: %s [-y|-n|-v] [-s seed[,no]] [-m max] [-i input]\n", prog);
        fprintf(stderr, "\t-y   64bit mode\n");
        fprintf(stderr, "\t-n   32bit mode\n");
@@ -269,7 +269,13 @@ int main(int argc, char **argv)
                insns++;
        }
 
-       fprintf(stdout, "%s: decoded and checked %d %s instructions with %d errors (seed:0x%x)\n", (errors) ? "Failure" : "Success", insns, (input_file) ? "given" : "random", errors, seed);
+       fprintf(stdout, "%s: %s: decoded and checked %d %s instructions with %d errors (seed:0x%x)\n",
+               prog,
+               (errors) ? "Failure" : "Success",
+               insns,
+               (input_file) ? "given" : "random",
+               errors,
+               seed);
 
        return errors ? 1 : 0;
 }
index 4acb5fe..172a02a 100644 (file)
@@ -170,4 +170,19 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
        consistent_sync(vaddr, size, direction);
 }
 
+/* Not supported for now */
+static inline int dma_mmap_coherent(struct device *dev,
+                                   struct vm_area_struct *vma, void *cpu_addr,
+                                   dma_addr_t dma_addr, size_t size)
+{
+       return -EINVAL;
+}
+
+static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+                                 void *cpu_addr, dma_addr_t dma_addr,
+                                 size_t size)
+{
+       return -EINVAL;
+}
+
 #endif /* _XTENSA_DMA_MAPPING_H */
index 9a289d7..3993ebf 100644 (file)
@@ -35,6 +35,8 @@ static DEFINE_IDR(ext_devt_idr);
 
 static struct device_type disk_type;
 
+static void disk_check_events(struct disk_events *ev,
+                             unsigned int *clearing_ptr);
 static void disk_alloc_events(struct gendisk *disk);
 static void disk_add_events(struct gendisk *disk);
 static void disk_del_events(struct gendisk *disk);
@@ -1549,6 +1551,7 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask)
        const struct block_device_operations *bdops = disk->fops;
        struct disk_events *ev = disk->ev;
        unsigned int pending;
+       unsigned int clearing = mask;
 
        if (!ev) {
                /* for drivers still using the old ->media_changed method */
@@ -1558,34 +1561,53 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask)
                return 0;
        }
 
-       /* tell the workfn about the events being cleared */
+       disk_block_events(disk);
+
+       /*
+        * store the union of mask and ev->clearing on the stack so that the
+        * race with disk_flush_events does not cause ambiguity (ev->clearing
+        * can still be modified even if events are blocked).
+        */
        spin_lock_irq(&ev->lock);
-       ev->clearing |= mask;
+       clearing |= ev->clearing;
+       ev->clearing = 0;
        spin_unlock_irq(&ev->lock);
 
-       /* uncondtionally schedule event check and wait for it to finish */
-       disk_block_events(disk);
-       queue_delayed_work(system_freezable_wq, &ev->dwork, 0);
-       flush_delayed_work(&ev->dwork);
-       __disk_unblock_events(disk, false);
+       disk_check_events(ev, &clearing);
+       /*
+        * if ev->clearing is not 0, the disk_flush_events got called in the
+        * middle of this function, so we want to run the workfn without delay.
+        */
+       __disk_unblock_events(disk, ev->clearing ? true : false);
 
        /* then, fetch and clear pending events */
        spin_lock_irq(&ev->lock);
-       WARN_ON_ONCE(ev->clearing & mask);      /* cleared by workfn */
        pending = ev->pending & mask;
        ev->pending &= ~mask;
        spin_unlock_irq(&ev->lock);
+       WARN_ON_ONCE(clearing & mask);
 
        return pending;
 }
 
+/*
+ * Separate this part out so that a different pointer for clearing_ptr can be
+ * passed in for disk_clear_events.
+ */
 static void disk_events_workfn(struct work_struct *work)
 {
        struct delayed_work *dwork = to_delayed_work(work);
        struct disk_events *ev = container_of(dwork, struct disk_events, dwork);
+
+       disk_check_events(ev, &ev->clearing);
+}
+
+static void disk_check_events(struct disk_events *ev,
+                             unsigned int *clearing_ptr)
+{
        struct gendisk *disk = ev->disk;
        char *envp[ARRAY_SIZE(disk_uevents) + 1] = { };
-       unsigned int clearing = ev->clearing;
+       unsigned int clearing = *clearing_ptr;
        unsigned int events;
        unsigned long intv;
        int nr_events = 0, i;
@@ -1598,7 +1620,7 @@ static void disk_events_workfn(struct work_struct *work)
 
        events &= ~ev->pending;
        ev->pending |= events;
-       ev->clearing &= ~clearing;
+       *clearing_ptr &= ~clearing;
 
        intv = disk_events_poll_jiffies(disk);
        if (!ev->block && intv)
index f5fb072..2b4e89b 100644 (file)
@@ -134,6 +134,8 @@ source "drivers/hwspinlock/Kconfig"
 
 source "drivers/clocksource/Kconfig"
 
+source "drivers/mailbox/Kconfig"
+
 source "drivers/iommu/Kconfig"
 
 source "drivers/remoteproc/Kconfig"
index 7863b9f..a8d32f1 100644 (file)
@@ -130,6 +130,7 @@ obj-y                               += platform/
 #common clk code
 obj-y                          += clk/
 
+obj-$(CONFIG_MAILBOX)          += mailbox/
 obj-$(CONFIG_HWSPINLOCK)       += hwspinlock/
 obj-$(CONFIG_NFC)              += nfc/
 obj-$(CONFIG_IOMMU_SUPPORT)    += iommu/
index 38c5078..78105b3 100644 (file)
@@ -337,7 +337,7 @@ config X86_PM_TIMER
          systems require this timer. 
 
 config ACPI_CONTAINER
-       tristate "Container and Module Devices (EXPERIMENTAL)"
+       bool "Container and Module Devices (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
        help
index 2a4502b..474fcfe 100644 (file)
@@ -37,7 +37,8 @@ acpi-y                                += resource.o
 acpi-y                         += processor_core.o
 acpi-y                         += ec.o
 acpi-$(CONFIG_ACPI_DOCK)       += dock.o
-acpi-y                         += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-y                         += pci_root.o pci_link.o pci_irq.o
+acpi-y                         += csrt.o
 acpi-y                         += acpi_platform.o
 acpi-y                         += power.o
 acpi-y                         += event.o
index d5fdd36..6d5bf64 100644 (file)
@@ -60,7 +60,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file);
 #endif
 
 static int acpi_ac_add(struct acpi_device *device);
-static int acpi_ac_remove(struct acpi_device *device, int type);
+static int acpi_ac_remove(struct acpi_device *device);
 static void acpi_ac_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id ac_device_ids[] = {
@@ -337,7 +337,7 @@ static int acpi_ac_resume(struct device *dev)
 }
 #endif
 
-static int acpi_ac_remove(struct acpi_device *device, int type)
+static int acpi_ac_remove(struct acpi_device *device)
 {
        struct acpi_ac *ac = NULL;
 
index b679bf8..034d3e7 100644 (file)
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
 #define MEMORY_POWER_OFF_STATE 2
 
 static int acpi_memory_device_add(struct acpi_device *device);
-static int acpi_memory_device_remove(struct acpi_device *device, int type);
+static int acpi_memory_device_remove(struct acpi_device *device);
 
 static const struct acpi_device_id memory_device_ids[] = {
        {ACPI_MEMORY_DEVICE_HID, 0},
@@ -153,51 +153,46 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
        return 0;
 }
 
-static int
-acpi_memory_get_device(acpi_handle handle,
-                      struct acpi_memory_device **mem_device)
+static int acpi_memory_get_device(acpi_handle handle,
+                                 struct acpi_memory_device **mem_device)
 {
-       acpi_status status;
-       acpi_handle phandle;
        struct acpi_device *device = NULL;
-       struct acpi_device *pdevice = NULL;
-       int result;
+       int result = 0;
 
+       acpi_scan_lock_acquire();
 
-       if (!acpi_bus_get_device(handle, &device) && device)
+       acpi_bus_get_device(handle, &device);
+       if (device)
                goto end;
 
-       status = acpi_get_parent(handle, &phandle);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Cannot find acpi parent"));
-               return -EINVAL;
-       }
-
-       /* Get the parent device */
-       result = acpi_bus_get_device(phandle, &pdevice);
-       if (result) {
-               acpi_handle_warn(phandle, "Cannot get acpi bus device\n");
-               return -EINVAL;
-       }
-
        /*
         * Now add the notified device.  This creates the acpi_device
         * and invokes .add function
         */
-       result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
+       result = acpi_bus_scan(handle);
        if (result) {
-               acpi_handle_warn(handle, "Cannot add acpi bus\n");
-               return -EINVAL;
+               acpi_handle_warn(handle, "ACPI namespace scan failed\n");
+               result = -EINVAL;
+               goto out;
+       }
+       result = acpi_bus_get_device(handle, &device);
+       if (result) {
+               acpi_handle_warn(handle, "Missing device object\n");
+               result = -EINVAL;
+               goto out;
        }
 
     end:
+ end:
        *mem_device = acpi_driver_data(device);
        if (!(*mem_device)) {
                dev_err(&device->dev, "driver data not found\n");
-               return -ENODEV;
+               result = -ENODEV;
+               goto out;
        }
 
-       return 0;
+ out:
+       acpi_scan_lock_release();
+       return result;
 }
 
 static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
@@ -317,6 +312,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
        struct acpi_device *device;
        struct acpi_eject_event *ej_event = NULL;
        u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
+       acpi_status status;
 
        switch (event) {
        case ACPI_NOTIFY_BUS_CHECK:
@@ -339,29 +335,40 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "\nReceived EJECT REQUEST notification for device\n"));
 
+               status = AE_ERROR;
+               acpi_scan_lock_acquire();
+
                if (acpi_bus_get_device(handle, &device)) {
                        acpi_handle_err(handle, "Device doesn't exist\n");
-                       break;
+                       goto unlock;
                }
                mem_device = acpi_driver_data(device);
                if (!mem_device) {
                        acpi_handle_err(handle, "Driver Data is NULL\n");
-                       break;
+                       goto unlock;
                }
 
                ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
                if (!ej_event) {
                        pr_err(PREFIX "No memory, dropping EJECT\n");
-                       break;
+                       goto unlock;
                }
 
-               ej_event->handle = handle;
+               get_device(&device->dev);
+               ej_event->device = device;
                ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-               acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
-                                       (void *)ej_event);
+               /* The eject is carried out asynchronously. */
+               status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
+                                                ej_event);
+               if (ACPI_FAILURE(status)) {
+                       put_device(&device->dev);
+                       kfree(ej_event);
+               }
 
-               /* eject is performed asynchronously */
-               return;
+ unlock:
+               acpi_scan_lock_release();
+               if (ACPI_SUCCESS(status))
+                       return;
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Unsupported event [0x%x]\n", event));
@@ -372,7 +379,6 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
 
        /* Inform firmware that the hotplug operation has completed */
        (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
-       return;
 }
 
 static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
@@ -427,7 +433,7 @@ static int acpi_memory_device_add(struct acpi_device *device)
        return result;
 }
 
-static int acpi_memory_device_remove(struct acpi_device *device, int type)
+static int acpi_memory_device_remove(struct acpi_device *device)
 {
        struct acpi_memory_device *mem_device = NULL;
        int result;
index 16fa979..31de104 100644 (file)
@@ -482,8 +482,7 @@ static int acpi_pad_add(struct acpi_device *device)
        return 0;
 }
 
-static int acpi_pad_remove(struct acpi_device *device,
-       int type)
+static int acpi_pad_remove(struct acpi_device *device)
 {
        mutex_lock(&isolated_cpus_lock);
        acpi_pad_idle_cpus(0);
index db129b9..26fce4b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/acpi.h>
 #include <linux/device.h>
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
 ACPI_MODULE_NAME("platform");
 
+/* Flags for acpi_create_platform_device */
+#define ACPI_PLATFORM_CLK      BIT(0)
+
+/*
+ * The following ACPI IDs are known to be suitable for representing as
+ * platform devices.
+ */
+static const struct acpi_device_id acpi_platform_device_ids[] = {
+
+       { "PNP0D40" },
+
+       /* Haswell LPSS devices */
+       { "INT33C0", ACPI_PLATFORM_CLK },
+       { "INT33C1", ACPI_PLATFORM_CLK },
+       { "INT33C2", ACPI_PLATFORM_CLK },
+       { "INT33C3", ACPI_PLATFORM_CLK },
+       { "INT33C4", ACPI_PLATFORM_CLK },
+       { "INT33C5", ACPI_PLATFORM_CLK },
+       { "INT33C6", ACPI_PLATFORM_CLK },
+       { "INT33C7", ACPI_PLATFORM_CLK },
+
+       { }
+};
+
+static int acpi_create_platform_clks(struct acpi_device *adev)
+{
+       static struct platform_device *pdev;
+
+       /* Create Lynxpoint LPSS clocks */
+       if (!pdev && !strncmp(acpi_device_hid(adev), "INT33C", 6)) {
+               pdev = platform_device_register_simple("clk-lpt", -1, NULL, 0);
+               if (IS_ERR(pdev))
+                       return PTR_ERR(pdev);
+       }
+
+       return 0;
+}
+
 /**
  * acpi_create_platform_device - Create platform device for ACPI device node
  * @adev: ACPI device node to create a platform device for.
+ * @id: ACPI device ID used to match @adev.
  *
  * Check if the given @adev can be represented as a platform device and, if
  * that's the case, create and register a platform device, populate its common
  * resources and returns a pointer to it.  Otherwise, return %NULL.
  *
- * The platform device's name will be taken from the @adev's _HID and _UID.
+ * Name of the platform device will be the same as @adev's.
  */
-struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
+static int acpi_create_platform_device(struct acpi_device *adev,
+                                      const struct acpi_device_id *id)
 {
+       unsigned long flags = id->driver_data;
        struct platform_device *pdev = NULL;
        struct acpi_device *acpi_parent;
        struct platform_device_info pdevinfo;
@@ -41,20 +83,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
        struct resource *resources;
        int count;
 
+       if (flags & ACPI_PLATFORM_CLK) {
+               int ret = acpi_create_platform_clks(adev);
+               if (ret) {
+                       dev_err(&adev->dev, "failed to create clocks\n");
+                       return ret;
+               }
+       }
+
        /* If the ACPI node already has a physical device attached, skip it. */
        if (adev->physical_node_count)
-               return NULL;
+               return 0;
 
        INIT_LIST_HEAD(&resource_list);
        count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
        if (count <= 0)
-               return NULL;
+               return 0;
 
        resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
        if (!resources) {
                dev_err(&adev->dev, "No memory for resources\n");
                acpi_dev_free_resource_list(&resource_list);
-               return NULL;
+               return -ENOMEM;
        }
        count = 0;
        list_for_each_entry(rentry, &resource_list, node)
@@ -100,5 +150,15 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
        }
 
        kfree(resources);
-       return pdev;
+       return 1;
+}
+
+static struct acpi_scan_handler platform_handler = {
+       .ids = acpi_platform_device_ids,
+       .attach = acpi_create_platform_device,
+};
+
+void __init acpi_platform_init(void)
+{
+       acpi_scan_add_handler(&platform_handler);
 }
index bc7a03d..a1b9bf5 100644 (file)
@@ -31,6 +31,7 @@ acpi-y +=             \
        evgpeinit.o     \
        evgpeutil.o     \
        evglock.o       \
+       evhandler.o     \
        evmisc.o        \
        evregion.o      \
        evrgnini.o      \
@@ -90,6 +91,7 @@ acpi-y +=             \
        nsobject.o      \
        nsparse.o       \
        nspredef.o      \
+       nsprepkg.o      \
        nsrepair.o      \
        nsrepair2.o     \
        nssearch.o      \
@@ -104,7 +106,9 @@ acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
 acpi-y +=              \
        psargs.o        \
        psloop.o        \
+       psobject.o      \
        psopcode.o      \
+       psopinfo.o      \
        psparse.o       \
        psscope.o       \
        pstree.o        \
@@ -126,7 +130,7 @@ acpi-y +=           \
        rsutils.o       \
        rsxface.o
 
-acpi-$(ACPI_FUTURE_USAGE) += rsdump.o
+acpi-$(ACPI_FUTURE_USAGE) += rsdump.o rsdumpinfo.o
 
 acpi-y +=              \
        tbfadt.o        \
@@ -155,8 +159,10 @@ acpi-y +=          \
        utmutex.o       \
        utobject.o      \
        utosi.o         \
+       utownerid.o     \
        utresrc.o       \
        utstate.o       \
+       utstring.o      \
        utxface.o       \
        utxfinit.o      \
        utxferror.o     \
index 8a7d51b..8a6c4a0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,7 @@
  *
  * Note: The order of these include files is important.
  */
+#include <acpi/acconfig.h>     /* Global configuration constants */
 #include "acmacros.h"          /* C macros */
 #include "aclocal.h"           /* Internal data types */
 #include "acobject.h"          /* ACPI internal object */
index 432a318..9feba08 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -115,6 +115,21 @@ ACPI_HW_DEPENDENT_RETURN_VOID(void
                                                   char *block_arg))
 
 /*
+ * dbconvert - miscellaneous conversion routines
+ */
+ acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value);
+
+acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object);
+
+acpi_status
+acpi_db_convert_to_object(acpi_object_type type,
+                         char *string, union acpi_object *object);
+
+u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info);
+
+void acpi_db_dump_pld_buffer(union acpi_object *obj_desc);
+
+/*
  * dbmethod - control method commands
  */
 void
@@ -191,6 +206,8 @@ void
 acpi_db_create_execution_threads(char *num_threads_arg,
                                 char *num_loops_arg, char *method_name_arg);
 
+void acpi_db_delete_objects(u32 count, union acpi_object *objects);
+
 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
 u32 acpi_db_get_cache_info(struct acpi_memory_list *cache);
 #endif
index ed33ebc..427db72 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e975c67..ab0e977 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -158,10 +158,23 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
                            void *context);
 
 /*
- * evregion - Address Space handling
+ * evhandler - Address space handling
  */
+u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+                           acpi_adr_space_type space_id);
+
 acpi_status acpi_ev_install_region_handlers(void);
 
+acpi_status
+acpi_ev_install_space_handler(struct acpi_namespace_node *node,
+                             acpi_adr_space_type space_id,
+                             acpi_adr_space_handler handler,
+                             acpi_adr_space_setup setup, void *context);
+
+/*
+ * evregion - Operation region support
+ */
 acpi_status acpi_ev_initialize_op_regions(void);
 
 acpi_status
@@ -180,12 +193,6 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
                      u8 acpi_ns_is_locked);
 
 acpi_status
-acpi_ev_install_space_handler(struct acpi_namespace_node *node,
-                             acpi_adr_space_type space_id,
-                             acpi_adr_space_handler handler,
-                             acpi_adr_space_setup setup, void *context);
-
-acpi_status
 acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
                            acpi_adr_space_type space_id);
 
index 64472e4..ecb4992 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -192,14 +192,6 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
 ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
 ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
 
-/* Mutex for _OSI support */
-
-ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex;
-
-/* Reader/Writer lock is used for namespace walk and dynamic table unload */
-
-ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
-
 /*****************************************************************************
  *
  * Mutual exclusion within ACPICA subsystem
@@ -233,6 +225,14 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
 ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock;   /* For GPE data structs and registers */
 ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock;      /* For ACPI H/W except GPE registers */
 
+/* Mutex for _OSI support */
+
+ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex;
+
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
+
 /*****************************************************************************
  *
  * Miscellaneous globals
@@ -252,7 +252,7 @@ ACPI_EXTERN acpi_cache_t *acpi_gbl_operand_cache;
 ACPI_EXTERN struct acpi_global_notify_handler acpi_gbl_global_notify[2];
 ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
 ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
-ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler;
+ACPI_EXTERN acpi_table_handler acpi_gbl_table_handler;
 ACPI_EXTERN void *acpi_gbl_table_handler_context;
 ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
 ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler;
@@ -304,6 +304,7 @@ extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
 ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list;
 ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list;
 ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats;
+ACPI_EXTERN u8 acpi_gbl_disable_mem_tracking;
 #endif
 
 /*****************************************************************************
@@ -365,19 +366,18 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
  *
  ****************************************************************************/
 
-extern struct acpi_fixed_event_info
-    acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN struct acpi_fixed_event_handler
-    acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
-ACPI_EXTERN struct acpi_gpe_block_info
-*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
-
 #if (!ACPI_REDUCED_HARDWARE)
 
 ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
+ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
+ACPI_EXTERN struct acpi_gpe_block_info
+    *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
 ACPI_EXTERN acpi_gbl_event_handler acpi_gbl_global_event_handler;
 ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
+ACPI_EXTERN struct acpi_fixed_event_handler
+    acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
+extern struct acpi_fixed_event_info
+    acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
 
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
@@ -405,7 +405,7 @@ ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer;
 
 /*****************************************************************************
  *
- * Debugger globals
+ * Debugger and Disassembler globals
  *
  ****************************************************************************/
 
@@ -413,8 +413,12 @@ ACPI_EXTERN u8 acpi_gbl_db_output_flags;
 
 #ifdef ACPI_DISASSEMBLER
 
+u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE);
+
 ACPI_EXTERN u8 acpi_gbl_db_opt_disasm;
 ACPI_EXTERN u8 acpi_gbl_db_opt_verbose;
+ACPI_EXTERN struct acpi_external_list *acpi_gbl_external_list;
+ACPI_EXTERN struct acpi_external_file *acpi_gbl_external_file_list;
 #endif
 
 #ifdef ACPI_DEBUGGER
@@ -426,6 +430,7 @@ extern u8 acpi_gbl_db_terminate_threads;
 ACPI_EXTERN u8 acpi_gbl_db_opt_tables;
 ACPI_EXTERN u8 acpi_gbl_db_opt_stats;
 ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods;
+ACPI_EXTERN u8 acpi_gbl_db_opt_no_region_support;
 
 ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS];
 ACPI_EXTERN acpi_object_type acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS];
index d902d31..6357e93 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index eb30863..8af8c9b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -458,7 +458,7 @@ void acpi_ex_reacquire_interpreter(void);
 
 void acpi_ex_relinquish_interpreter(void);
 
-void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc);
+u8 acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc);
 
 void acpi_ex_acquire_global_lock(u32 rule);
 
index ff8bd00..805f419 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -189,11 +189,10 @@ struct acpi_namespace_node {
 #define ANOBJ_EVALUATED                 0x20   /* Set on first evaluation of node */
 #define ANOBJ_ALLOCATED_BUFFER          0x40   /* Method AML buffer is dynamic (install_method) */
 
-#define ANOBJ_IS_EXTERNAL               0x08   /* i_aSL only: This object created via External() */
-#define ANOBJ_METHOD_NO_RETVAL          0x10   /* i_aSL only: Method has no return value */
-#define ANOBJ_METHOD_SOME_NO_RETVAL     0x20   /* i_aSL only: Method has at least one return value */
-#define ANOBJ_IS_BIT_OFFSET             0x40   /* i_aSL only: Reference is a bit offset */
-#define ANOBJ_IS_REFERENCED             0x80   /* i_aSL only: Object was referenced */
+#define ANOBJ_IS_EXTERNAL               0x08   /* iASL only: This object created via External() */
+#define ANOBJ_METHOD_NO_RETVAL          0x10   /* iASL only: Method has no return value */
+#define ANOBJ_METHOD_SOME_NO_RETVAL     0x20   /* iASL only: Method has at least one return value */
+#define ANOBJ_IS_REFERENCED             0x80   /* iASL only: Object was referenced */
 
 /* Internal ACPI table management - master table list */
 
@@ -411,11 +410,10 @@ struct acpi_gpe_notify_info {
        struct acpi_gpe_notify_info *next;
 };
 
-struct acpi_gpe_notify_object {
-       struct acpi_namespace_node *node;
-       struct acpi_gpe_notify_object *next;
-};
-
+/*
+ * GPE dispatch info. At any time, the GPE can have at most one type
+ * of dispatch - Method, Handler, or Implicit Notify.
+ */
 union acpi_gpe_dispatch_info {
        struct acpi_namespace_node *method_node;        /* Method node for this GPE level */
        struct acpi_gpe_handler_info *handler;  /* Installed GPE handler */
@@ -679,6 +677,8 @@ struct acpi_opcode_info {
        u8 type;                /* Opcode type */
 };
 
+/* Value associated with the parse object */
+
 union acpi_parse_value {
        u64 integer;            /* Integer constant (Up to 64 bits) */
        u32 size;               /* bytelist or field size */
@@ -1025,6 +1025,31 @@ struct acpi_port_info {
 
 /*****************************************************************************
  *
+ * Disassembler
+ *
+ ****************************************************************************/
+
+struct acpi_external_list {
+       char *path;
+       char *internal_path;
+       struct acpi_external_list *next;
+       u32 value;
+       u16 length;
+       u8 type;
+       u8 flags;
+};
+
+/* Values for Flags field above */
+
+#define ACPI_IPATH_ALLOCATED    0x01
+
+struct acpi_external_file {
+       char *path;
+       struct acpi_external_file *next;
+};
+
+/*****************************************************************************
+ *
  * Debugger
  *
  ****************************************************************************/
index 5efad99..ed7943b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * get into potential aligment issues -- see the STORE macros below.
  * Use with care.
  */
-#define ACPI_GET8(ptr)                  *ACPI_CAST_PTR (u8, ptr)
-#define ACPI_GET16(ptr)                 *ACPI_CAST_PTR (u16, ptr)
-#define ACPI_GET32(ptr)                 *ACPI_CAST_PTR (u32, ptr)
-#define ACPI_GET64(ptr)                 *ACPI_CAST_PTR (u64, ptr)
-#define ACPI_SET8(ptr)                  *ACPI_CAST_PTR (u8, ptr)
-#define ACPI_SET16(ptr)                 *ACPI_CAST_PTR (u16, ptr)
-#define ACPI_SET32(ptr)                 *ACPI_CAST_PTR (u32, ptr)
-#define ACPI_SET64(ptr)                 *ACPI_CAST_PTR (u64, ptr)
+#define ACPI_CAST8(ptr)                 ACPI_CAST_PTR (u8, (ptr))
+#define ACPI_CAST16(ptr)                ACPI_CAST_PTR (u16, (ptr))
+#define ACPI_CAST32(ptr)                ACPI_CAST_PTR (u32, (ptr))
+#define ACPI_CAST64(ptr)                ACPI_CAST_PTR (u64, (ptr))
+#define ACPI_GET8(ptr)                  (*ACPI_CAST8 (ptr))
+#define ACPI_GET16(ptr)                 (*ACPI_CAST16 (ptr))
+#define ACPI_GET32(ptr)                 (*ACPI_CAST32 (ptr))
+#define ACPI_GET64(ptr)                 (*ACPI_CAST64 (ptr))
+#define ACPI_SET8(ptr, val)             (*ACPI_CAST8 (ptr) = (u8) (val))
+#define ACPI_SET16(ptr, val)            (*ACPI_CAST16 (ptr) = (u16) (val))
+#define ACPI_SET32(ptr, val)            (*ACPI_CAST32 (ptr) = (u32) (val))
+#define ACPI_SET64(ptr, val)            (*ACPI_CAST64 (ptr) = (u64) (val))
 
 /*
  * printf() format helpers
 #define ACPI_16BIT_MASK     0x0000FFFF
 #define ACPI_24BIT_MASK     0x00FFFFFF
 
+/* Macros to extract flag bits from position zero */
+
+#define ACPI_GET_1BIT_FLAG(value)                   ((value) & ACPI_1BIT_MASK)
+#define ACPI_GET_2BIT_FLAG(value)                   ((value) & ACPI_2BIT_MASK)
+#define ACPI_GET_3BIT_FLAG(value)                   ((value) & ACPI_3BIT_MASK)
+#define ACPI_GET_4BIT_FLAG(value)                   ((value) & ACPI_4BIT_MASK)
+
+/* Macros to extract flag bits from position one and above */
+
+#define ACPI_EXTRACT_1BIT_FLAG(field, position)     (ACPI_GET_1BIT_FLAG ((field) >> position))
+#define ACPI_EXTRACT_2BIT_FLAG(field, position)     (ACPI_GET_2BIT_FLAG ((field) >> position))
+#define ACPI_EXTRACT_3BIT_FLAG(field, position)     (ACPI_GET_3BIT_FLAG ((field) >> position))
+#define ACPI_EXTRACT_4BIT_FLAG(field, position)     (ACPI_GET_4BIT_FLAG ((field) >> position))
+
+/* ACPI Pathname helpers */
+
+#define ACPI_IS_ROOT_PREFIX(c)      ((c) == (u8) 0x5C) /* Backslash */
+#define ACPI_IS_PARENT_PREFIX(c)    ((c) == (u8) 0x5E) /* Carat */
+#define ACPI_IS_PATH_SEPARATOR(c)   ((c) == (u8) 0x2E) /* Period (dot) */
+
 /*
  * An object of type struct acpi_namespace_node can appear in some contexts
  * where a pointer to an object of type union acpi_operand_object can also
 
 #endif                         /* ACPI_NO_ERROR_MESSAGES */
 
-/*
- * Debug macros that are conditionally compiled
- */
-#ifdef ACPI_DEBUG_OUTPUT
-/*
- * Function entry tracing
- */
-#define ACPI_FUNCTION_TRACE(a)          ACPI_FUNCTION_NAME(a) \
-                         acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
-#define ACPI_FUNCTION_TRACE_PTR(a, b)   ACPI_FUNCTION_NAME(a) \
-                                          acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS, (void *)b)
-#define ACPI_FUNCTION_TRACE_U32(a, b)   ACPI_FUNCTION_NAME(a) \
-                                                        acpi_ut_trace_u32(ACPI_DEBUG_PARAMETERS, (u32)b)
-#define ACPI_FUNCTION_TRACE_STR(a, b)   ACPI_FUNCTION_NAME(a) \
-                                                                         acpi_ut_trace_str(ACPI_DEBUG_PARAMETERS, (char *)b)
-
-#define ACPI_FUNCTION_ENTRY()           acpi_ut_track_stack_ptr()
-
-/*
- * Function exit tracing.
- * WARNING: These macros include a return statement. This is usually considered
- * bad form, but having a separate exit macro is very ugly and difficult to maintain.
- * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
- * so that "_AcpiFunctionName" is defined.
- *
- * Note: the DO_WHILE0 macro is used to prevent some compilers from complaining
- * about these constructs.
- */
-#ifdef ACPI_USE_DO_WHILE_0
-#define ACPI_DO_WHILE0(a)               do a while(0)
-#else
-#define ACPI_DO_WHILE0(a)               a
-#endif
-
-#define return_VOID                     ACPI_DO_WHILE0 ({ \
-                                                                                       acpi_ut_exit (ACPI_DEBUG_PARAMETERS); \
-                                                                                       return;})
-/*
- * There are two versions of most of the return macros. The default version is
- * safer, since it avoids side-effects by guaranteeing that the argument will
- * not be evaluated twice.
- *
- * A less-safe version of the macros is provided for optional use if the
- * compiler uses excessive CPU stack (for example, this may happen in the
- * debug case if code optimzation is disabled.)
- */
-#ifndef ACPI_SIMPLE_RETURN_MACROS
-
-#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({ \
-                                                                                       register acpi_status _s = (s); \
-                                                                                       acpi_ut_status_exit (ACPI_DEBUG_PARAMETERS, _s); \
-                                                                                       return (_s); })
-#define return_PTR(s)                   ACPI_DO_WHILE0 ({ \
-                                                                                       register void *_s = (void *) (s); \
-                                                                                       acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) _s); \
-                                                                                       return (_s); })
-#define return_VALUE(s)                 ACPI_DO_WHILE0 ({ \
-                                                                                       register u64 _s = (s); \
-                                                                                       acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \
-                                                                                       return (_s); })
-#define return_UINT8(s)                 ACPI_DO_WHILE0 ({ \
-                                                                                       register u8 _s = (u8) (s); \
-                                                                                       acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \
-                                                                                       return (_s); })
-#define return_UINT32(s)                ACPI_DO_WHILE0 ({ \
-                                                                                       register u32 _s = (u32) (s); \
-                                                                                       acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) _s); \
-                                                                                       return (_s); })
-#else                          /* Use original less-safe macros */
-
-#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({ \
-                                                                                       acpi_ut_status_exit (ACPI_DEBUG_PARAMETERS, (s)); \
-                                                                                       return((s)); })
-#define return_PTR(s)                   ACPI_DO_WHILE0 ({ \
-                                                                                       acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) (s)); \
-                                                                                       return((s)); })
-#define return_VALUE(s)                 ACPI_DO_WHILE0 ({ \
-                                                                                       acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (u64) (s)); \
-                                                                                       return((s)); })
-#define return_UINT8(s)                 return_VALUE(s)
-#define return_UINT32(s)                return_VALUE(s)
-
-#endif                         /* ACPI_SIMPLE_RETURN_MACROS */
-
-/* Conditional execution */
-
-#define ACPI_DEBUG_EXEC(a)              a
-#define ACPI_DEBUG_ONLY_MEMBERS(a)      a;
-#define _VERBOSE_STRUCTURES
-
-/* Various object display routines for debug */
-
-#define ACPI_DUMP_STACK_ENTRY(a)        acpi_ex_dump_operand((a), 0)
-#define ACPI_DUMP_OPERANDS(a, b ,c)     acpi_ex_dump_operands(a, b, c)
-#define ACPI_DUMP_ENTRY(a, b)           acpi_ns_dump_entry (a, b)
-#define ACPI_DUMP_PATHNAME(a, b, c, d)  acpi_ns_dump_pathname(a, b, c, d)
-#define ACPI_DUMP_BUFFER(a, b)          acpi_ut_debug_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT)
-
-#else
-/*
- * This is the non-debug case -- make everything go away,
- * leaving no executable debug code!
- */
-#define ACPI_DEBUG_EXEC(a)
-#define ACPI_DEBUG_ONLY_MEMBERS(a)
-#define ACPI_FUNCTION_TRACE(a)
-#define ACPI_FUNCTION_TRACE_PTR(a, b)
-#define ACPI_FUNCTION_TRACE_U32(a, b)
-#define ACPI_FUNCTION_TRACE_STR(a, b)
-#define ACPI_FUNCTION_EXIT
-#define ACPI_FUNCTION_STATUS_EXIT(s)
-#define ACPI_FUNCTION_VALUE_EXIT(s)
-#define ACPI_FUNCTION_ENTRY()
-#define ACPI_DUMP_STACK_ENTRY(a)
-#define ACPI_DUMP_OPERANDS(a, b, c)
-#define ACPI_DUMP_ENTRY(a, b)
-#define ACPI_DUMP_TABLES(a, b)
-#define ACPI_DUMP_PATHNAME(a, b, c, d)
-#define ACPI_DUMP_BUFFER(a, b)
-#define ACPI_DEBUG_PRINT(pl)
-#define ACPI_DEBUG_PRINT_RAW(pl)
-
-#define return_VOID                     return
-#define return_ACPI_STATUS(s)           return(s)
-#define return_VALUE(s)                 return(s)
-#define return_UINT8(s)                 return(s)
-#define return_UINT32(s)                return(s)
-#define return_PTR(s)                   return(s)
-
-#endif                         /* ACPI_DEBUG_OUTPUT */
-
 #if (!ACPI_REDUCED_HARDWARE)
 #define ACPI_HW_OPTIONAL_FUNCTION(addr)     addr
 #else
index 9b19d4b..02cd548 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -218,6 +218,18 @@ acpi_ns_check_parameter_count(char *pathname,
                              u32 user_param_count,
                              const union acpi_predefined_info *info);
 
+acpi_status
+acpi_ns_check_object_type(struct acpi_predefined_data *data,
+                         union acpi_operand_object **return_object_ptr,
+                         u32 expected_btypes, u32 package_index);
+
+/*
+ * nsprepkg - Validation of predefined name packages
+ */
+acpi_status
+acpi_ns_check_package(struct acpi_predefined_data *data,
+                     union acpi_operand_object **return_object_ptr);
+
 /*
  * nsnames - Name and Scope manipulation
  */
@@ -333,8 +345,6 @@ acpi_ns_install_node(struct acpi_walk_state *walk_state,
 /*
  * nsutils - Utility functions
  */
-u8 acpi_ns_valid_root_prefix(char prefix);
-
 acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node);
 
 u32 acpi_ns_local(acpi_object_type type);
index 24eb9ea..cc7ab6d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -307,7 +307,7 @@ struct acpi_object_addr_handler {
        struct acpi_namespace_node *node;       /* Parent device */
        void *context;
        acpi_adr_space_setup setup;
-       union acpi_operand_object *region_list; /* regions using this handler */
+       union acpi_operand_object *region_list; /* Regions using this handler */
        union acpi_operand_object *next;
 };
 
index d786a51..3fc9ca7 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index eefcf47..aed3193 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -105,7 +105,28 @@ union acpi_parse_object *acpi_ps_find_name(union acpi_parse_object *scope,
 union acpi_parse_object *acpi_ps_get_parent(union acpi_parse_object *op);
 
 /*
- * psopcode - AML Opcode information
+ * psobject - support for parse object processing
+ */
+acpi_status
+acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
+                      u8 *aml_op_start,
+                      union acpi_parse_object *unnamed_op,
+                      union acpi_parse_object **op);
+
+acpi_status
+acpi_ps_create_op(struct acpi_walk_state *walk_state,
+                 u8 *aml_op_start, union acpi_parse_object **new_op);
+
+acpi_status
+acpi_ps_complete_op(struct acpi_walk_state *walk_state,
+                   union acpi_parse_object **op, acpi_status status);
+
+acpi_status
+acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
+                         union acpi_parse_object *op, acpi_status status);
+
+/*
+ * psopinfo - AML Opcode information
  */
 const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode);
 
@@ -211,8 +232,6 @@ void acpi_ps_free_op(union acpi_parse_object *op);
 
 u8 acpi_ps_is_leading_char(u32 c);
 
-u8 acpi_ps_is_prefix_char(u32 c);
-
 #ifdef ACPI_FUTURE_USAGE
 u32 acpi_ps_get_name(union acpi_parse_object *op);
 #endif                         /* ACPI_FUTURE_USAGE */
index 9dfa1c8..752cc40 100644 (file)
@@ -1,12 +1,11 @@
 /******************************************************************************
  *
  * Name: acpredef - Information table for ACPI predefined methods and objects
- *              $Revision: 1.1 $
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  *
  * 1) PTYPE1 packages do not contain sub-packages.
  *
- * ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
+ * ACPI_PTYPE1_FIXED: Fixed-length length, 1 or 2 object types:
  *      object type
  *      count
  *      object type
  *      count
  *
- * ACPI_PTYPE1_VAR: Variable length:
+ * ACPI_PTYPE1_VAR: Variable-length length:
  *      object type (Int/Buf/Ref)
  *
  * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
  *      count
  *      (Used for _CST)
  *
- * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length
+ * ACPI_PTYPE2_FIXED: Each subpackage is of Fixed-length
  *      (Used for _PRT)
  *
- * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
+ * ACPI_PTYPE2_MIN: Each subpackage has a Variable-length but minimum length
  *      (Used for _HPX)
  *
  * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length
@@ -124,7 +123,8 @@ enum acpi_return_package_types {
  * These are the names that can actually be evaluated via acpi_evaluate_object.
  * Not present in this table are the following:
  *
- *      1) Predefined/Reserved names that are never evaluated via acpi_evaluate_object:
+ *      1) Predefined/Reserved names that are never evaluated via
+ *         acpi_evaluate_object:
  *          _Lxx and _Exx GPE methods
  *          _Qxx EC methods
  *          _T_x compiler temporary variables
@@ -149,6 +149,8 @@ enum acpi_return_package_types {
  * information about the expected structure of the package. This information
  * is saved here (rather than in a separate table) in order to minimize the
  * overall size of the stored data.
+ *
+ * Note: The additional braces are intended to promote portability.
  */
 static const union acpi_predefined_info predefined_names[] = {
        {{"_AC0", 0, ACPI_RTYPE_INTEGER}},
@@ -212,9 +214,8 @@ static const union acpi_predefined_info predefined_names[] = {
        {{"_BCT", 1, ACPI_RTYPE_INTEGER}},
        {{"_BDN", 0, ACPI_RTYPE_INTEGER}},
        {{"_BFS", 1, 0}},
-       {{"_BIF", 0, ACPI_RTYPE_PACKAGE} }, /* Fixed-length (9 Int),(4 Str/Buf) */
-                         {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9,
-                            ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}, 4, 0} },
+       {{"_BIF", 0, ACPI_RTYPE_PACKAGE}},      /* Fixed-length (9 Int),(4 Str) */
+       {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4, 0}},
 
        {{"_BIX", 0, ACPI_RTYPE_PACKAGE}},      /* Fixed-length (16 Int),(4 Str) */
        {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4,
@@ -236,7 +237,8 @@ static const union acpi_predefined_info predefined_names[] = {
        {{"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* See PCI firmware spec 3.0 */
        {{"_CDM", 0, ACPI_RTYPE_INTEGER}},
        {{"_CID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Strs) */
-                         {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0}, 0,0}},
+       {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0, 0}, 0,
+         0}},
 
        {{"_CLS", 0, ACPI_RTYPE_PACKAGE}},      /* Fixed-length (3 Int) */
        {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, 0}, 0, 0}},
@@ -251,7 +253,8 @@ static const union acpi_predefined_info predefined_names[] = {
                          {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0,0}, 0,0}},
 
        {{"_CST", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n Pkg (1 Buf/3 Int) */
-                         {{{ACPI_PTYPE2_PKG_COUNT,ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_INTEGER}, 3,0}},
+       {{{ACPI_PTYPE2_PKG_COUNT, ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_INTEGER}, 3,
+         0}},
 
        {{"_CWS", 1, ACPI_RTYPE_INTEGER}},
        {{"_DCK", 1, ACPI_RTYPE_INTEGER}},
@@ -342,8 +345,8 @@ static const union acpi_predefined_info predefined_names[] = {
        {{"_MBM", 0, ACPI_RTYPE_PACKAGE}},      /* Fixed-length (8 Int) */
        {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 8, 0}, 0, 0}},
 
-       {{"_MLS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (2 Str) */
-                         {{{ACPI_PTYPE2, ACPI_RTYPE_STRING, 2,0}, 0,0}},
+       {{"_MLS", 0, ACPI_RTYPE_PACKAGE}},      /* Variable-length (Pkgs) each (1 Str/1 Buf) */
+       {{{ACPI_PTYPE2, ACPI_RTYPE_STRING, 1, ACPI_RTYPE_BUFFER}, 1, 0}},
 
        {{"_MSG", 1, 0}},
        {{"_MSM", 4, ACPI_RTYPE_INTEGER}},
index 0347d09..f691d0e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -347,18 +347,21 @@ extern struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[];
 extern struct acpi_rsdump_info *acpi_gbl_dump_serial_bus_dispatch[];
 
 /*
- * rsdump
+ * rsdumpinfo
  */
 extern struct acpi_rsdump_info acpi_rs_dump_irq[];
+extern struct acpi_rsdump_info acpi_rs_dump_prt[];
 extern struct acpi_rsdump_info acpi_rs_dump_dma[];
 extern struct acpi_rsdump_info acpi_rs_dump_start_dpf[];
 extern struct acpi_rsdump_info acpi_rs_dump_end_dpf[];
 extern struct acpi_rsdump_info acpi_rs_dump_io[];
+extern struct acpi_rsdump_info acpi_rs_dump_io_flags[];
 extern struct acpi_rsdump_info acpi_rs_dump_fixed_io[];
 extern struct acpi_rsdump_info acpi_rs_dump_vendor[];
 extern struct acpi_rsdump_info acpi_rs_dump_end_tag[];
 extern struct acpi_rsdump_info acpi_rs_dump_memory24[];
 extern struct acpi_rsdump_info acpi_rs_dump_memory32[];
+extern struct acpi_rsdump_info acpi_rs_dump_memory_flags[];
 extern struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[];
 extern struct acpi_rsdump_info acpi_rs_dump_address16[];
 extern struct acpi_rsdump_info acpi_rs_dump_address32[];
@@ -372,6 +375,7 @@ extern struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[];
 extern struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[];
 extern struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[];
 extern struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[];
+extern struct acpi_rsdump_info acpi_rs_dump_general_flags[];
 #endif
 
 #endif                         /* __ACRESRC_H__ */
index 937e66c..7896d85 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6712965..7755e91 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b0f5f92..0082fa0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -483,39 +483,17 @@ acpi_ut_short_divide(u64 in_dividend,
 /*
  * utmisc
  */
-void ut_convert_backslashes(char *pathname);
-
 const char *acpi_ut_validate_exception(acpi_status status);
 
 u8 acpi_ut_is_pci_root_bridge(char *id);
 
 u8 acpi_ut_is_aml_table(struct acpi_table_header *table);
 
-acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id);
-
-void acpi_ut_release_owner_id(acpi_owner_id * owner_id);
-
 acpi_status
 acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
                          void *target_object,
                          acpi_pkg_callback walk_callback, void *context);
 
-void acpi_ut_strupr(char *src_string);
-
-void acpi_ut_strlwr(char *src_string);
-
-int acpi_ut_stricmp(char *string1, char *string2);
-
-void acpi_ut_print_string(char *string, u8 max_length);
-
-u8 acpi_ut_valid_acpi_name(u32 name);
-
-void acpi_ut_repair_name(char *name);
-
-u8 acpi_ut_valid_acpi_char(char character, u32 position);
-
-acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer);
-
 /* Values for Base above (16=Hex, 10=Decimal) */
 
 #define ACPI_ANY_BASE        0
@@ -532,15 +510,25 @@ acpi_ut_display_init_pathname(u8 type,
 #endif
 
 /*
+ * utownerid - Support for Table/Method Owner IDs
+ */
+acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id);
+
+void acpi_ut_release_owner_id(acpi_owner_id * owner_id);
+
+/*
  * utresrc
  */
 acpi_status
-acpi_ut_walk_aml_resources(u8 *aml,
+acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
+                          u8 *aml,
                           acpi_size aml_length,
                           acpi_walk_aml_callback user_function,
                           void **context);
 
-acpi_status acpi_ut_validate_resource(void *aml, u8 *return_index);
+acpi_status
+acpi_ut_validate_resource(struct acpi_walk_state *walk_state,
+                         void *aml, u8 *return_index);
 
 u32 acpi_ut_get_descriptor_length(void *aml);
 
@@ -554,6 +542,27 @@ acpi_status
 acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag);
 
 /*
+ * utstring - String and character utilities
+ */
+void acpi_ut_strupr(char *src_string);
+
+void acpi_ut_strlwr(char *src_string);
+
+int acpi_ut_stricmp(char *string1, char *string2);
+
+acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer);
+
+void acpi_ut_print_string(char *string, u8 max_length);
+
+void ut_convert_backslashes(char *pathname);
+
+u8 acpi_ut_valid_acpi_name(u32 name);
+
+u8 acpi_ut_valid_acpi_char(char character, u32 position);
+
+void acpi_ut_repair_name(char *name);
+
+/*
  * utmutex - mutex support
  */
 acpi_status acpi_ut_mutex_initialize(void);
index c26f8ff..48a3e33 100644 (file)
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9684496..87c2636 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -199,6 +199,12 @@ struct aml_resource_fixed_dma {
 struct aml_resource_large_header {
 AML_RESOURCE_LARGE_HEADER_COMMON};
 
+/* General Flags for address space resource descriptors */
+
+#define ACPI_RESOURCE_FLAG_DEC      2
+#define ACPI_RESOURCE_FLAG_MIF      4
+#define ACPI_RESOURCE_FLAG_MAF      8
+
 struct aml_resource_memory24 {
        AML_RESOURCE_LARGE_HEADER_COMMON u8 flags;
        u16 minimum;
index c8b5e25..fb09b08 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 57895db..7ea0f16 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b5b904e..feadeed 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 87eff70..bc8e63f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 52eb4e0..a9ffd44 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,7 @@
 #include "acinterp.h"
 #include "acnamesp.h"
 #ifdef ACPI_DISASSEMBLER
-#include <acpi/acdisasm.h>
+#include "acdisasm.h"
 #endif
 
 #define _COMPONENT          ACPI_DISPATCHER
@@ -151,6 +151,7 @@ acpi_ds_create_method_mutex(union acpi_operand_object *method_desc)
 
        status = acpi_os_create_mutex(&mutex_desc->mutex.os_mutex);
        if (ACPI_FAILURE(status)) {
+               acpi_ut_delete_object_desc(mutex_desc);
                return_ACPI_STATUS(status);
        }
 
@@ -378,7 +379,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
         */
        info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
        if (!info) {
-               return_ACPI_STATUS(AE_NO_MEMORY);
+               status = AE_NO_MEMORY;
+               goto cleanup;
        }
 
        info->parameters = &this_walk_state->operands[0];
index 9a83b7e..3da8046 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c9f15d3..e20e9f8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -388,7 +388,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
        union acpi_parse_object *parent;
        union acpi_operand_object *obj_desc = NULL;
        acpi_status status = AE_OK;
-       unsigned i;
+       u32 i;
        u16 index;
        u16 reference_count;
 
@@ -525,7 +525,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
                }
 
                ACPI_INFO((AE_INFO,
-                          "Actual Package length (%u) is larger than NumElements field (%u), truncated\n",
+                          "Actual Package length (%u) is larger than NumElements field (%u), truncated",
                           i, element_count));
        } else if (i < element_count) {
                /*
@@ -703,7 +703,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
                                /* Truncate value if we are executing from a 32-bit ACPI table */
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-                               acpi_ex_truncate_for32bit_table(obj_desc);
+                               (void)acpi_ex_truncate_for32bit_table(obj_desc);
 #endif
                                break;
 
@@ -725,8 +725,18 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
                case AML_TYPE_LITERAL:
 
                        obj_desc->integer.value = op->common.value.integer;
+
 #ifndef ACPI_NO_METHOD_EXECUTION
-                       acpi_ex_truncate_for32bit_table(obj_desc);
+                       if (acpi_ex_truncate_for32bit_table(obj_desc)) {
+
+                               /* Warn if we found a 64-bit constant in a 32-bit table */
+
+                               ACPI_WARNING((AE_INFO,
+                                             "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
+                                             ACPI_FORMAT_UINT64(op->common.
+                                                                value.integer),
+                                             (u32)obj_desc->integer.value));
+                       }
 #endif
                        break;
 
index d09c6b4..ee6367b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -486,18 +486,18 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
        ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
 
        /*
-        * This is where we evaluate the signature_string and oem_iDString
-        * and oem_table_iDString of the data_table_region declaration
+        * This is where we evaluate the Signature string, oem_id string,
+        * and oem_table_id string of the Data Table Region declaration
         */
        node = op->common.node;
 
-       /* next_op points to signature_string op */
+       /* next_op points to Signature string op */
 
        next_op = op->common.value.arg;
 
        /*
-        * Evaluate/create the signature_string and oem_iDString
-        * and oem_table_iDString operands
+        * Evaluate/create the Signature string, oem_id string,
+        * and oem_table_id string operands
         */
        status = acpi_ds_create_operands(walk_state, next_op);
        if (ACPI_FAILURE(status)) {
@@ -505,8 +505,8 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
        }
 
        /*
-        * Resolve the signature_string and oem_iDString
-        * and oem_table_iDString operands
+        * Resolve the Signature string, oem_id string,
+        * and oem_table_id string operands
         */
        status = acpi_ex_resolve_operands(op->common.aml_opcode,
                                          ACPI_WALK_OPERANDS, walk_state);
index afeb99f..4d8c992 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -178,7 +178,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
 
        if (!op) {
                ACPI_ERROR((AE_INFO, "Null Op"));
-               return_UINT8(TRUE);
+               return_VALUE(TRUE);
        }
 
        /*
@@ -210,7 +210,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
                                  "At Method level, result of [%s] not used\n",
                                  acpi_ps_get_opcode_name(op->common.
                                                          aml_opcode)));
-               return_UINT8(FALSE);
+               return_VALUE(FALSE);
        }
 
        /* Get info on the parent. The root_op is AML_SCOPE */
@@ -219,7 +219,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
            acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
        if (parent_info->class == AML_CLASS_UNKNOWN) {
                ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op));
-               return_UINT8(FALSE);
+               return_VALUE(FALSE);
        }
 
        /*
@@ -307,7 +307,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
                          acpi_ps_get_opcode_name(op->common.parent->common.
                                                  aml_opcode), op));
 
-       return_UINT8(TRUE);
+       return_VALUE(TRUE);
 
       result_not_used:
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
@@ -316,7 +316,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
                          acpi_ps_get_opcode_name(op->common.parent->common.
                                                  aml_opcode), op));
 
-       return_UINT8(FALSE);
+       return_VALUE(FALSE);
 }
 
 /*******************************************************************************
index 5859393..44f8325 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -149,7 +149,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
 
        /* Truncate the predicate to 32-bits if necessary */
 
-       acpi_ex_truncate_for32bit_table(local_obj_desc);
+       (void)acpi_ex_truncate_for32bit_table(local_obj_desc);
 
        /*
         * Save the result of the predicate evaluation on
@@ -706,7 +706,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
         * ACPI 2.0 support for 64-bit integers: Truncate numeric
         * result value if we are executing from a 32-bit ACPI table
         */
-       acpi_ex_truncate_for32bit_table(walk_state->result_obj);
+       (void)acpi_ex_truncate_for32bit_table(walk_state->result_obj);
 
        /*
         * Check if we just completed the evaluation of a
index 5575100..6e17c0e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,7 +50,7 @@
 #include "acnamesp.h"
 
 #ifdef ACPI_ASL_COMPILER
-#include <acpi/acdisasm.h>
+#include "acdisasm.h"
 #endif
 
 #define _COMPONENT          ACPI_DISPATCHER
@@ -178,7 +178,8 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
                         * Target of Scope() not found. Generate an External for it, and
                         * insert the name into the namespace.
                         */
-                       acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0);
+                       acpi_dm_add_to_external_list(op, path, ACPI_TYPE_DEVICE,
+                                                    0);
                        status =
                            acpi_ns_lookup(walk_state->scope_info, path,
                                           object_type, ACPI_IMODE_LOAD_PASS1,
index 3798357..4407ff2 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -222,7 +222,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
                         */
                        ACPI_WARNING((AE_INFO,
                                      "Type override - [%4.4s] had invalid type (%s) "
-                                     "for Scope operator, changed to type ANY\n",
+                                     "for Scope operator, changed to type ANY",
                                      acpi_ut_get_node_name(node),
                                      acpi_ut_get_type_name(node->type)));
 
index f6c4295..d67891d 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 3e65a15..ecb12e2 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d4acfbb..b8ea0b2 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index af14a71..a621481 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 36d1205..b9adb9a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -561,8 +561,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
                        status = AE_NO_MEMORY;
                } else {
                        /*
-                        * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
-                        * control method that corresponds to this GPE
+                        * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
+                        * _Lxx/_Exx control method that corresponds to this GPE
                         */
                        info->prefix_node =
                            local_gpe_event_info->dispatch.method_node;
@@ -707,7 +707,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
                if (ACPI_FAILURE(status)) {
                        ACPI_EXCEPTION((AE_INFO, status,
                                        "Unable to clear GPE%02X", gpe_number));
-                       return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
+                       return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
                }
        }
 
@@ -724,7 +724,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status,
                                "Unable to disable GPE%02X", gpe_number));
-               return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
+               return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
        }
 
        /*
@@ -765,7 +765,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
                                         gpe_event_info);
                if (ACPI_FAILURE(status)) {
                        ACPI_EXCEPTION((AE_INFO, status,
-                                       "Unable to queue handler for GPE%2X - event disabled",
+                                       "Unable to queue handler for GPE%02X - event disabled",
                                        gpe_number));
                }
                break;
@@ -784,7 +784,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
                break;
        }
 
-       return_UINT32(ACPI_INTERRUPT_HANDLED);
+       return_VALUE(ACPI_INTERRUPT_HANDLED);
 }
 
 #endif                         /* !ACPI_REDUCED_HARDWARE */
index 1571a61..a2d688b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -405,13 +405,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
                (*return_gpe_block) = gpe_block;
        }
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INIT,
-                         "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
-                         (u32) gpe_block->block_base_number,
-                         (u32) (gpe_block->block_base_number +
-                               (gpe_block->gpe_count - 1)),
-                         gpe_device->name.ascii, gpe_block->register_count,
-                         interrupt_number));
+       ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+                             "    Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X\n",
+                             (u32)gpe_block->block_base_number,
+                             (u32)(gpe_block->block_base_number +
+                                   (gpe_block->gpe_count - 1)),
+                             gpe_device->name.ascii, gpe_block->register_count,
+                             interrupt_number));
 
        /* Update global count of currently available GPEs */
 
@@ -496,9 +496,11 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
        }
 
        if (gpe_enabled_count) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INIT,
-                                 "Enabled %u GPEs in this block\n",
-                                 gpe_enabled_count));
+               ACPI_INFO((AE_INFO,
+                          "Enabled %u GPEs in block %02X to %02X",
+                          gpe_enabled_count, (u32)gpe_block->block_base_number,
+                          (u32)(gpe_block->block_base_number +
+                                (gpe_block->gpe_count - 1))));
        }
 
        gpe_block->initialized = TRUE;
index da0add8..72b8f6b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -86,6 +86,9 @@ acpi_status acpi_ev_gpe_initialize(void)
 
        ACPI_FUNCTION_TRACE(ev_gpe_initialize);
 
+       ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
+                             "Initializing General Purpose Events (GPEs):\n"));
+
        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
index 228a0c3..b24dbb8 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c
new file mode 100644 (file)
index 0000000..d4f8311
--- /dev/null
@@ -0,0 +1,529 @@
+/******************************************************************************
+ *
+ * Module Name: evhandler - Support for Address Space handlers
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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 "acnamesp.h"
+#include "acinterp.h"
+
+#define _COMPONENT          ACPI_EVENTS
+ACPI_MODULE_NAME("evhandler")
+
+/* Local prototypes */
+static acpi_status
+acpi_ev_install_handler(acpi_handle obj_handle,
+                       u32 level, void *context, void **return_value);
+
+/* These are the address spaces that will get default handlers */
+
+u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
+       ACPI_ADR_SPACE_SYSTEM_MEMORY,
+       ACPI_ADR_SPACE_SYSTEM_IO,
+       ACPI_ADR_SPACE_PCI_CONFIG,
+       ACPI_ADR_SPACE_DATA_TABLE
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_region_handlers
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Installs the core subsystem default address space handlers.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ev_install_region_handlers(void)
+{
+       acpi_status status;
+       u32 i;
+
+       ACPI_FUNCTION_TRACE(ev_install_region_handlers);
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /*
+        * All address spaces (PCI Config, EC, SMBus) are scope dependent and
+        * registration must occur for a specific device.
+        *
+        * In the case of the system memory and IO address spaces there is
+        * currently no device associated with the address space. For these we
+        * use the root.
+        *
+        * We install the default PCI config space handler at the root so that
+        * this space is immediately available even though the we have not
+        * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
+        * specification which states that the PCI config space must be always
+        * available -- even though we are nowhere near ready to find the PCI root
+        * buses at this point.
+        *
+        * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
+        * has already been installed (via acpi_install_address_space_handler).
+        * Similar for AE_SAME_HANDLER.
+        */
+       for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
+               status = acpi_ev_install_space_handler(acpi_gbl_root_node,
+                                                      acpi_gbl_default_address_spaces
+                                                      [i],
+                                                      ACPI_DEFAULT_HANDLER,
+                                                      NULL, NULL);
+               switch (status) {
+               case AE_OK:
+               case AE_SAME_HANDLER:
+               case AE_ALREADY_EXISTS:
+
+                       /* These exceptions are all OK */
+
+                       status = AE_OK;
+                       break;
+
+               default:
+
+                       goto unlock_and_exit;
+               }
+       }
+
+      unlock_and_exit:
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+       return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_has_default_handler
+ *
+ * PARAMETERS:  node                - Namespace node for the device
+ *              space_id            - The address space ID
+ *
+ * RETURN:      TRUE if default handler is installed, FALSE otherwise
+ *
+ * DESCRIPTION: Check if the default handler is installed for the requested
+ *              space ID.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+                           acpi_adr_space_type space_id)
+{
+       union acpi_operand_object *obj_desc;
+       union acpi_operand_object *handler_obj;
+
+       /* Must have an existing internal object */
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (obj_desc) {
+               handler_obj = obj_desc->device.handler;
+
+               /* Walk the linked list of handlers for this object */
+
+               while (handler_obj) {
+                       if (handler_obj->address_space.space_id == space_id) {
+                               if (handler_obj->address_space.handler_flags &
+                                   ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+                                       return (TRUE);
+                               }
+                       }
+
+                       handler_obj = handler_obj->address_space.next;
+               }
+       }
+
+       return (FALSE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_handler
+ *
+ * PARAMETERS:  walk_namespace callback
+ *
+ * DESCRIPTION: This routine installs an address handler into objects that are
+ *              of type Region or Device.
+ *
+ *              If the Object is a Device, and the device has a handler of
+ *              the same type then the search is terminated in that branch.
+ *
+ *              This is because the existing handler is closer in proximity
+ *              to any more regions than the one we are trying to install.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_install_handler(acpi_handle obj_handle,
+                       u32 level, void *context, void **return_value)
+{
+       union acpi_operand_object *handler_obj;
+       union acpi_operand_object *next_handler_obj;
+       union acpi_operand_object *obj_desc;
+       struct acpi_namespace_node *node;
+       acpi_status status;
+
+       ACPI_FUNCTION_NAME(ev_install_handler);
+
+       handler_obj = (union acpi_operand_object *)context;
+
+       /* Parameter validation */
+
+       if (!handler_obj) {
+               return (AE_OK);
+       }
+
+       /* Convert and validate the device handle */
+
+       node = acpi_ns_validate_handle(obj_handle);
+       if (!node) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       /*
+        * We only care about regions and objects that are allowed to have
+        * address space handlers
+        */
+       if ((node->type != ACPI_TYPE_DEVICE) &&
+           (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
+               return (AE_OK);
+       }
+
+       /* Check for an existing internal object */
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (!obj_desc) {
+
+               /* No object, just exit */
+
+               return (AE_OK);
+       }
+
+       /* Devices are handled different than regions */
+
+       if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
+
+               /* Check if this Device already has a handler for this address space */
+
+               next_handler_obj = obj_desc->device.handler;
+               while (next_handler_obj) {
+
+                       /* Found a handler, is it for the same address space? */
+
+                       if (next_handler_obj->address_space.space_id ==
+                           handler_obj->address_space.space_id) {
+                               ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+                                                 "Found handler for region [%s] in device %p(%p) "
+                                                 "handler %p\n",
+                                                 acpi_ut_get_region_name
+                                                 (handler_obj->address_space.
+                                                  space_id), obj_desc,
+                                                 next_handler_obj,
+                                                 handler_obj));
+
+                               /*
+                                * Since the object we found it on was a device, then it
+                                * means that someone has already installed a handler for
+                                * the branch of the namespace from this device on. Just
+                                * bail out telling the walk routine to not traverse this
+                                * branch. This preserves the scoping rule for handlers.
+                                */
+                               return (AE_CTRL_DEPTH);
+                       }
+
+                       /* Walk the linked list of handlers attached to this device */
+
+                       next_handler_obj = next_handler_obj->address_space.next;
+               }
+
+               /*
+                * As long as the device didn't have a handler for this space we
+                * don't care about it. We just ignore it and proceed.
+                */
+               return (AE_OK);
+       }
+
+       /* Object is a Region */
+
+       if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
+
+               /* This region is for a different address space, just ignore it */
+
+               return (AE_OK);
+       }
+
+       /*
+        * Now we have a region and it is for the handler's address space type.
+        *
+        * First disconnect region for any previous handler (if any)
+        */
+       acpi_ev_detach_region(obj_desc, FALSE);
+
+       /* Connect the region to the new handler */
+
+       status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_space_handler
+ *
+ * PARAMETERS:  node            - Namespace node for the device
+ *              space_id        - The address space ID
+ *              handler         - Address of the handler
+ *              setup           - Address of the setup function
+ *              context         - Value passed to the handler on each access
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for all op_regions of a given space_id.
+ *              Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_space_handler(struct acpi_namespace_node * node,
+                             acpi_adr_space_type space_id,
+                             acpi_adr_space_handler handler,
+                             acpi_adr_space_setup setup, void *context)
+{
+       union acpi_operand_object *obj_desc;
+       union acpi_operand_object *handler_obj;
+       acpi_status status;
+       acpi_object_type type;
+       u8 flags = 0;
+
+       ACPI_FUNCTION_TRACE(ev_install_space_handler);
+
+       /*
+        * This registration is valid for only the types below and the root. This
+        * is where the default handlers get placed.
+        */
+       if ((node->type != ACPI_TYPE_DEVICE) &&
+           (node->type != ACPI_TYPE_PROCESSOR) &&
+           (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
+               status = AE_BAD_PARAMETER;
+               goto unlock_and_exit;
+       }
+
+       if (handler == ACPI_DEFAULT_HANDLER) {
+               flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
+
+               switch (space_id) {
+               case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+                       handler = acpi_ex_system_memory_space_handler;
+                       setup = acpi_ev_system_memory_region_setup;
+                       break;
+
+               case ACPI_ADR_SPACE_SYSTEM_IO:
+                       handler = acpi_ex_system_io_space_handler;
+                       setup = acpi_ev_io_space_region_setup;
+                       break;
+
+               case ACPI_ADR_SPACE_PCI_CONFIG:
+                       handler = acpi_ex_pci_config_space_handler;
+                       setup = acpi_ev_pci_config_region_setup;
+                       break;
+
+               case ACPI_ADR_SPACE_CMOS:
+                       handler = acpi_ex_cmos_space_handler;
+                       setup = acpi_ev_cmos_region_setup;
+                       break;
+
+               case ACPI_ADR_SPACE_PCI_BAR_TARGET:
+                       handler = acpi_ex_pci_bar_space_handler;
+                       setup = acpi_ev_pci_bar_region_setup;
+                       break;
+
+               case ACPI_ADR_SPACE_DATA_TABLE:
+                       handler = acpi_ex_data_table_space_handler;
+                       setup = NULL;
+                       break;
+
+               default:
+                       status = AE_BAD_PARAMETER;
+                       goto unlock_and_exit;
+               }
+       }
+
+       /* If the caller hasn't specified a setup routine, use the default */
+
+       if (!setup) {
+               setup = acpi_ev_default_region_setup;
+       }
+
+       /* Check for an existing internal object */
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (obj_desc) {
+               /*
+                * The attached device object already exists. Make sure the handler
+                * is not already installed.
+                */
+               handler_obj = obj_desc->device.handler;
+
+               /* Walk the handler list for this device */
+
+               while (handler_obj) {
+
+                       /* Same space_id indicates a handler already installed */
+
+                       if (handler_obj->address_space.space_id == space_id) {
+                               if (handler_obj->address_space.handler ==
+                                   handler) {
+                                       /*
+                                        * It is (relatively) OK to attempt to install the SAME
+                                        * handler twice. This can easily happen with the
+                                        * PCI_Config space.
+                                        */
+                                       status = AE_SAME_HANDLER;
+                                       goto unlock_and_exit;
+                               } else {
+                                       /* A handler is already installed */
+
+                                       status = AE_ALREADY_EXISTS;
+                               }
+                               goto unlock_and_exit;
+                       }
+
+                       /* Walk the linked list of handlers */
+
+                       handler_obj = handler_obj->address_space.next;
+               }
+       } else {
+               ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+                                 "Creating object on Device %p while installing handler\n",
+                                 node));
+
+               /* obj_desc does not exist, create one */
+
+               if (node->type == ACPI_TYPE_ANY) {
+                       type = ACPI_TYPE_DEVICE;
+               } else {
+                       type = node->type;
+               }
+
+               obj_desc = acpi_ut_create_internal_object(type);
+               if (!obj_desc) {
+                       status = AE_NO_MEMORY;
+                       goto unlock_and_exit;
+               }
+
+               /* Init new descriptor */
+
+               obj_desc->common.type = (u8)type;
+
+               /* Attach the new object to the Node */
+
+               status = acpi_ns_attach_object(node, obj_desc, type);
+
+               /* Remove local reference to the object */
+
+               acpi_ut_remove_reference(obj_desc);
+
+               if (ACPI_FAILURE(status)) {
+                       goto unlock_and_exit;
+               }
+       }
+
+       ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
+                         "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+                         acpi_ut_get_region_name(space_id), space_id,
+                         acpi_ut_get_node_name(node), node, obj_desc));
+
+       /*
+        * Install the handler
+        *
+        * At this point there is no existing handler. Just allocate the object
+        * for the handler and link it into the list.
+        */
+       handler_obj =
+           acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
+       if (!handler_obj) {
+               status = AE_NO_MEMORY;
+               goto unlock_and_exit;
+       }
+
+       /* Init handler obj */
+
+       handler_obj->address_space.space_id = (u8)space_id;
+       handler_obj->address_space.handler_flags = flags;
+       handler_obj->address_space.region_list = NULL;
+       handler_obj->address_space.node = node;
+       handler_obj->address_space.handler = handler;
+       handler_obj->address_space.context = context;
+       handler_obj->address_space.setup = setup;
+
+       /* Install at head of Device.address_space list */
+
+       handler_obj->address_space.next = obj_desc->device.handler;
+
+       /*
+        * The Device object is the first reference on the handler_obj.
+        * Each region that uses the handler adds a reference.
+        */
+       obj_desc->device.handler = handler_obj;
+
+       /*
+        * Walk the namespace finding all of the regions this
+        * handler will manage.
+        *
+        * Start at the device and search the branch toward
+        * the leaf nodes until either the leaf is encountered or
+        * a device is detected that has an address handler of the
+        * same type.
+        *
+        * In either case, back up and search down the remainder
+        * of the branch
+        */
+       status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+                                       ACPI_NS_WALK_UNLOCK,
+                                       acpi_ev_install_handler, NULL,
+                                       handler_obj, NULL);
+
+      unlock_and_exit:
+       return_ACPI_STATUS(status);
+}
index 51f5379..c986b23 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0cc6a16..6555e35 100644 (file)
@@ -1,11 +1,11 @@
 /******************************************************************************
  *
- * Module Name: evregion - ACPI address_space (op_region) handler dispatch
+ * Module Name: evregion - Operation Region support
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evregion")
 
+extern u8 acpi_gbl_default_address_spaces[];
+
 /* Local prototypes */
-static u8
-acpi_ev_has_default_handler(struct acpi_namespace_node *node,
-                           acpi_adr_space_type space_id);
 
 static void acpi_ev_orphan_ec_reg_method(void);
 
@@ -61,135 +60,6 @@ static acpi_status
 acpi_ev_reg_run(acpi_handle obj_handle,
                u32 level, void *context, void **return_value);
 
-static acpi_status
-acpi_ev_install_handler(acpi_handle obj_handle,
-                       u32 level, void *context, void **return_value);
-
-/* These are the address spaces that will get default handlers */
-
-#define ACPI_NUM_DEFAULT_SPACES     4
-
-static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
-       ACPI_ADR_SPACE_SYSTEM_MEMORY,
-       ACPI_ADR_SPACE_SYSTEM_IO,
-       ACPI_ADR_SPACE_PCI_CONFIG,
-       ACPI_ADR_SPACE_DATA_TABLE
-};
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_install_region_handlers
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Installs the core subsystem default address space handlers.
- *
- ******************************************************************************/
-
-acpi_status acpi_ev_install_region_handlers(void)
-{
-       acpi_status status;
-       u32 i;
-
-       ACPI_FUNCTION_TRACE(ev_install_region_handlers);
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
-
-       /*
-        * All address spaces (PCI Config, EC, SMBus) are scope dependent and
-        * registration must occur for a specific device.
-        *
-        * In the case of the system memory and IO address spaces there is
-        * currently no device associated with the address space. For these we
-        * use the root.
-        *
-        * We install the default PCI config space handler at the root so that
-        * this space is immediately available even though the we have not
-        * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
-        * specification which states that the PCI config space must be always
-        * available -- even though we are nowhere near ready to find the PCI root
-        * buses at this point.
-        *
-        * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
-        * has already been installed (via acpi_install_address_space_handler).
-        * Similar for AE_SAME_HANDLER.
-        */
-       for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
-               status = acpi_ev_install_space_handler(acpi_gbl_root_node,
-                                                      acpi_gbl_default_address_spaces
-                                                      [i],
-                                                      ACPI_DEFAULT_HANDLER,
-                                                      NULL, NULL);
-               switch (status) {
-               case AE_OK:
-               case AE_SAME_HANDLER:
-               case AE_ALREADY_EXISTS:
-
-                       /* These exceptions are all OK */
-
-                       status = AE_OK;
-                       break;
-
-               default:
-
-                       goto unlock_and_exit;
-               }
-       }
-
-      unlock_and_exit:
-       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-       return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_has_default_handler
- *
- * PARAMETERS:  node                - Namespace node for the device
- *              space_id            - The address space ID
- *
- * RETURN:      TRUE if default handler is installed, FALSE otherwise
- *
- * DESCRIPTION: Check if the default handler is installed for the requested
- *              space ID.
- *
- ******************************************************************************/
-
-static u8
-acpi_ev_has_default_handler(struct acpi_namespace_node *node,
-                           acpi_adr_space_type space_id)
-{
-       union acpi_operand_object *obj_desc;
-       union acpi_operand_object *handler_obj;
-
-       /* Must have an existing internal object */
-
-       obj_desc = acpi_ns_get_attached_object(node);
-       if (obj_desc) {
-               handler_obj = obj_desc->device.handler;
-
-               /* Walk the linked list of handlers for this object */
-
-               while (handler_obj) {
-                       if (handler_obj->address_space.space_id == space_id) {
-                               if (handler_obj->address_space.handler_flags &
-                                   ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
-                                       return (TRUE);
-                               }
-                       }
-
-                       handler_obj = handler_obj->address_space.next;
-               }
-       }
-
-       return (FALSE);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_initialize_op_regions
@@ -241,91 +111,6 @@ acpi_status acpi_ev_initialize_op_regions(void)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_execute_reg_method
- *
- * PARAMETERS:  region_obj          - Region object
- *              function            - Passed to _REG: On (1) or Off (0)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Execute _REG method for a region
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
-{
-       struct acpi_evaluate_info *info;
-       union acpi_operand_object *args[3];
-       union acpi_operand_object *region_obj2;
-       acpi_status status;
-
-       ACPI_FUNCTION_TRACE(ev_execute_reg_method);
-
-       region_obj2 = acpi_ns_get_secondary_object(region_obj);
-       if (!region_obj2) {
-               return_ACPI_STATUS(AE_NOT_EXIST);
-       }
-
-       if (region_obj2->extra.method_REG == NULL) {
-               return_ACPI_STATUS(AE_OK);
-       }
-
-       /* Allocate and initialize the evaluation information block */
-
-       info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
-       if (!info) {
-               return_ACPI_STATUS(AE_NO_MEMORY);
-       }
-
-       info->prefix_node = region_obj2->extra.method_REG;
-       info->pathname = NULL;
-       info->parameters = args;
-       info->flags = ACPI_IGNORE_RETURN_VALUE;
-
-       /*
-        * The _REG method has two arguments:
-        *
-        * arg0 - Integer:
-        *  Operation region space ID Same value as region_obj->Region.space_id
-        *
-        * arg1 - Integer:
-        *  connection status 1 for connecting the handler, 0 for disconnecting
-        *  the handler (Passed as a parameter)
-        */
-       args[0] =
-           acpi_ut_create_integer_object((u64) region_obj->region.space_id);
-       if (!args[0]) {
-               status = AE_NO_MEMORY;
-               goto cleanup1;
-       }
-
-       args[1] = acpi_ut_create_integer_object((u64) function);
-       if (!args[1]) {
-               status = AE_NO_MEMORY;
-               goto cleanup2;
-       }
-
-       args[2] = NULL;         /* Terminate list */
-
-       /* Execute the method, no return value */
-
-       ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
-                       (ACPI_TYPE_METHOD, info->prefix_node, NULL));
-
-       status = acpi_ns_evaluate(info);
-       acpi_ut_remove_reference(args[1]);
-
-      cleanup2:
-       acpi_ut_remove_reference(args[0]);
-
-      cleanup1:
-       ACPI_FREE(info);
-       return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ev_address_space_dispatch
  *
  * PARAMETERS:  region_obj          - Internal region object
@@ -709,351 +494,86 @@ acpi_ev_attach_region(union acpi_operand_object *handler_obj,
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_install_handler
- *
- * PARAMETERS:  walk_namespace callback
- *
- * DESCRIPTION: This routine installs an address handler into objects that are
- *              of type Region or Device.
- *
- *              If the Object is a Device, and the device has a handler of
- *              the same type then the search is terminated in that branch.
- *
- *              This is because the existing handler is closer in proximity
- *              to any more regions than the one we are trying to install.
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ev_install_handler(acpi_handle obj_handle,
-                       u32 level, void *context, void **return_value)
-{
-       union acpi_operand_object *handler_obj;
-       union acpi_operand_object *next_handler_obj;
-       union acpi_operand_object *obj_desc;
-       struct acpi_namespace_node *node;
-       acpi_status status;
-
-       ACPI_FUNCTION_NAME(ev_install_handler);
-
-       handler_obj = (union acpi_operand_object *)context;
-
-       /* Parameter validation */
-
-       if (!handler_obj) {
-               return (AE_OK);
-       }
-
-       /* Convert and validate the device handle */
-
-       node = acpi_ns_validate_handle(obj_handle);
-       if (!node) {
-               return (AE_BAD_PARAMETER);
-       }
-
-       /*
-        * We only care about regions and objects that are allowed to have
-        * address space handlers
-        */
-       if ((node->type != ACPI_TYPE_DEVICE) &&
-           (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
-               return (AE_OK);
-       }
-
-       /* Check for an existing internal object */
-
-       obj_desc = acpi_ns_get_attached_object(node);
-       if (!obj_desc) {
-
-               /* No object, just exit */
-
-               return (AE_OK);
-       }
-
-       /* Devices are handled different than regions */
-
-       if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
-
-               /* Check if this Device already has a handler for this address space */
-
-               next_handler_obj = obj_desc->device.handler;
-               while (next_handler_obj) {
-
-                       /* Found a handler, is it for the same address space? */
-
-                       if (next_handler_obj->address_space.space_id ==
-                           handler_obj->address_space.space_id) {
-                               ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-                                                 "Found handler for region [%s] in device %p(%p) "
-                                                 "handler %p\n",
-                                                 acpi_ut_get_region_name
-                                                 (handler_obj->address_space.
-                                                  space_id), obj_desc,
-                                                 next_handler_obj,
-                                                 handler_obj));
-
-                               /*
-                                * Since the object we found it on was a device, then it
-                                * means that someone has already installed a handler for
-                                * the branch of the namespace from this device on. Just
-                                * bail out telling the walk routine to not traverse this
-                                * branch. This preserves the scoping rule for handlers.
-                                */
-                               return (AE_CTRL_DEPTH);
-                       }
-
-                       /* Walk the linked list of handlers attached to this device */
-
-                       next_handler_obj = next_handler_obj->address_space.next;
-               }
-
-               /*
-                * As long as the device didn't have a handler for this space we
-                * don't care about it. We just ignore it and proceed.
-                */
-               return (AE_OK);
-       }
-
-       /* Object is a Region */
-
-       if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
-
-               /* This region is for a different address space, just ignore it */
-
-               return (AE_OK);
-       }
-
-       /*
-        * Now we have a region and it is for the handler's address space type.
-        *
-        * First disconnect region for any previous handler (if any)
-        */
-       acpi_ev_detach_region(obj_desc, FALSE);
-
-       /* Connect the region to the new handler */
-
-       status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
-       return (status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_install_space_handler
+ * FUNCTION:    acpi_ev_execute_reg_method
  *
- * PARAMETERS:  node            - Namespace node for the device
- *              space_id        - The address space ID
- *              handler         - Address of the handler
- *              setup           - Address of the setup function
- *              context         - Value passed to the handler on each access
+ * PARAMETERS:  region_obj          - Region object
+ *              function            - Passed to _REG: On (1) or Off (0)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Install a handler for all op_regions of a given space_id.
- *              Assumes namespace is locked
+ * DESCRIPTION: Execute _REG method for a region
  *
  ******************************************************************************/
 
 acpi_status
-acpi_ev_install_space_handler(struct acpi_namespace_node * node,
-                             acpi_adr_space_type space_id,
-                             acpi_adr_space_handler handler,
-                             acpi_adr_space_setup setup, void *context)
+acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
 {
-       union acpi_operand_object *obj_desc;
-       union acpi_operand_object *handler_obj;
+       struct acpi_evaluate_info *info;
+       union acpi_operand_object *args[3];
+       union acpi_operand_object *region_obj2;
        acpi_status status;
-       acpi_object_type type;
-       u8 flags = 0;
 
-       ACPI_FUNCTION_TRACE(ev_install_space_handler);
-
-       /*
-        * This registration is valid for only the types below and the root. This
-        * is where the default handlers get placed.
-        */
-       if ((node->type != ACPI_TYPE_DEVICE) &&
-           (node->type != ACPI_TYPE_PROCESSOR) &&
-           (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
+       ACPI_FUNCTION_TRACE(ev_execute_reg_method);
 
-       if (handler == ACPI_DEFAULT_HANDLER) {
-               flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
-
-               switch (space_id) {
-               case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-                       handler = acpi_ex_system_memory_space_handler;
-                       setup = acpi_ev_system_memory_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_SYSTEM_IO:
-                       handler = acpi_ex_system_io_space_handler;
-                       setup = acpi_ev_io_space_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_PCI_CONFIG:
-                       handler = acpi_ex_pci_config_space_handler;
-                       setup = acpi_ev_pci_config_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_CMOS:
-                       handler = acpi_ex_cmos_space_handler;
-                       setup = acpi_ev_cmos_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_PCI_BAR_TARGET:
-                       handler = acpi_ex_pci_bar_space_handler;
-                       setup = acpi_ev_pci_bar_region_setup;
-                       break;
-
-               case ACPI_ADR_SPACE_DATA_TABLE:
-                       handler = acpi_ex_data_table_space_handler;
-                       setup = NULL;
-                       break;
-
-               default:
-                       status = AE_BAD_PARAMETER;
-                       goto unlock_and_exit;
-               }
+       region_obj2 = acpi_ns_get_secondary_object(region_obj);
+       if (!region_obj2) {
+               return_ACPI_STATUS(AE_NOT_EXIST);
        }
 
-       /* If the caller hasn't specified a setup routine, use the default */
-
-       if (!setup) {
-               setup = acpi_ev_default_region_setup;
+       if (region_obj2->extra.method_REG == NULL) {
+               return_ACPI_STATUS(AE_OK);
        }
 
-       /* Check for an existing internal object */
-
-       obj_desc = acpi_ns_get_attached_object(node);
-       if (obj_desc) {
-               /*
-                * The attached device object already exists. Make sure the handler
-                * is not already installed.
-                */
-               handler_obj = obj_desc->device.handler;
-
-               /* Walk the handler list for this device */
-
-               while (handler_obj) {
-
-                       /* Same space_id indicates a handler already installed */
-
-                       if (handler_obj->address_space.space_id == space_id) {
-                               if (handler_obj->address_space.handler ==
-                                   handler) {
-                                       /*
-                                        * It is (relatively) OK to attempt to install the SAME
-                                        * handler twice. This can easily happen with the
-                                        * PCI_Config space.
-                                        */
-                                       status = AE_SAME_HANDLER;
-                                       goto unlock_and_exit;
-                               } else {
-                                       /* A handler is already installed */
-
-                                       status = AE_ALREADY_EXISTS;
-                               }
-                               goto unlock_and_exit;
-                       }
-
-                       /* Walk the linked list of handlers */
-
-                       handler_obj = handler_obj->address_space.next;
-               }
-       } else {
-               ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-                                 "Creating object on Device %p while installing handler\n",
-                                 node));
-
-               /* obj_desc does not exist, create one */
-
-               if (node->type == ACPI_TYPE_ANY) {
-                       type = ACPI_TYPE_DEVICE;
-               } else {
-                       type = node->type;
-               }
-
-               obj_desc = acpi_ut_create_internal_object(type);
-               if (!obj_desc) {
-                       status = AE_NO_MEMORY;
-                       goto unlock_and_exit;
-               }
-
-               /* Init new descriptor */
-
-               obj_desc->common.type = (u8) type;
-
-               /* Attach the new object to the Node */
-
-               status = acpi_ns_attach_object(node, obj_desc, type);
-
-               /* Remove local reference to the object */
-
-               acpi_ut_remove_reference(obj_desc);
+       /* Allocate and initialize the evaluation information block */
 
-               if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
-               }
+       info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+       if (!info) {
+               return_ACPI_STATUS(AE_NO_MEMORY);
        }
 
-       ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-                         "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
-                         acpi_ut_get_region_name(space_id), space_id,
-                         acpi_ut_get_node_name(node), node, obj_desc));
+       info->prefix_node = region_obj2->extra.method_REG;
+       info->pathname = NULL;
+       info->parameters = args;
+       info->flags = ACPI_IGNORE_RETURN_VALUE;
 
        /*
-        * Install the handler
+        * The _REG method has two arguments:
+        *
+        * arg0 - Integer:
+        *  Operation region space ID Same value as region_obj->Region.space_id
         *
-        * At this point there is no existing handler. Just allocate the object
-        * for the handler and link it into the list.
+        * arg1 - Integer:
+        *  connection status 1 for connecting the handler, 0 for disconnecting
+        *  the handler (Passed as a parameter)
         */
-       handler_obj =
-           acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
-       if (!handler_obj) {
+       args[0] =
+           acpi_ut_create_integer_object((u64)region_obj->region.space_id);
+       if (!args[0]) {
                status = AE_NO_MEMORY;
-               goto unlock_and_exit;
+               goto cleanup1;
        }
 
-       /* Init handler obj */
+       args[1] = acpi_ut_create_integer_object((u64)function);
+       if (!args[1]) {
+               status = AE_NO_MEMORY;
+               goto cleanup2;
+       }
 
-       handler_obj->address_space.space_id = (u8) space_id;
-       handler_obj->address_space.handler_flags = flags;
-       handler_obj->address_space.region_list = NULL;
-       handler_obj->address_space.node = node;
-       handler_obj->address_space.handler = handler;
-       handler_obj->address_space.context = context;
-       handler_obj->address_space.setup = setup;
+       args[2] = NULL;         /* Terminate list */
 
-       /* Install at head of Device.address_space list */
+       /* Execute the method, no return value */
 
-       handler_obj->address_space.next = obj_desc->device.handler;
+       ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
+                       (ACPI_TYPE_METHOD, info->prefix_node, NULL));
 
-       /*
-        * The Device object is the first reference on the handler_obj.
-        * Each region that uses the handler adds a reference.
-        */
-       obj_desc->device.handler = handler_obj;
+       status = acpi_ns_evaluate(info);
+       acpi_ut_remove_reference(args[1]);
 
-       /*
-        * Walk the namespace finding all of the regions this
-        * handler will manage.
-        *
-        * Start at the device and search the branch toward
-        * the leaf nodes until either the leaf is encountered or
-        * a device is detected that has an address handler of the
-        * same type.
-        *
-        * In either case, back up and search down the remainder
-        * of the branch
-        */
-       status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
-                                       ACPI_NS_WALK_UNLOCK,
-                                       acpi_ev_install_handler, NULL,
-                                       handler_obj, NULL);
+      cleanup2:
+       acpi_ut_remove_reference(args[0]);
 
-      unlock_and_exit:
+      cleanup1:
+       ACPI_FREE(info);
        return_ACPI_STATUS(status);
 }
 
index 1474241..3bb6167 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f9661e2..f4b43be 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -89,7 +89,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
         */
        interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
 
-       return_UINT32(interrupt_handled);
+       return_VALUE(interrupt_handled);
 }
 
 /*******************************************************************************
@@ -120,7 +120,7 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context)
 
        interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
 
-       return_UINT32(interrupt_handled);
+       return_VALUE(interrupt_handled);
 }
 
 /******************************************************************************
index ae668f3..ddffd68 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -56,13 +56,13 @@ ACPI_MODULE_NAME("evxface")
  *
  * FUNCTION:    acpi_install_notify_handler
  *
- * PARAMETERS:  Device          - The device for which notifies will be handled
+ * PARAMETERS:  device          - The device for which notifies will be handled
  *              handler_type    - The type of handler:
  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
  *                                  ACPI_ALL_NOTIFY:    Both System and Device
- *              Handler         - Address of the handler
- *              Context         - Value passed to the handler on each GPE
+ *              handler         - Address of the handler
+ *              context         - Value passed to the handler on each GPE
  *
  * RETURN:      Status
  *
@@ -217,12 +217,12 @@ ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
  *
  * FUNCTION:    acpi_remove_notify_handler
  *
- * PARAMETERS:  Device          - The device for which the handler is installed
+ * PARAMETERS:  device          - The device for which the handler is installed
  *              handler_type    - The type of handler:
  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
  *                                  ACPI_ALL_NOTIFY:    Both System and Device
- *              Handler         - Address of the handler
+ *              handler         - Address of the handler
  *
  * RETURN:      Status
  *
@@ -249,7 +249,8 @@ acpi_remove_notify_handler(acpi_handle device,
            (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
-       /* Make sure all deferred tasks are completed */
+
+       /* Make sure all deferred notify tasks are completed */
 
        acpi_os_wait_events_complete();
 
@@ -596,7 +597,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
                return_ACPI_STATUS(status);
        }
 
-       /* Allocate memory for the handler object */
+       /* Allocate and init handler object (before lock) */
 
        handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
        if (!handler) {
@@ -622,16 +623,15 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
                goto free_and_exit;
        }
 
-       /* Allocate and init handler object */
-
        handler->address = address;
        handler->context = context;
        handler->method_node = gpe_event_info->dispatch.method_node;
-       handler->original_flags = gpe_event_info->flags &
-                       (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
+       handler->original_flags = (u8)(gpe_event_info->flags &
+                                      (ACPI_GPE_XRUPT_TYPE_MASK |
+                                       ACPI_GPE_DISPATCH_MASK));
 
        /*
-        * If the GPE is associated with a method, it might have been enabled
+        * If the GPE is associated with a method, it may have been enabled
         * automatically during initialization, in which case it has to be
         * disabled now to avoid spurious execution of the handler.
         */
@@ -646,7 +646,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
 
        gpe_event_info->dispatch.handler = handler;
 
-       /* Setup up dispatch flags to indicate handler (vs. method) */
+       /* Setup up dispatch flags to indicate handler (vs. method/notify) */
 
        gpe_event_info->flags &=
            ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
@@ -697,7 +697,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
-       /* Make sure all deferred tasks are completed */
+       /* Make sure all deferred GPE tasks are completed */
 
        acpi_os_wait_events_complete();
 
@@ -747,10 +747,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
         * enabled, it should be enabled at this point to restore the
         * post-initialization configuration.
         */
-
-       if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
-           && handler->originally_enabled)
+       if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) &&
+           handler->originally_enabled) {
                (void)acpi_ev_add_gpe_reference(gpe_event_info);
+       }
 
        /* Now we can free the handler object */
 
index 35520c6..d6e4e42 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,7 +61,6 @@ ACPI_MODULE_NAME("evxfevnt")
  * DESCRIPTION: Transfers the system into ACPI mode.
  *
  ******************************************************************************/
-
 acpi_status acpi_enable(void)
 {
        acpi_status status;
@@ -210,8 +209,8 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
  *
  * FUNCTION:    acpi_disable_event
  *
- * PARAMETERS:  Event           - The fixed eventto be enabled
- *              Flags           - Reserved
+ * PARAMETERS:  event           - The fixed event to be disabled
+ *              flags           - Reserved
  *
  * RETURN:      Status
  *
index 3f30e75..aff4cc2 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
 ACPI_MODULE_NAME("evxfgpe")
 
 #if (!ACPI_REDUCED_HARDWARE)   /* Entire module */
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_update_all_gpes
  *
@@ -172,6 +172,7 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
        return_ACPI_STATUS(status);
 }
+
 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
 
 
@@ -225,7 +226,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
                    ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
        }
 
-       /* Validate WakeDevice is of type Device */
+       /* Validate wake_device is of type Device */
 
        if (device_node->type != ACPI_TYPE_DEVICE) {
                return_ACPI_STATUS (AE_BAD_PARAMETER);
@@ -432,8 +433,8 @@ ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
  *
  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  *              gpe_number      - GPE level within the GPE block
- *              event_status    - Where the current status of the event will
- *                                be returned
+ *              event_status        - Where the current status of the event
+ *                                    will be returned
  *
  * RETURN:      Status
  *
index 96b412d..96c9e5f 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 16219bd..d93b70b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,7 @@
 #include "actables.h"
 #include "acdispat.h"
 #include "acevents.h"
+#include "amlcode.h"
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exconfig")
@@ -120,8 +121,11 @@ acpi_ex_add_table(u32 table_index,
        acpi_ns_exec_module_code_list();
        acpi_ex_enter_interpreter();
 
-       /* Update GPEs for any new _Lxx/_Exx methods. Ignore errors */
-
+       /*
+        * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
+        * responsible for discovering any new wake GPEs by running _PRW methods
+        * that may have been loaded by this table.
+        */
        status = acpi_tb_get_owner_id(table_index, &owner_id);
        if (ACPI_SUCCESS(status)) {
                acpi_ev_update_gpes(owner_id);
@@ -158,12 +162,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 
        ACPI_FUNCTION_TRACE(ex_load_table_op);
 
-       /* Validate lengths for the signature_string, OEMIDString, OEMtable_iD */
+       /* Validate lengths for the Signature, oem_id, and oem_table_id strings */
 
        if ((operand[0]->string.length > ACPI_NAME_SIZE) ||
            (operand[1]->string.length > ACPI_OEM_ID_SIZE) ||
            (operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) {
-               return_ACPI_STATUS(AE_BAD_PARAMETER);
+               return_ACPI_STATUS(AE_AML_STRING_LIMIT);
        }
 
        /* Find the ACPI table in the RSDT/XSDT */
@@ -210,8 +214,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
        /* parameter_path (optional parameter) */
 
        if (operand[4]->string.length > 0) {
-               if ((operand[4]->string.pointer[0] != '\\') &&
-                   (operand[4]->string.pointer[0] != '^')) {
+               if ((operand[4]->string.pointer[0] != AML_ROOT_PREFIX) &&
+                   (operand[4]->string.pointer[0] != AML_PARENT_PREFIX)) {
                        /*
                         * Path is not absolute, so it will be relative to the node
                         * referenced by the root_path_string (or the NS root if omitted)
@@ -301,7 +305,7 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
                    acpi_ev_address_space_dispatch(obj_desc, NULL, ACPI_READ,
                                                   region_offset, 8, &value);
                if (ACPI_FAILURE(status)) {
-                       return status;
+                       return (status);
                }
 
                *buffer = (u8)value;
@@ -309,7 +313,7 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
                region_offset++;
        }
 
-       return AE_OK;
+       return (AE_OK);
 }
 
 /*******************************************************************************
index 4492a4e..d2b9613 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -176,7 +176,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
 
        /* Save the Result */
 
-       acpi_ex_truncate_for32bit_table(return_desc);
+       (void)acpi_ex_truncate_for32bit_table(return_desc);
        *result_desc = return_desc;
        return_ACPI_STATUS(AE_OK);
 }
index 66554bc..26a13f6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d7c9f51..7eb853c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 858b43a..e5a3c24 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -464,9 +464,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
 
        ACPI_FUNCTION_NAME(ex_dump_operand)
 
-           if (!
-               ((ACPI_LV_EXEC & acpi_dbg_level)
-                 && (_COMPONENT & acpi_dbg_layer))) {
+           /* Check if debug output enabled */
+           if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_EXEC, _COMPONENT)) {
                return;
        }
 
@@ -811,9 +810,10 @@ void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags)
        ACPI_FUNCTION_ENTRY();
 
        if (!flags) {
-               if (!
-                   ((ACPI_LV_OBJECTS & acpi_dbg_level)
-                     && (_COMPONENT & acpi_dbg_layer))) {
+
+               /* Check if debug output enabled */
+
+               if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_OBJECTS, _COMPONENT)) {
                        return;
                }
        }
@@ -999,9 +999,10 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags)
        }
 
        if (!flags) {
-               if (!
-                   ((ACPI_LV_OBJECTS & acpi_dbg_level)
-                     && (_COMPONENT & acpi_dbg_layer))) {
+
+               /* Check if debug output enabled */
+
+               if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_OBJECTS, _COMPONENT)) {
                        return_VOID;
                }
        }
index ebc55fb..7d4bae7 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index aa2ccfb..ec7f569 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -329,7 +329,6 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
 static u8
 acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value)
 {
-       ACPI_FUNCTION_NAME(ex_register_overflow);
 
        if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
                /*
index 8405870..72a2a13 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index d1f449d..7be0205 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -377,7 +377,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
        }
 
-       /* Must have a valid thread. */
+       /* Must have a valid thread ID */
+
        if (!walk_state->thread) {
                ACPI_ERROR((AE_INFO,
                            "Cannot release Mutex [%4.4s], null thread info",
index 2ff578a..14689de 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index bbf01e9..b60c877 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -948,13 +948,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
                                         */
                                        return_desc =
                                            acpi_ut_create_integer_object((u64)
-                                                                         temp_desc->
-                                                                         buffer.
-                                                                         pointer
-                                                                         [operand
-                                                                          [0]->
-                                                                          reference.
-                                                                          value]);
+                                                                         temp_desc->buffer.pointer[operand[0]->reference.value]);
                                        if (!return_desc) {
                                                status = AE_NO_MEMORY;
                                                goto cleanup;
index ee5634a..e491e46 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 2c89b46..2d7491f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 3e08695..b76b970 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ba9db4d..d6eab81 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -276,7 +276,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
                /* Invalid field access type */
 
                ACPI_ERROR((AE_INFO, "Unknown field access type 0x%X", access));
-               return_UINT32(0);
+               return_VALUE(0);
        }
 
        if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
@@ -289,7 +289,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
        }
 
        *return_byte_alignment = byte_alignment;
-       return_UINT32(bit_length);
+       return_VALUE(bit_length);
 }
 
 /*******************************************************************************
index 1db2c0b..182abaf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -142,9 +142,9 @@ acpi_ex_system_memory_space_handler(u32 function,
                }
 
                /*
-                * Attempt to map from the requested address to the end of the region.
-                * However, we will never map more than one page, nor will we cross
-                * a page boundary.
+                * October 2009: Attempt to map from the requested address to the
+                * end of the region. However, we will never map more than one
+                * page, nor will we cross a page boundary.
                 */
                map_length = (acpi_size)
                    ((mem_info->address + mem_info->length) - address);
@@ -154,12 +154,15 @@ acpi_ex_system_memory_space_handler(u32 function,
                 * a page boundary, just map up to the page boundary, do not cross.
                 * On some systems, crossing a page boundary while mapping regions
                 * can cause warnings if the pages have different attributes
-                * due to resource management
+                * due to resource management.
+                *
+                * This has the added benefit of constraining a single mapping to
+                * one page, which is similar to the original code that used a 4k
+                * maximum window.
                 */
                page_boundary_map_length =
                    ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address;
-
-               if (!page_boundary_map_length) {
+               if (page_boundary_map_length == 0) {
                        page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
                }
 
@@ -236,19 +239,19 @@ acpi_ex_system_memory_space_handler(u32 function,
 
                switch (bit_width) {
                case 8:
-                       ACPI_SET8(logical_addr_ptr) = (u8) * value;
+                       ACPI_SET8(logical_addr_ptr, *value);
                        break;
 
                case 16:
-                       ACPI_SET16(logical_addr_ptr) = (u16) * value;
+                       ACPI_SET16(logical_addr_ptr, *value);
                        break;
 
                case 32:
-                       ACPI_SET32(logical_addr_ptr) = (u32) * value;
+                       ACPI_SET32(logical_addr_ptr, *value);
                        break;
 
                case 64:
-                       ACPI_SET64(logical_addr_ptr) = (u64) * value;
+                       ACPI_SET64(logical_addr_ptr, *value);
                        break;
 
                default:
index 6239956..8565b6b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index cc176b2..e4f9dfb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b9ebff2..9fb9f5e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 90431f1..93c6049 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -487,14 +487,33 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
        default:
 
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
+                                 "Storing [%s] (%p) directly into node [%s] (%p)"
+                                 " with no implicit conversion\n",
                                  acpi_ut_get_object_type_name(source_desc),
-                                 source_desc, node));
+                                 source_desc,
+                                 acpi_ut_get_object_type_name(target_desc),
+                                 node));
 
-               /* No conversions for all other types. Just attach the source object */
+               /*
+                * No conversions for all other types. Directly store a copy of
+                * the source object. NOTE: This is a departure from the ACPI
+                * spec, which states "If conversion is impossible, abort the
+                * running control method".
+                *
+                * This code implements "If conversion is impossible, treat the
+                * Store operation as a CopyObject".
+                */
+               status =
+                   acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc,
+                                                   walk_state);
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
 
-               status = acpi_ns_attach_object(node, source_desc,
-                                              source_desc->common.type);
+               status =
+                   acpi_ns_attach_object(node, new_desc,
+                                         new_desc->common.type);
+               acpi_ut_remove_reference(new_desc);
                break;
        }
 
index 87153bb..1cefe77 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -253,7 +253,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
 
                /* Truncate value if we are executing from a 32-bit ACPI table */
 
-               acpi_ex_truncate_for32bit_table(dest_desc);
+               (void)acpi_ex_truncate_for32bit_table(dest_desc);
                break;
 
        case ACPI_TYPE_STRING:
index b5f339c..26e3710 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index c8a0ad5..6578dee 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 264d22d..b205cbb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -202,35 +202,39 @@ void acpi_ex_relinquish_interpreter(void)
  *
  * PARAMETERS:  obj_desc        - Object to be truncated
  *
- * RETURN:      none
+ * RETURN:      TRUE if a truncation was performed, FALSE otherwise.
  *
  * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
  *              32-bit, as determined by the revision of the DSDT.
  *
  ******************************************************************************/
 
-void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
+u8 acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
 {
 
        ACPI_FUNCTION_ENTRY();
 
        /*
         * Object must be a valid number and we must be executing
-        * a control method. NS node could be there for AML_INT_NAMEPATH_OP.
+        * a control method. Object could be NS node for AML_INT_NAMEPATH_OP.
         */
        if ((!obj_desc) ||
            (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
            (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
-               return;
+               return (FALSE);
        }
 
-       if (acpi_gbl_integer_byte_width == 4) {
+       if ((acpi_gbl_integer_byte_width == 4) &&
+           (obj_desc->integer.value > (u64)ACPI_UINT32_MAX)) {
                /*
-                * We are running a method that exists in a 32-bit ACPI table.
+                * We are executing in a 32-bit ACPI table.
                 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
                 */
-               obj_desc->integer.value &= (u64) ACPI_UINT32_MAX;
+               obj_desc->integer.value &= (u64)ACPI_UINT32_MAX;
+               return (TRUE);
        }
+
+       return (FALSE);
 }
 
 /*******************************************************************************
@@ -336,7 +340,7 @@ static u32 acpi_ex_digits_needed(u64 value, u32 base)
        /* u64 is unsigned, so we don't worry about a '-' prefix */
 
        if (value == 0) {
-               return_UINT32(1);
+               return_VALUE(1);
        }
 
        current_value = value;
@@ -350,7 +354,7 @@ static u32 acpi_ex_digits_needed(u64 value, u32 base)
                num_digits++;
        }
 
-       return_UINT32(num_digits);
+       return_VALUE(num_digits);
 }
 
 /*******************************************************************************
index 90a9aea..deb3f61 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -108,8 +108,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
                 * enable bits to default
                 */
                status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
-                                           (u32) acpi_gbl_FADT.acpi_disable,
-                                           8);
+                                           (u32)acpi_gbl_FADT.acpi_disable, 8);
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Attempting to enable Legacy (non-ACPI) mode\n"));
                break;
@@ -152,18 +151,18 @@ u32 acpi_hw_get_mode(void)
         * system does not support mode transition.
         */
        if (!acpi_gbl_FADT.smi_command) {
-               return_UINT32(ACPI_SYS_MODE_ACPI);
+               return_VALUE(ACPI_SYS_MODE_ACPI);
        }
 
        status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
        if (ACPI_FAILURE(status)) {
-               return_UINT32(ACPI_SYS_MODE_LEGACY);
+               return_VALUE(ACPI_SYS_MODE_LEGACY);
        }
 
        if (value) {
-               return_UINT32(ACPI_SYS_MODE_ACPI);
+               return_VALUE(ACPI_SYS_MODE_ACPI);
        } else {
-               return_UINT32(ACPI_SYS_MODE_LEGACY);
+               return_VALUE(ACPI_SYS_MODE_LEGACY);
        }
 }
 
index 94996f9..5e5f762 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -200,7 +200,6 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state)
  * FUNCTION:    acpi_hw_extended_wake
  *
  * PARAMETERS:  sleep_state         - Which sleep state we just exited
- *              flags               - Reserved, set to zero
  *
  * RETURN:      Status
  *
index 6456004..20d02e9 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,8 +69,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
 
 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
 {
-       return (u32)1 << (gpe_event_info->gpe_number -
-                gpe_event_info->register_info->base_gpe_number);
+
+       return ((u32)1 <<
+               (gpe_event_info->gpe_number -
+                gpe_event_info->register_info->base_gpe_number));
 }
 
 /******************************************************************************
@@ -133,7 +135,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
                break;
 
        default:
-               ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action));
+               ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action));
                return (AE_BAD_PARAMETER);
        }
 
index 65bc345..0889a62 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f4e5750..083d655 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,6 @@
 
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "acnamesp.h"
 #include "acevents.h"
 
 #define _COMPONENT          ACPI_HARDWARE
@@ -364,8 +363,7 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
  * DESCRIPTION: Read from the specified ACPI register
  *
  ******************************************************************************/
-acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value)
+acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value)
 {
        u32 value = 0;
        acpi_status status;
@@ -485,7 +483,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
                                                &acpi_gbl_xpm1b_status);
                break;
 
-       case ACPI_REGISTER_PM1_ENABLE:  /* PM1 A/B: 16-bit access */
+       case ACPI_REGISTER_PM1_ENABLE:  /* PM1 A/B: 16-bit access each */
 
                status = acpi_hw_write_multiple(value,
                                                &acpi_gbl_xpm1a_enable,
index 3fddde0..e3828cc 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
 #include <acpi/acpi.h>
 #include <linux/acpi.h>
 #include "accommon.h"
-#include <linux/module.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwsleep")
@@ -178,7 +177,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
                 * to still read the right value. Ideally, this block would go
                 * away entirely.
                 */
-               acpi_os_stall(10000000);
+               acpi_os_stall(10 * ACPI_USEC_PER_SEC);
 
                status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
                                                sleep_enable_reg_info->
@@ -323,7 +322,8 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state)
         * and use it to determine whether the system is rebooting or
         * resuming. Clear WAK_STS for compatibility.
         */
-       acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
+       (void)acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS,
+                                     ACPI_CLEAR_STATUS);
        acpi_gbl_system_awake_and_running = TRUE;
 
        /* Enable power button */
index bfdce22..0c1a8bb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -176,10 +176,11 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
        /*
         * Compute Duration (Requires a 64-bit multiply and divide):
         *
-        * time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY;
+        * time_elapsed (microseconds) =
+        *  (delta_ticks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;
         */
-       status = acpi_ut_short_divide(((u64) delta_ticks) * 1000000,
-                                     PM_TIMER_FREQUENCY, &quotient, NULL);
+       status = acpi_ut_short_divide(((u64)delta_ticks) * ACPI_USEC_PER_SEC,
+                                     ACPI_PM_TIMER_FREQUENCY, &quotient, NULL);
 
        *time_elapsed = (u32) quotient;
        return_ACPI_STATUS(status);
index b6aae58..eab70d5 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -135,7 +135,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
        if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) {
                ACPI_ERROR((AE_INFO,
                            "Bad BitWidth parameter: %8.8X", bit_width));
-               return AE_BAD_PARAMETER;
+               return (AE_BAD_PARAMETER);
        }
 
        port_info = acpi_protected_ports;
@@ -234,11 +234,11 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
        status = acpi_hw_validate_io_request(address, width);
        if (ACPI_SUCCESS(status)) {
                status = acpi_os_read_port(address, value, width);
-               return status;
+               return (status);
        }
 
        if (status != AE_AML_ILLEGAL_ADDRESS) {
-               return status;
+               return (status);
        }
 
        /*
@@ -253,7 +253,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
                if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
                        status = acpi_os_read_port(address, &one_byte, 8);
                        if (ACPI_FAILURE(status)) {
-                               return status;
+                               return (status);
                        }
 
                        *value |= (one_byte << i);
@@ -262,7 +262,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
                address++;
        }
 
-       return AE_OK;
+       return (AE_OK);
 }
 
 /******************************************************************************
@@ -297,11 +297,11 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
        status = acpi_hw_validate_io_request(address, width);
        if (ACPI_SUCCESS(status)) {
                status = acpi_os_write_port(address, value, width);
-               return status;
+               return (status);
        }
 
        if (status != AE_AML_ILLEGAL_ADDRESS) {
-               return status;
+               return (status);
        }
 
        /*
@@ -317,12 +317,12 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
                        status =
                            acpi_os_write_port(address, (value >> i) & 0xFF, 8);
                        if (ACPI_FAILURE(status)) {
-                               return status;
+                               return (status);
                        }
                }
 
                address++;
        }
 
-       return AE_OK;
+       return (AE_OK);
 }
index 05a154c..04c2e16 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -80,10 +80,10 @@ acpi_status acpi_reset(void)
 
        if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
                /*
-                * For I/O space, write directly to the OSL. This
-                * bypasses the port validation mechanism, which may
-                * block a valid write to the reset register. Spec
-                * section 4.7.3.6 requires register width to be 8.
+                * For I/O space, write directly to the OSL. This bypasses the port
+                * validation mechanism, which may block a valid write to the reset
+                * register.
+                * Spec section 4.7.3.6 requires register width to be 8.
                 */
                status =
                    acpi_os_write_port((acpi_io_address) reset_reg->address,
@@ -333,7 +333,7 @@ ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
  * FUNCTION:    acpi_write_bit_register
  *
  * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
- *              Value           - Value to write to the register, in bit
+ *              value           - Value to write to the register, in bit
  *                                position zero. The bit is automatically
  *                                shifted to the correct position.
  *
@@ -440,17 +440,41 @@ ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
  *              *sleep_type_a        - Where SLP_TYPa is returned
  *              *sleep_type_b        - Where SLP_TYPb is returned
  *
- * RETURN:      status - ACPI status
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
+ *              sleep state via the appropriate \_Sx object.
+ *
+ *  The sleep state package returned from the corresponding \_Sx_ object
+ *  must contain at least one integer.
+ *
+ *  March 2005:
+ *  Added support for a package that contains two integers. This
+ *  goes against the ACPI specification which defines this object as a
+ *  package with one encoded DWORD integer. However, existing practice
+ *  by many BIOS vendors is to return a package with 2 or more integer
+ *  elements, at least one per sleep type (A/B).
  *
- * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
- *              state.
+ *  January 2013:
+ *  Therefore, we must be prepared to accept a package with either a
+ *  single integer or multiple integers.
+ *
+ *  The single integer DWORD format is as follows:
+ *      BYTE 0 - Value for the PM1A SLP_TYP register
+ *      BYTE 1 - Value for the PM1B SLP_TYP register
+ *      BYTE 2-3 - Reserved
+ *
+ *  The dual integer format is as follows:
+ *      Integer 0 - Value for the PM1A SLP_TYP register
+ *      Integer 1 - Value for the PM1A SLP_TYP register
  *
  ******************************************************************************/
 acpi_status
 acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
 {
-       acpi_status status = AE_OK;
+       acpi_status status;
        struct acpi_evaluate_info *info;
+       union acpi_operand_object **elements;
 
        ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
 
@@ -467,18 +491,14 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
                return_ACPI_STATUS(AE_NO_MEMORY);
        }
 
+       /*
+        * Evaluate the \_Sx namespace object containing the register values
+        * for this state
+        */
        info->pathname =
            ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
-
-       /* Evaluate the namespace object containing the values for this state */
-
        status = acpi_ns_evaluate(info);
        if (ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "%s while evaluating SleepState [%s]\n",
-                                 acpi_format_exception(status),
-                                 info->pathname));
-
                goto cleanup;
        }
 
@@ -487,64 +507,67 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
        if (!info->return_object) {
                ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
                            info->pathname));
-               status = AE_NOT_EXIST;
+               status = AE_AML_NO_RETURN_VALUE;
+               goto cleanup;
        }
 
-       /* It must be of type Package */
+       /* Return object must be of type Package */
 
-       else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
+       if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
                ACPI_ERROR((AE_INFO,
                            "Sleep State return object is not a Package"));
                status = AE_AML_OPERAND_TYPE;
+               goto cleanup1;
        }
 
        /*
-        * The package must have at least two elements. NOTE (March 2005): This
-        * goes against the current ACPI spec which defines this object as a
-        * package with one encoded DWORD element. However, existing practice
-        * by BIOS vendors seems to be to have 2 or more elements, at least
-        * one per sleep type (A/B).
+        * Any warnings about the package length or the object types have
+        * already been issued by the predefined name module -- there is no
+        * need to repeat them here.
         */
-       else if (info->return_object->package.count < 2) {
-               ACPI_ERROR((AE_INFO,
-                           "Sleep State return package does not have at least two elements"));
-               status = AE_AML_NO_OPERAND;
-       }
+       elements = info->return_object->package.elements;
+       switch (info->return_object->package.count) {
+       case 0:
+               status = AE_AML_PACKAGE_LIMIT;
+               break;
+
+       case 1:
+               if (elements[0]->common.type != ACPI_TYPE_INTEGER) {
+                       status = AE_AML_OPERAND_TYPE;
+                       break;
+               }
 
-       /* The first two elements must both be of type Integer */
+               /* A valid _Sx_ package with one integer */
 
-       else if (((info->return_object->package.elements[0])->common.type
-                 != ACPI_TYPE_INTEGER) ||
-                ((info->return_object->package.elements[1])->common.type
-                 != ACPI_TYPE_INTEGER)) {
-               ACPI_ERROR((AE_INFO,
-                           "Sleep State return package elements are not both Integers "
-                           "(%s, %s)",
-                           acpi_ut_get_object_type_name(info->return_object->
-                                                        package.elements[0]),
-                           acpi_ut_get_object_type_name(info->return_object->
-                                                        package.elements[1])));
-               status = AE_AML_OPERAND_TYPE;
-       } else {
-               /* Valid _Sx_ package size, type, and value */
+               *sleep_type_a = (u8)elements[0]->integer.value;
+               *sleep_type_b = (u8)(elements[0]->integer.value >> 8);
+               break;
 
-               *sleep_type_a = (u8)
-                   (info->return_object->package.elements[0])->integer.value;
-               *sleep_type_b = (u8)
-                   (info->return_object->package.elements[1])->integer.value;
-       }
+       case 2:
+       default:
+               if ((elements[0]->common.type != ACPI_TYPE_INTEGER) ||
+                   (elements[1]->common.type != ACPI_TYPE_INTEGER)) {
+                       status = AE_AML_OPERAND_TYPE;
+                       break;
+               }
 
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status,
-                               "While evaluating SleepState [%s], bad Sleep object %p type %s",
-                               info->pathname, info->return_object,
-                               acpi_ut_get_object_type_name(info->
-                                                            return_object)));
+               /* A valid _Sx_ package with two integers */
+
+               *sleep_type_a = (u8)elements[0]->integer.value;
+               *sleep_type_b = (u8)elements[1]->integer.value;
+               break;
        }
 
+      cleanup1:
        acpi_ut_remove_reference(info->return_object);
 
       cleanup:
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "While evaluating Sleep State [%s]",
+                               info->pathname));
+       }
+
        ACPI_FREE(info);
        return_ACPI_STATUS(status);
 }
index ae443fe..35eebda 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,9 +41,9 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include <linux/module.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwxfsleep")
@@ -207,7 +207,7 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
                                    (u32)acpi_gbl_FADT.s4_bios_request, 8);
 
        do {
-               acpi_os_stall(1000);
+               acpi_os_stall(ACPI_USEC_PER_MSEC);
                status =
                    acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
                if (ACPI_FAILURE(status)) {
@@ -350,7 +350,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
+ * DESCRIPTION: Enter a system sleep state
  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
@@ -382,8 +382,9 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
  * RETURN:      Status
  *
  * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
- *              sleep.
- *              Called with interrupts DISABLED.
+ *              sleep. Called with interrupts DISABLED.
+ *              We break wake/resume into 2 stages so that OSPM can handle
+ *              various OS-specific tasks between the two steps.
  *
  ******************************************************************************/
 acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
index d70eaf3..8769cf8 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 15143c4..2437373 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 924b3c7..ce6e973 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
+#include <acpi/acoutput.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsdump")
@@ -77,8 +78,9 @@ void acpi_ns_print_pathname(u32 num_segments, char *pathname)
 
        ACPI_FUNCTION_NAME(ns_print_pathname);
 
-       if (!(acpi_dbg_level & ACPI_LV_NAMES)
-           || !(acpi_dbg_layer & ACPI_NAMESPACE)) {
+       /* Check if debug output enabled */
+
+       if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_NAMES, ACPI_NAMESPACE)) {
                return;
        }
 
@@ -127,7 +129,7 @@ acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component)
 
        /* Do this only if the requested debug level and component are enabled */
 
-       if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) {
+       if (!ACPI_IS_DEBUG_ENABLED(level, component)) {
                return_VOID;
        }
 
@@ -729,5 +731,5 @@ void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth)
                             ACPI_OWNER_ID_MAX, search_handle);
        return_VOID;
 }
-#endif                         /* _ACPI_ASL_COMPILER */
-#endif                         /* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */
+#endif
+#endif
index 944d4c8..409ae80 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,6 @@
  */
 
 #include <acpi/acpi.h>
-#include "accommon.h"
 
 /* TBD: This entire module is apparently obsolete and should be removed */
 
index 69074be..1538f3e 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 4328e2a..2a431ec 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,6 @@
 #include "acnamesp.h"
 #include "acdispat.h"
 #include "acinterp.h"
-#include <linux/nmi.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsinit")
@@ -87,7 +86,7 @@ acpi_status acpi_ns_initialize_objects(void)
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
                          "**** Starting initialization of namespace objects ****\n"));
        ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-                             "Completing Region/Field/Buffer/Package initialization:"));
+                             "Completing Region/Field/Buffer/Package initialization:\n"));
 
        /* Set all init info to zero */
 
@@ -103,7 +102,7 @@ acpi_status acpi_ns_initialize_objects(void)
        }
 
        ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-                             "\nInitialized %u/%u Regions %u/%u Fields %u/%u "
+                             "    Initialized %u/%u Regions %u/%u Fields %u/%u "
                              "Buffers %u/%u Packages (%u nodes)\n",
                              info.op_region_init, info.op_region_count,
                              info.field_init, info.field_count,
@@ -150,7 +149,7 @@ acpi_status acpi_ns_initialize_devices(void)
 
        ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
                              "Initializing Device/Processor/Thermal objects "
-                             "by executing _INI methods:"));
+                             "and executing _INI/_STA methods:\n"));
 
        /* Tree analysis: find all subtrees that contain _INI methods */
 
@@ -208,7 +207,7 @@ acpi_status acpi_ns_initialize_devices(void)
        }
 
        ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-                             "\nExecuted %u _INI methods requiring %u _STA executions "
+                             "    Executed %u _INI methods requiring %u _STA executions "
                              "(examined %u objects)\n",
                              info.num_INI, info.num_STA, info.device_count));
 
@@ -350,14 +349,6 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
        }
 
        /*
-        * Print a dot for each object unless we are going to print the entire
-        * pathname
-        */
-       if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
-               ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
-       }
-
-       /*
         * We ignore errors from above, and always return OK, since we don't want
         * to abort the walk on any single error.
         */
@@ -572,20 +563,10 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
        info->parameters = NULL;
        info->flags = ACPI_IGNORE_RETURN_VALUE;
 
-       /*
-        * Some hardware relies on this being executed as atomically
-        * as possible (without an NMI being received in the middle of
-        * this) - so disable NMIs and initialize the device:
-        */
        status = acpi_ns_evaluate(info);
 
        if (ACPI_SUCCESS(status)) {
                walk_info->num_INI++;
-
-               if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
-                   (!(acpi_dbg_level & ACPI_LV_INFO))) {
-                       ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
-               }
        }
 #ifdef ACPI_DEBUG_OUTPUT
        else if (status != AE_NOT_FOUND) {
index 911f991..0a7badc 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 55a175e..90a0380 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -126,7 +126,8 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
  *              the node, In external format (name segments separated by path
  *              separators.)
  *
- * DESCRIPTION: Used for debug printing in acpi_ns_search_table().
+ * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
+ *              for error and debug statements.
  *
  ******************************************************************************/
 
index e69f7fa..7a736f4 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 233f756..35dde81 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 2419f41..224c300 100644 (file)
@@ -1,12 +1,11 @@
 /******************************************************************************
  *
  * Module Name: nspredef - Validation of ACPI predefined methods and objects
- *              $Revision: 1.1 $
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -74,27 +73,6 @@ ACPI_MODULE_NAME("nspredef")
  ******************************************************************************/
 /* Local prototypes */
 static acpi_status
-acpi_ns_check_package(struct acpi_predefined_data *data,
-                     union acpi_operand_object **return_object_ptr);
-
-static acpi_status
-acpi_ns_check_package_list(struct acpi_predefined_data *data,
-                          const union acpi_predefined_info *package,
-                          union acpi_operand_object **elements, u32 count);
-
-static acpi_status
-acpi_ns_check_package_elements(struct acpi_predefined_data *data,
-                              union acpi_operand_object **elements,
-                              u8 type1,
-                              u32 count1,
-                              u8 type2, u32 count2, u32 start_index);
-
-static acpi_status
-acpi_ns_check_object_type(struct acpi_predefined_data *data,
-                         union acpi_operand_object **return_object_ptr,
-                         u32 expected_btypes, u32 package_index);
-
-static acpi_status
 acpi_ns_check_reference(struct acpi_predefined_data *data,
                        union acpi_operand_object *return_object);
 
@@ -148,7 +126,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
 
        pathname = acpi_ns_get_external_pathname(node);
        if (!pathname) {
-               return AE_OK;   /* Could not get pathname, ignore */
+               return (AE_OK); /* Could not get pathname, ignore */
        }
 
        /*
@@ -408,564 +386,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ns_check_package
- *
- * PARAMETERS:  data            - Pointer to validation data structure
- *              return_object_ptr - Pointer to the object returned from the
- *                                evaluation of a method or object
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Check a returned package object for the correct count and
- *              correct type of all sub-objects.
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ns_check_package(struct acpi_predefined_data *data,
-                     union acpi_operand_object **return_object_ptr)
-{
-       union acpi_operand_object *return_object = *return_object_ptr;
-       const union acpi_predefined_info *package;
-       union acpi_operand_object **elements;
-       acpi_status status = AE_OK;
-       u32 expected_count;
-       u32 count;
-       u32 i;
-
-       ACPI_FUNCTION_NAME(ns_check_package);
-
-       /* The package info for this name is in the next table entry */
-
-       package = data->predefined + 1;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-                         "%s Validating return Package of Type %X, Count %X\n",
-                         data->pathname, package->ret_info.type,
-                         return_object->package.count));
-
-       /*
-        * For variable-length Packages, we can safely remove all embedded
-        * and trailing NULL package elements
-        */
-       acpi_ns_remove_null_elements(data, package->ret_info.type,
-                                    return_object);
-
-       /* Extract package count and elements array */
-
-       elements = return_object->package.elements;
-       count = return_object->package.count;
-
-       /* The package must have at least one element, else invalid */
-
-       if (!count) {
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
-                                     "Return Package has no elements (empty)"));
-
-               return (AE_AML_OPERAND_VALUE);
-       }
-
-       /*
-        * Decode the type of the expected package contents
-        *
-        * PTYPE1 packages contain no subpackages
-        * PTYPE2 packages contain sub-packages
-        */
-       switch (package->ret_info.type) {
-       case ACPI_PTYPE1_FIXED:
-
-               /*
-                * The package count is fixed and there are no sub-packages
-                *
-                * If package is too small, exit.
-                * If package is larger than expected, issue warning but continue
-                */
-               expected_count =
-                   package->ret_info.count1 + package->ret_info.count2;
-               if (count < expected_count) {
-                       goto package_too_small;
-               } else if (count > expected_count) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
-                                         "%s: Return Package is larger than needed - "
-                                         "found %u, expected %u\n",
-                                         data->pathname, count,
-                                         expected_count));
-               }
-
-               /* Validate all elements of the returned package */
-
-               status = acpi_ns_check_package_elements(data, elements,
-                                                       package->ret_info.
-                                                       object_type1,
-                                                       package->ret_info.
-                                                       count1,
-                                                       package->ret_info.
-                                                       object_type2,
-                                                       package->ret_info.
-                                                       count2, 0);
-               break;
-
-       case ACPI_PTYPE1_VAR:
-
-               /*
-                * The package count is variable, there are no sub-packages, and all
-                * elements must be of the same type
-                */
-               for (i = 0; i < count; i++) {
-                       status = acpi_ns_check_object_type(data, elements,
-                                                          package->ret_info.
-                                                          object_type1, i);
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
-                       }
-                       elements++;
-               }
-               break;
-
-       case ACPI_PTYPE1_OPTION:
-
-               /*
-                * The package count is variable, there are no sub-packages. There are
-                * a fixed number of required elements, and a variable number of
-                * optional elements.
-                *
-                * Check if package is at least as large as the minimum required
-                */
-               expected_count = package->ret_info3.count;
-               if (count < expected_count) {
-                       goto package_too_small;
-               }
-
-               /* Variable number of sub-objects */
-
-               for (i = 0; i < count; i++) {
-                       if (i < package->ret_info3.count) {
-
-                               /* These are the required package elements (0, 1, or 2) */
-
-                               status =
-                                   acpi_ns_check_object_type(data, elements,
-                                                             package->
-                                                             ret_info3.
-                                                             object_type[i],
-                                                             i);
-                               if (ACPI_FAILURE(status)) {
-                                       return (status);
-                               }
-                       } else {
-                               /* These are the optional package elements */
-
-                               status =
-                                   acpi_ns_check_object_type(data, elements,
-                                                             package->
-                                                             ret_info3.
-                                                             tail_object_type,
-                                                             i);
-                               if (ACPI_FAILURE(status)) {
-                                       return (status);
-                               }
-                       }
-                       elements++;
-               }
-               break;
-
-       case ACPI_PTYPE2_REV_FIXED:
-
-               /* First element is the (Integer) revision */
-
-               status = acpi_ns_check_object_type(data, elements,
-                                                  ACPI_RTYPE_INTEGER, 0);
-               if (ACPI_FAILURE(status)) {
-                       return (status);
-               }
-
-               elements++;
-               count--;
-
-               /* Examine the sub-packages */
-
-               status =
-                   acpi_ns_check_package_list(data, package, elements, count);
-               break;
-
-       case ACPI_PTYPE2_PKG_COUNT:
-
-               /* First element is the (Integer) count of sub-packages to follow */
-
-               status = acpi_ns_check_object_type(data, elements,
-                                                  ACPI_RTYPE_INTEGER, 0);
-               if (ACPI_FAILURE(status)) {
-                       return (status);
-               }
-
-               /*
-                * Count cannot be larger than the parent package length, but allow it
-                * to be smaller. The >= accounts for the Integer above.
-                */
-               expected_count = (u32) (*elements)->integer.value;
-               if (expected_count >= count) {
-                       goto package_too_small;
-               }
-
-               count = expected_count;
-               elements++;
-
-               /* Examine the sub-packages */
-
-               status =
-                   acpi_ns_check_package_list(data, package, elements, count);
-               break;
-
-       case ACPI_PTYPE2:
-       case ACPI_PTYPE2_FIXED:
-       case ACPI_PTYPE2_MIN:
-       case ACPI_PTYPE2_COUNT:
-       case ACPI_PTYPE2_FIX_VAR:
-
-               /*
-                * These types all return a single Package that consists of a
-                * variable number of sub-Packages.
-                *
-                * First, ensure that the first element is a sub-Package. If not,
-                * the BIOS may have incorrectly returned the object as a single
-                * package instead of a Package of Packages (a common error if
-                * there is only one entry). We may be able to repair this by
-                * wrapping the returned Package with a new outer Package.
-                */
-               if (*elements
-                   && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
-
-                       /* Create the new outer package and populate it */
-
-                       status =
-                           acpi_ns_wrap_with_package(data, return_object,
-                                                     return_object_ptr);
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
-                       }
-
-                       /* Update locals to point to the new package (of 1 element) */
-
-                       return_object = *return_object_ptr;
-                       elements = return_object->package.elements;
-                       count = 1;
-               }
-
-               /* Examine the sub-packages */
-
-               status =
-                   acpi_ns_check_package_list(data, package, elements, count);
-               break;
-
-       default:
-
-               /* Should not get here if predefined info table is correct */
-
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
-                                     "Invalid internal return type in table entry: %X",
-                                     package->ret_info.type));
-
-               return (AE_AML_INTERNAL);
-       }
-
-       return (status);
-
-package_too_small:
-
-       /* Error exit for the case with an incorrect package count */
-
-       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
-                             "Return Package is too small - found %u elements, expected %u",
-                             count, expected_count));
-
-       return (AE_AML_OPERAND_VALUE);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ns_check_package_list
- *
- * PARAMETERS:  data            - Pointer to validation data structure
- *              package         - Pointer to package-specific info for method
- *              elements        - Element list of parent package. All elements
- *                                of this list should be of type Package.
- *              count           - Count of subpackages
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Examine a list of subpackages
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ns_check_package_list(struct acpi_predefined_data *data,
-                          const union acpi_predefined_info *package,
-                          union acpi_operand_object **elements, u32 count)
-{
-       union acpi_operand_object *sub_package;
-       union acpi_operand_object **sub_elements;
-       acpi_status status;
-       u32 expected_count;
-       u32 i;
-       u32 j;
-
-       /*
-        * Validate each sub-Package in the parent Package
-        *
-        * NOTE: assumes list of sub-packages contains no NULL elements.
-        * Any NULL elements should have been removed by earlier call
-        * to acpi_ns_remove_null_elements.
-        */
-       for (i = 0; i < count; i++) {
-               sub_package = *elements;
-               sub_elements = sub_package->package.elements;
-               data->parent_package = sub_package;
-
-               /* Each sub-object must be of type Package */
-
-               status = acpi_ns_check_object_type(data, &sub_package,
-                                                  ACPI_RTYPE_PACKAGE, i);
-               if (ACPI_FAILURE(status)) {
-                       return (status);
-               }
-
-               /* Examine the different types of expected sub-packages */
-
-               data->parent_package = sub_package;
-               switch (package->ret_info.type) {
-               case ACPI_PTYPE2:
-               case ACPI_PTYPE2_PKG_COUNT:
-               case ACPI_PTYPE2_REV_FIXED:
-
-                       /* Each subpackage has a fixed number of elements */
-
-                       expected_count =
-                           package->ret_info.count1 + package->ret_info.count2;
-                       if (sub_package->package.count < expected_count) {
-                               goto package_too_small;
-                       }
-
-                       status =
-                           acpi_ns_check_package_elements(data, sub_elements,
-                                                          package->ret_info.
-                                                          object_type1,
-                                                          package->ret_info.
-                                                          count1,
-                                                          package->ret_info.
-                                                          object_type2,
-                                                          package->ret_info.
-                                                          count2, 0);
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
-                       }
-                       break;
-
-               case ACPI_PTYPE2_FIX_VAR:
-                       /*
-                        * Each subpackage has a fixed number of elements and an
-                        * optional element
-                        */
-                       expected_count =
-                           package->ret_info.count1 + package->ret_info.count2;
-                       if (sub_package->package.count < expected_count) {
-                               goto package_too_small;
-                       }
-
-                       status =
-                           acpi_ns_check_package_elements(data, sub_elements,
-                                                          package->ret_info.
-                                                          object_type1,
-                                                          package->ret_info.
-                                                          count1,
-                                                          package->ret_info.
-                                                          object_type2,
-                                                          sub_package->package.
-                                                          count -
-                                                          package->ret_info.
-                                                          count1, 0);
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
-                       }
-                       break;
-
-               case ACPI_PTYPE2_FIXED:
-
-                       /* Each sub-package has a fixed length */
-
-                       expected_count = package->ret_info2.count;
-                       if (sub_package->package.count < expected_count) {
-                               goto package_too_small;
-                       }
-
-                       /* Check the type of each sub-package element */
-
-                       for (j = 0; j < expected_count; j++) {
-                               status =
-                                   acpi_ns_check_object_type(data,
-                                                             &sub_elements[j],
-                                                             package->
-                                                             ret_info2.
-                                                             object_type[j],
-                                                             j);
-                               if (ACPI_FAILURE(status)) {
-                                       return (status);
-                               }
-                       }
-                       break;
-
-               case ACPI_PTYPE2_MIN:
-
-                       /* Each sub-package has a variable but minimum length */
-
-                       expected_count = package->ret_info.count1;
-                       if (sub_package->package.count < expected_count) {
-                               goto package_too_small;
-                       }
-
-                       /* Check the type of each sub-package element */
-
-                       status =
-                           acpi_ns_check_package_elements(data, sub_elements,
-                                                          package->ret_info.
-                                                          object_type1,
-                                                          sub_package->package.
-                                                          count, 0, 0, 0);
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
-                       }
-                       break;
-
-               case ACPI_PTYPE2_COUNT:
-
-                       /*
-                        * First element is the (Integer) count of elements, including
-                        * the count field (the ACPI name is num_elements)
-                        */
-                       status = acpi_ns_check_object_type(data, sub_elements,
-                                                          ACPI_RTYPE_INTEGER,
-                                                          0);
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
-                       }
-
-                       /*
-                        * Make sure package is large enough for the Count and is
-                        * is as large as the minimum size
-                        */
-                       expected_count = (u32)(*sub_elements)->integer.value;
-                       if (sub_package->package.count < expected_count) {
-                               goto package_too_small;
-                       }
-                       if (sub_package->package.count <
-                           package->ret_info.count1) {
-                               expected_count = package->ret_info.count1;
-                               goto package_too_small;
-                       }
-                       if (expected_count == 0) {
-                               /*
-                                * Either the num_entries element was originally zero or it was
-                                * a NULL element and repaired to an Integer of value zero.
-                                * In either case, repair it by setting num_entries to be the
-                                * actual size of the subpackage.
-                                */
-                               expected_count = sub_package->package.count;
-                               (*sub_elements)->integer.value = expected_count;
-                       }
-
-                       /* Check the type of each sub-package element */
-
-                       status =
-                           acpi_ns_check_package_elements(data,
-                                                          (sub_elements + 1),
-                                                          package->ret_info.
-                                                          object_type1,
-                                                          (expected_count - 1),
-                                                          0, 0, 1);
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
-                       }
-                       break;
-
-               default:        /* Should not get here, type was validated by caller */
-
-                       return (AE_AML_INTERNAL);
-               }
-
-               elements++;
-       }
-
-       return (AE_OK);
-
-package_too_small:
-
-       /* The sub-package count was smaller than required */
-
-       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
-                             "Return Sub-Package[%u] is too small - found %u elements, expected %u",
-                             i, sub_package->package.count, expected_count));
-
-       return (AE_AML_OPERAND_VALUE);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ns_check_package_elements
- *
- * PARAMETERS:  data            - Pointer to validation data structure
- *              elements        - Pointer to the package elements array
- *              type1           - Object type for first group
- *              count1          - Count for first group
- *              type2           - Object type for second group
- *              count2          - Count for second group
- *              start_index     - Start of the first group of elements
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Check that all elements of a package are of the correct object
- *              type. Supports up to two groups of different object types.
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ns_check_package_elements(struct acpi_predefined_data *data,
-                              union acpi_operand_object **elements,
-                              u8 type1,
-                              u32 count1,
-                              u8 type2, u32 count2, u32 start_index)
-{
-       union acpi_operand_object **this_element = elements;
-       acpi_status status;
-       u32 i;
-
-       /*
-        * Up to two groups of package elements are supported by the data
-        * structure. All elements in each group must be of the same type.
-        * The second group can have a count of zero.
-        */
-       for (i = 0; i < count1; i++) {
-               status = acpi_ns_check_object_type(data, this_element,
-                                                  type1, i + start_index);
-               if (ACPI_FAILURE(status)) {
-                       return (status);
-               }
-               this_element++;
-       }
-
-       for (i = 0; i < count2; i++) {
-               status = acpi_ns_check_object_type(data, this_element,
-                                                  type2,
-                                                  (i + count1 + start_index));
-               if (ACPI_FAILURE(status)) {
-                       return (status);
-               }
-               this_element++;
-       }
-
-       return (AE_OK);
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ns_check_object_type
  *
  * PARAMETERS:  data            - Pointer to validation data structure
@@ -983,7 +403,7 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data,
  *
  ******************************************************************************/
 
-static acpi_status
+acpi_status
 acpi_ns_check_object_type(struct acpi_predefined_data *data,
                          union acpi_operand_object **return_object_ptr,
                          u32 expected_btypes, u32 package_index)
diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c
new file mode 100644 (file)
index 0000000..a401554
--- /dev/null
@@ -0,0 +1,621 @@
+/******************************************************************************
+ *
+ * Module Name: nsprepkg - Validation of package objects for predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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 "acpredef.h"
+
+#define _COMPONENT          ACPI_NAMESPACE
+ACPI_MODULE_NAME("nsprepkg")
+
+/* Local prototypes */
+static acpi_status
+acpi_ns_check_package_list(struct acpi_predefined_data *data,
+                          const union acpi_predefined_info *package,
+                          union acpi_operand_object **elements, u32 count);
+
+static acpi_status
+acpi_ns_check_package_elements(struct acpi_predefined_data *data,
+                              union acpi_operand_object **elements,
+                              u8 type1,
+                              u32 count1,
+                              u8 type2, u32 count2, u32 start_index);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_package
+ *
+ * PARAMETERS:  data                - Pointer to validation data structure
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check a returned package object for the correct count and
+ *              correct type of all sub-objects.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_check_package(struct acpi_predefined_data *data,
+                     union acpi_operand_object **return_object_ptr)
+{
+       union acpi_operand_object *return_object = *return_object_ptr;
+       const union acpi_predefined_info *package;
+       union acpi_operand_object **elements;
+       acpi_status status = AE_OK;
+       u32 expected_count;
+       u32 count;
+       u32 i;
+
+       ACPI_FUNCTION_NAME(ns_check_package);
+
+       /* The package info for this name is in the next table entry */
+
+       package = data->predefined + 1;
+
+       ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+                         "%s Validating return Package of Type %X, Count %X\n",
+                         data->pathname, package->ret_info.type,
+                         return_object->package.count));
+
+       /*
+        * For variable-length Packages, we can safely remove all embedded
+        * and trailing NULL package elements
+        */
+       acpi_ns_remove_null_elements(data, package->ret_info.type,
+                                    return_object);
+
+       /* Extract package count and elements array */
+
+       elements = return_object->package.elements;
+       count = return_object->package.count;
+
+       /* The package must have at least one element, else invalid */
+
+       if (!count) {
+               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+                                     "Return Package has no elements (empty)"));
+
+               return (AE_AML_OPERAND_VALUE);
+       }
+
+       /*
+        * Decode the type of the expected package contents
+        *
+        * PTYPE1 packages contain no subpackages
+        * PTYPE2 packages contain sub-packages
+        */
+       switch (package->ret_info.type) {
+       case ACPI_PTYPE1_FIXED:
+
+               /*
+                * The package count is fixed and there are no sub-packages
+                *
+                * If package is too small, exit.
+                * If package is larger than expected, issue warning but continue
+                */
+               expected_count =
+                   package->ret_info.count1 + package->ret_info.count2;
+               if (count < expected_count) {
+                       goto package_too_small;
+               } else if (count > expected_count) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+                                         "%s: Return Package is larger than needed - "
+                                         "found %u, expected %u\n",
+                                         data->pathname, count,
+                                         expected_count));
+               }
+
+               /* Validate all elements of the returned package */
+
+               status = acpi_ns_check_package_elements(data, elements,
+                                                       package->ret_info.
+                                                       object_type1,
+                                                       package->ret_info.
+                                                       count1,
+                                                       package->ret_info.
+                                                       object_type2,
+                                                       package->ret_info.
+                                                       count2, 0);
+               break;
+
+       case ACPI_PTYPE1_VAR:
+
+               /*
+                * The package count is variable, there are no sub-packages, and all
+                * elements must be of the same type
+                */
+               for (i = 0; i < count; i++) {
+                       status = acpi_ns_check_object_type(data, elements,
+                                                          package->ret_info.
+                                                          object_type1, i);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+                       elements++;
+               }
+               break;
+
+       case ACPI_PTYPE1_OPTION:
+
+               /*
+                * The package count is variable, there are no sub-packages. There are
+                * a fixed number of required elements, and a variable number of
+                * optional elements.
+                *
+                * Check if package is at least as large as the minimum required
+                */
+               expected_count = package->ret_info3.count;
+               if (count < expected_count) {
+                       goto package_too_small;
+               }
+
+               /* Variable number of sub-objects */
+
+               for (i = 0; i < count; i++) {
+                       if (i < package->ret_info3.count) {
+
+                               /* These are the required package elements (0, 1, or 2) */
+
+                               status =
+                                   acpi_ns_check_object_type(data, elements,
+                                                             package->
+                                                             ret_info3.
+                                                             object_type[i],
+                                                             i);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                       } else {
+                               /* These are the optional package elements */
+
+                               status =
+                                   acpi_ns_check_object_type(data, elements,
+                                                             package->
+                                                             ret_info3.
+                                                             tail_object_type,
+                                                             i);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                       }
+                       elements++;
+               }
+               break;
+
+       case ACPI_PTYPE2_REV_FIXED:
+
+               /* First element is the (Integer) revision */
+
+               status = acpi_ns_check_object_type(data, elements,
+                                                  ACPI_RTYPE_INTEGER, 0);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+
+               elements++;
+               count--;
+
+               /* Examine the sub-packages */
+
+               status =
+                   acpi_ns_check_package_list(data, package, elements, count);
+               break;
+
+       case ACPI_PTYPE2_PKG_COUNT:
+
+               /* First element is the (Integer) count of sub-packages to follow */
+
+               status = acpi_ns_check_object_type(data, elements,
+                                                  ACPI_RTYPE_INTEGER, 0);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+
+               /*
+                * Count cannot be larger than the parent package length, but allow it
+                * to be smaller. The >= accounts for the Integer above.
+                */
+               expected_count = (u32)(*elements)->integer.value;
+               if (expected_count >= count) {
+                       goto package_too_small;
+               }
+
+               count = expected_count;
+               elements++;
+
+               /* Examine the sub-packages */
+
+               status =
+                   acpi_ns_check_package_list(data, package, elements, count);
+               break;
+
+       case ACPI_PTYPE2:
+       case ACPI_PTYPE2_FIXED:
+       case ACPI_PTYPE2_MIN:
+       case ACPI_PTYPE2_COUNT:
+       case ACPI_PTYPE2_FIX_VAR:
+
+               /*
+                * These types all return a single Package that consists of a
+                * variable number of sub-Packages.
+                *
+                * First, ensure that the first element is a sub-Package. If not,
+                * the BIOS may have incorrectly returned the object as a single
+                * package instead of a Package of Packages (a common error if
+                * there is only one entry). We may be able to repair this by
+                * wrapping the returned Package with a new outer Package.
+                */
+               if (*elements
+                   && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
+
+                       /* Create the new outer package and populate it */
+
+                       status =
+                           acpi_ns_wrap_with_package(data, return_object,
+                                                     return_object_ptr);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+
+                       /* Update locals to point to the new package (of 1 element) */
+
+                       return_object = *return_object_ptr;
+                       elements = return_object->package.elements;
+                       count = 1;
+               }
+
+               /* Examine the sub-packages */
+
+               status =
+                   acpi_ns_check_package_list(data, package, elements, count);
+               break;
+
+       default:
+
+               /* Should not get here if predefined info table is correct */
+
+               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+                                     "Invalid internal return type in table entry: %X",
+                                     package->ret_info.type));
+
+               return (AE_AML_INTERNAL);
+       }
+
+       return (status);
+
+      package_too_small:
+
+       /* Error exit for the case with an incorrect package count */
+
+       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+                             "Return Package is too small - found %u elements, expected %u",
+                             count, expected_count));
+
+       return (AE_AML_OPERAND_VALUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_package_list
+ *
+ * PARAMETERS:  data            - Pointer to validation data structure
+ *              package         - Pointer to package-specific info for method
+ *              elements        - Element list of parent package. All elements
+ *                                of this list should be of type Package.
+ *              count           - Count of subpackages
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Examine a list of subpackages
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_package_list(struct acpi_predefined_data *data,
+                          const union acpi_predefined_info *package,
+                          union acpi_operand_object **elements, u32 count)
+{
+       union acpi_operand_object *sub_package;
+       union acpi_operand_object **sub_elements;
+       acpi_status status;
+       u32 expected_count;
+       u32 i;
+       u32 j;
+
+       /*
+        * Validate each sub-Package in the parent Package
+        *
+        * NOTE: assumes list of sub-packages contains no NULL elements.
+        * Any NULL elements should have been removed by earlier call
+        * to acpi_ns_remove_null_elements.
+        */
+       for (i = 0; i < count; i++) {
+               sub_package = *elements;
+               sub_elements = sub_package->package.elements;
+               data->parent_package = sub_package;
+
+               /* Each sub-object must be of type Package */
+
+               status = acpi_ns_check_object_type(data, &sub_package,
+                                                  ACPI_RTYPE_PACKAGE, i);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+
+               /* Examine the different types of expected sub-packages */
+
+               data->parent_package = sub_package;
+               switch (package->ret_info.type) {
+               case ACPI_PTYPE2:
+               case ACPI_PTYPE2_PKG_COUNT:
+               case ACPI_PTYPE2_REV_FIXED:
+
+                       /* Each subpackage has a fixed number of elements */
+
+                       expected_count =
+                           package->ret_info.count1 + package->ret_info.count2;
+                       if (sub_package->package.count < expected_count) {
+                               goto package_too_small;
+                       }
+
+                       status =
+                           acpi_ns_check_package_elements(data, sub_elements,
+                                                          package->ret_info.
+                                                          object_type1,
+                                                          package->ret_info.
+                                                          count1,
+                                                          package->ret_info.
+                                                          object_type2,
+                                                          package->ret_info.
+                                                          count2, 0);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+                       break;
+
+               case ACPI_PTYPE2_FIX_VAR:
+                       /*
+                        * Each subpackage has a fixed number of elements and an
+                        * optional element
+                        */
+                       expected_count =
+                           package->ret_info.count1 + package->ret_info.count2;
+                       if (sub_package->package.count < expected_count) {
+                               goto package_too_small;
+                       }
+
+                       status =
+                           acpi_ns_check_package_elements(data, sub_elements,
+                                                          package->ret_info.
+                                                          object_type1,
+                                                          package->ret_info.
+                                                          count1,
+                                                          package->ret_info.
+                                                          object_type2,
+                                                          sub_package->package.
+                                                          count -
+                                                          package->ret_info.
+                                                          count1, 0);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+                       break;
+
+               case ACPI_PTYPE2_FIXED:
+
+                       /* Each sub-package has a fixed length */
+
+                       expected_count = package->ret_info2.count;
+                       if (sub_package->package.count < expected_count) {
+                               goto package_too_small;
+                       }
+
+                       /* Check the type of each sub-package element */
+
+                       for (j = 0; j < expected_count; j++) {
+                               status =
+                                   acpi_ns_check_object_type(data,
+                                                             &sub_elements[j],
+                                                             package->
+                                                             ret_info2.
+                                                             object_type[j],
+                                                             j);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                       }
+                       break;
+
+               case ACPI_PTYPE2_MIN:
+
+                       /* Each sub-package has a variable but minimum length */
+
+                       expected_count = package->ret_info.count1;
+                       if (sub_package->package.count < expected_count) {
+                               goto package_too_small;
+                       }
+
+                       /* Check the type of each sub-package element */
+
+                       status =
+                           acpi_ns_check_package_elements(data, sub_elements,
+                                                          package->ret_info.
+                                                          object_type1,
+                                                          sub_package->package.
+                                                          count, 0, 0, 0);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+                       break;
+
+               case ACPI_PTYPE2_COUNT:
+
+                       /*
+                        * First element is the (Integer) count of elements, including
+                        * the count field (the ACPI name is num_elements)
+                        */
+                       status = acpi_ns_check_object_type(data, sub_elements,
+                                                          ACPI_RTYPE_INTEGER,
+                                                          0);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+
+                       /*
+                        * Make sure package is large enough for the Count and is
+                        * is as large as the minimum size
+                        */
+                       expected_count = (u32)(*sub_elements)->integer.value;
+                       if (sub_package->package.count < expected_count) {
+                               goto package_too_small;
+                       }
+                       if (sub_package->package.count <
+                           package->ret_info.count1) {
+                               expected_count = package->ret_info.count1;
+                               goto package_too_small;
+                       }
+                       if (expected_count == 0) {
+                               /*
+                                * Either the num_entries element was originally zero or it was
+                                * a NULL element and repaired to an Integer of value zero.
+                                * In either case, repair it by setting num_entries to be the
+                                * actual size of the subpackage.
+                                */
+                               expected_count = sub_package->package.count;
+                               (*sub_elements)->integer.value = expected_count;
+                       }
+
+                       /* Check the type of each sub-package element */
+
+                       status =
+                           acpi_ns_check_package_elements(data,
+                                                          (sub_elements + 1),
+                                                          package->ret_info.
+                                                          object_type1,
+                                                          (expected_count - 1),
+                                                          0, 0, 1);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+                       break;
+
+               default:        /* Should not get here, type was validated by caller */
+
+                       return (AE_AML_INTERNAL);
+               }
+
+               elements++;
+       }
+
+       return (AE_OK);
+
+      package_too_small:
+
+       /* The sub-package count was smaller than required */
+
+       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+                             "Return Sub-Package[%u] is too small - found %u elements, expected %u",
+                             i, sub_package->package.count, expected_count));
+
+       return (AE_AML_OPERAND_VALUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_package_elements
+ *
+ * PARAMETERS:  data            - Pointer to validation data structure
+ *              elements        - Pointer to the package elements array
+ *              type1           - Object type for first group
+ *              count1          - Count for first group
+ *              type2           - Object type for second group
+ *              count2          - Count for second group
+ *              start_index     - Start of the first group of elements
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check that all elements of a package are of the correct object
+ *              type. Supports up to two groups of different object types.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_package_elements(struct acpi_predefined_data *data,
+                              union acpi_operand_object **elements,
+                              u8 type1,
+                              u32 count1,
+                              u8 type2, u32 count2, u32 start_index)
+{
+       union acpi_operand_object **this_element = elements;
+       acpi_status status;
+       u32 i;
+
+       /*
+        * Up to two groups of package elements are supported by the data
+        * structure. All elements in each group must be of the same type.
+        * The second group can have a count of zero.
+        */
+       for (i = 0; i < count1; i++) {
+               status = acpi_ns_check_object_type(data, this_element,
+                                                  type1, i + start_index);
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+               this_element++;
+       }
+
+       for (i = 0; i < count2; i++) {
+               status = acpi_ns_check_object_type(data, this_element,
+                                                  type2,
+                                                  (i + count1 + start_index));
+               if (ACPI_FAILURE(status)) {
+                       return (status);
+               }
+               this_element++;
+       }
+
+       return (AE_OK);
+}
index 8c5f292..9e83335 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9018925..ba4d982 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,7 +55,8 @@ ACPI_MODULE_NAME("nsrepair2")
  */
 typedef
 acpi_status(*acpi_repair_function) (struct acpi_predefined_data *data,
-                                   union acpi_operand_object **return_object_ptr);
+                                   union acpi_operand_object
+                                   **return_object_ptr);
 
 typedef struct acpi_repair_info {
        char name[ACPI_NAME_SIZE];
index 1d2d8ff..5d43efc 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -328,6 +328,11 @@ acpi_ns_search_and_enter(u32 target_name,
                if ((status == AE_OK) && (flags & ACPI_NS_ERROR_IF_FOUND)) {
                        status = AE_ALREADY_EXISTS;
                }
+#ifdef ACPI_ASL_COMPILER
+               if (*return_node && (*return_node)->type == ACPI_TYPE_ANY) {
+                       (*return_node)->flags |= ANOBJ_IS_EXTERNAL;
+               }
+#endif
 
                /* Either found it or there was an error: finished either way */
 
index b5b4cb7..686420d 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "accommon.h"
 #include "acnamesp.h"
 #include "amlcode.h"
-#include "actables.h"
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsutils")
 
 /* Local prototypes */
-static u8 acpi_ns_valid_path_separator(char sep);
-
 #ifdef ACPI_OBSOLETE_FUNCTIONS
 acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
 #endif
@@ -99,42 +96,6 @@ acpi_ns_print_node_pathname(struct acpi_namespace_node *node,
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ns_valid_root_prefix
- *
- * PARAMETERS:  prefix          - Character to be checked
- *
- * RETURN:      TRUE if a valid prefix
- *
- * DESCRIPTION: Check if a character is a valid ACPI Root prefix
- *
- ******************************************************************************/
-
-u8 acpi_ns_valid_root_prefix(char prefix)
-{
-
-       return ((u8) (prefix == '\\'));
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ns_valid_path_separator
- *
- * PARAMETERS:  sep         - Character to be checked
- *
- * RETURN:      TRUE if a valid path separator
- *
- * DESCRIPTION: Check if a character is a valid ACPI path separator
- *
- ******************************************************************************/
-
-static u8 acpi_ns_valid_path_separator(char sep)
-{
-
-       return ((u8) (sep == '.'));
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ns_get_type
  *
  * PARAMETERS:  node        - Parent Node to be examined
@@ -151,10 +112,10 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node)
 
        if (!node) {
                ACPI_WARNING((AE_INFO, "Null Node parameter"));
-               return_UINT32(ACPI_TYPE_ANY);
+               return_VALUE(ACPI_TYPE_ANY);
        }
 
-       return_UINT32((acpi_object_type) node->type);
+       return_VALUE(node->type);
 }
 
 /*******************************************************************************
@@ -179,10 +140,10 @@ u32 acpi_ns_local(acpi_object_type type)
                /* Type code out of range  */
 
                ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type));
-               return_UINT32(ACPI_NS_NORMAL);
+               return_VALUE(ACPI_NS_NORMAL);
        }
 
-       return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
+       return_VALUE(acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
 }
 
 /*******************************************************************************
@@ -218,19 +179,19 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
         *
         * strlen() + 1 covers the first name_seg, which has no path separator
         */
-       if (acpi_ns_valid_root_prefix(*next_external_char)) {
+       if (ACPI_IS_ROOT_PREFIX(*next_external_char)) {
                info->fully_qualified = TRUE;
                next_external_char++;
 
                /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */
 
-               while (acpi_ns_valid_root_prefix(*next_external_char)) {
+               while (ACPI_IS_ROOT_PREFIX(*next_external_char)) {
                        next_external_char++;
                }
        } else {
                /* Handle Carat prefixes */
 
-               while (*next_external_char == '^') {
+               while (ACPI_IS_PARENT_PREFIX(*next_external_char)) {
                        info->num_carats++;
                        next_external_char++;
                }
@@ -244,7 +205,7 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
        if (*next_external_char) {
                info->num_segments = 1;
                for (i = 0; next_external_char[i]; i++) {
-                       if (acpi_ns_valid_path_separator(next_external_char[i])) {
+                       if (ACPI_IS_PATH_SEPARATOR(next_external_char[i])) {
                                info->num_segments++;
                        }
                }
@@ -282,7 +243,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
        /* Setup the correct prefixes, counts, and pointers */
 
        if (info->fully_qualified) {
-               internal_name[0] = '\\';
+               internal_name[0] = AML_ROOT_PREFIX;
 
                if (num_segments <= 1) {
                        result = &internal_name[1];
@@ -302,7 +263,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
                i = 0;
                if (info->num_carats) {
                        for (i = 0; i < info->num_carats; i++) {
-                               internal_name[i] = '^';
+                               internal_name[i] = AML_PARENT_PREFIX;
                        }
                }
 
@@ -322,7 +283,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
 
        for (; num_segments; num_segments--) {
                for (i = 0; i < ACPI_NAME_SIZE; i++) {
-                       if (acpi_ns_valid_path_separator(*external_name) ||
+                       if (ACPI_IS_PATH_SEPARATOR(*external_name) ||
                            (*external_name == 0)) {
 
                                /* Pad the segment with underscore(s) if segment is short */
@@ -339,7 +300,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
 
                /* Now we must have a path separator, or the pathname is bad */
 
-               if (!acpi_ns_valid_path_separator(*external_name) &&
+               if (!ACPI_IS_PATH_SEPARATOR(*external_name) &&
                    (*external_name != 0)) {
                        return_ACPI_STATUS(AE_BAD_PATHNAME);
                }
@@ -457,13 +418,13 @@ acpi_ns_externalize_name(u32 internal_name_length,
        /* Check for a prefix (one '\' | one or more '^') */
 
        switch (internal_name[0]) {
-       case '\\':
+       case AML_ROOT_PREFIX:
                prefix_length = 1;
                break;
 
-       case '^':
+       case AML_PARENT_PREFIX:
                for (i = 0; i < internal_name_length; i++) {
-                       if (internal_name[i] == '^') {
+                       if (ACPI_IS_PARENT_PREFIX(internal_name[i])) {
                                prefix_length = i + 1;
                        } else {
                                break;
@@ -664,17 +625,17 @@ void acpi_ns_terminate(void)
 
 u32 acpi_ns_opens_scope(acpi_object_type type)
 {
-       ACPI_FUNCTION_TRACE_STR(ns_opens_scope, acpi_ut_get_type_name(type));
+       ACPI_FUNCTION_ENTRY();
 
-       if (!acpi_ut_valid_object_type(type)) {
+       if (type > ACPI_TYPE_LOCAL_MAX) {
 
                /* type code out of range  */
 
                ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type));
-               return_UINT32(ACPI_NS_NORMAL);
+               return (ACPI_NS_NORMAL);
        }
 
-       return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
+       return (((u32)acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
 }
 
 /*******************************************************************************
@@ -710,6 +671,8 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
 
        ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname));
 
+       /* Simplest case is a null pathname */
+
        if (!pathname) {
                *return_node = prefix_node;
                if (!prefix_node) {
@@ -718,6 +681,13 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
                return_ACPI_STATUS(AE_OK);
        }
 
+       /* Quick check for a reference to the root */
+
+       if (ACPI_IS_ROOT_PREFIX(pathname[0]) && (!pathname[1])) {
+               *return_node = acpi_gbl_root_node;
+               return_ACPI_STATUS(AE_OK);
+       }
+
        /* Convert path to internal representation */
 
        status = acpi_ns_internalize_name(pathname, &internal_path);
index 0483877..e70911a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,12 +76,12 @@ struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
 
                /* It's really the parent's _scope_ that we want */
 
-               return parent_node->child;
+               return (parent_node->child);
        }
 
        /* Otherwise just return the next peer */
 
-       return child_node->peer;
+       return (child_node->peer);
 }
 
 /*******************************************************************************
index d6a9f77..fc69949 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -236,7 +236,7 @@ acpi_evaluate_object(acpi_handle handle,
         * 2) No handle, not fully qualified pathname (error)
         * 3) Valid handle
         */
-       if ((pathname) && (acpi_ns_valid_root_prefix(pathname[0]))) {
+       if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
 
                /* The path is fully qualified, just evaluate by name */
 
@@ -492,7 +492,7 @@ acpi_walk_namespace(acpi_object_type type,
         */
        status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
        if (ACPI_FAILURE(status)) {
-               return status;
+               return_ACPI_STATUS(status);
        }
 
        /*
@@ -550,7 +550,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
 
        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
+               return (status);
        }
 
        node = acpi_ns_validate_handle(obj_handle);
@@ -602,17 +602,22 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
 
                        /* Walk the CID list */
 
-                       found = 0;
+                       found = FALSE;
                        for (i = 0; i < cid->count; i++) {
                                if (ACPI_STRCMP(cid->ids[i].string, info->hid)
                                    == 0) {
-                                       found = 1;
+
+                                       /* Found a matching CID */
+
+                                       found = TRUE;
                                        break;
                                }
                        }
+
                        ACPI_FREE(cid);
-                       if (!found)
+                       if (!found) {
                                return (AE_OK);
+                       }
                }
        }
 
index 811c6f1..f3a4d95 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -107,7 +107,7 @@ acpi_get_handle(acpi_handle parent,
         *
         * Error for <null Parent + relative path>
         */
-       if (acpi_ns_valid_root_prefix(pathname[0])) {
+       if (ACPI_IS_ROOT_PREFIX(pathname[0])) {
 
                /* Pathname is fully qualified (starts with '\') */
 
@@ -290,7 +290,7 @@ acpi_get_object_info(acpi_handle handle,
 
        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE(status)) {
-               goto cleanup;
+               return (status);
        }
 
        node = acpi_ns_validate_handle(handle);
@@ -539,14 +539,14 @@ acpi_status acpi_install_method(u8 *buffer)
        /* Parameter validation */
 
        if (!buffer) {
-               return AE_BAD_PARAMETER;
+               return (AE_BAD_PARAMETER);
        }
 
        /* Table must be a DSDT or SSDT */
 
        if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) &&
            !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
-               return AE_BAD_HEADER;
+               return (AE_BAD_HEADER);
        }
 
        /* First AML opcode in the table must be a control method */
@@ -554,7 +554,7 @@ acpi_status acpi_install_method(u8 *buffer)
        parser_state.aml = buffer + sizeof(struct acpi_table_header);
        opcode = acpi_ps_peek_opcode(&parser_state);
        if (opcode != AML_METHOD_OP) {
-               return AE_BAD_PARAMETER;
+               return (AE_BAD_PARAMETER);
        }
 
        /* Extract method information from the raw AML */
@@ -572,13 +572,13 @@ acpi_status acpi_install_method(u8 *buffer)
         */
        aml_buffer = ACPI_ALLOCATE(aml_length);
        if (!aml_buffer) {
-               return AE_NO_MEMORY;
+               return (AE_NO_MEMORY);
        }
 
        method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
        if (!method_obj) {
                ACPI_FREE(aml_buffer);
-               return AE_NO_MEMORY;
+               return (AE_NO_MEMORY);
        }
 
        /* Lock namespace for acpi_ns_lookup, we may be creating a new node */
@@ -644,12 +644,12 @@ acpi_status acpi_install_method(u8 *buffer)
        /* Remove local reference to the method object */
 
        acpi_ut_remove_reference(method_obj);
-       return status;
+       return (status);
 
 error_exit:
 
        ACPI_FREE(aml_buffer);
        ACPI_FREE(method_obj);
-       return status;
+       return (status);
 }
 ACPI_EXPORT_SYMBOL(acpi_install_method)
index 9d029da..c0853ef 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index cb79e2d..f51308c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -108,7 +108,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
        /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
 
        package_length |= (aml[0] & byte_zero_mask);
-       return_UINT32(package_length);
+       return_VALUE(package_length);
 }
 
 /*******************************************************************************
@@ -162,7 +162,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
 
        /* Point past any namestring prefix characters (backslash or carat) */
 
-       while (acpi_ps_is_prefix_char(*end)) {
+       while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
                end++;
        }
 
@@ -798,7 +798,8 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
                subop = acpi_ps_peek_opcode(parser_state);
                if (subop == 0 ||
                    acpi_ps_is_leading_char(subop) ||
-                   acpi_ps_is_prefix_char(subop)) {
+                   ACPI_IS_ROOT_PREFIX(subop) ||
+                   ACPI_IS_PARENT_PREFIX(subop)) {
 
                        /* null_name or name_string */
 
index 5607805..63c4554 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #define _COMPONENT          ACPI_PARSER
 ACPI_MODULE_NAME("psloop")
 
-static u32 acpi_gbl_depth = 0;
-
 /* Local prototypes */
-
-static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
-
-static acpi_status
-acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
-                      u8 * aml_op_start,
-                      union acpi_parse_object *unnamed_op,
-                      union acpi_parse_object **op);
-
-static acpi_status
-acpi_ps_create_op(struct acpi_walk_state *walk_state,
-                 u8 * aml_op_start, union acpi_parse_object **new_op);
-
 static acpi_status
 acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
                      u8 * aml_op_start, union acpi_parse_object *op);
 
-static acpi_status
-acpi_ps_complete_op(struct acpi_walk_state *walk_state,
-                   union acpi_parse_object **op, acpi_status status);
-
-static acpi_status
-acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
-                         union acpi_parse_object *op, acpi_status status);
-
 static void
 acpi_ps_link_module_code(union acpi_parse_object *parent_op,
                         u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ps_get_aml_opcode
- *
- * PARAMETERS:  walk_state          - Current state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Extract the next AML opcode from the input stream.
- *
- ******************************************************************************/
-
-static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
-{
-
-       ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
-
-       walk_state->aml_offset =
-           (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
-                               walk_state->parser_state.aml_start);
-       walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
-
-       /*
-        * First cut to determine what we have found:
-        * 1) A valid AML opcode
-        * 2) A name string
-        * 3) An unknown/invalid opcode
-        */
-       walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
-
-       switch (walk_state->op_info->class) {
-       case AML_CLASS_ASCII:
-       case AML_CLASS_PREFIX:
-               /*
-                * Starts with a valid prefix or ASCII char, this is a name
-                * string. Convert the bare name string to a namepath.
-                */
-               walk_state->opcode = AML_INT_NAMEPATH_OP;
-               walk_state->arg_types = ARGP_NAMESTRING;
-               break;
-
-       case AML_CLASS_UNKNOWN:
-
-               /* The opcode is unrecognized. Complain and skip unknown opcodes */
-
-               if (walk_state->pass_number == 2) {
-                       ACPI_ERROR((AE_INFO,
-                                   "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
-                                   walk_state->opcode,
-                                   (u32)(walk_state->aml_offset +
-                                         sizeof(struct acpi_table_header))));
-
-                       ACPI_DUMP_BUFFER(walk_state->parser_state.aml - 16, 48);
-
-#ifdef ACPI_ASL_COMPILER
-                       /*
-                        * This is executed for the disassembler only. Output goes
-                        * to the disassembled ASL output file.
-                        */
-                       acpi_os_printf
-                           ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
-                            walk_state->opcode,
-                            (u32)(walk_state->aml_offset +
-                                  sizeof(struct acpi_table_header)));
-
-                       /* Dump the context surrounding the invalid opcode */
-
-                       acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
-                                            aml - 16), 48, DB_BYTE_DISPLAY,
-                                           walk_state->aml_offset +
-                                           sizeof(struct acpi_table_header) -
-                                           16);
-                       acpi_os_printf(" */\n");
-#endif
-               }
-
-               /* Increment past one-byte or two-byte opcode */
-
-               walk_state->parser_state.aml++;
-               if (walk_state->opcode > 0xFF) {        /* Can only happen if first byte is 0x5B */
-                       walk_state->parser_state.aml++;
-               }
-
-               return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
-
-       default:
-
-               /* Found opcode info, this is a normal opcode */
-
-               walk_state->parser_state.aml +=
-                   acpi_ps_get_opcode_size(walk_state->opcode);
-               walk_state->arg_types = walk_state->op_info->parse_args;
-               break;
-       }
-
-       return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_build_named_op
- *
- * PARAMETERS:  walk_state          - Current state
- *              aml_op_start        - Begin of named Op in AML
- *              unnamed_op          - Early Op (not a named Op)
- *              op                  - Returned Op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Parse a named Op
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
-                      u8 * aml_op_start,
-                      union acpi_parse_object *unnamed_op,
-                      union acpi_parse_object **op)
-{
-       acpi_status status = AE_OK;
-       union acpi_parse_object *arg = NULL;
-
-       ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
-
-       unnamed_op->common.value.arg = NULL;
-       unnamed_op->common.arg_list_length = 0;
-       unnamed_op->common.aml_opcode = walk_state->opcode;
-
-       /*
-        * Get and append arguments until we find the node that contains
-        * the name (the type ARGP_NAME).
-        */
-       while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
-              (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
-               status =
-                   acpi_ps_get_next_arg(walk_state,
-                                        &(walk_state->parser_state),
-                                        GET_CURRENT_ARG_TYPE(walk_state->
-                                                             arg_types), &arg);
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-
-               acpi_ps_append_arg(unnamed_op, arg);
-               INCREMENT_ARG_LIST(walk_state->arg_types);
-       }
-
-       /*
-        * Make sure that we found a NAME and didn't run out of arguments
-        */
-       if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
-               return_ACPI_STATUS(AE_AML_NO_OPERAND);
-       }
-
-       /* We know that this arg is a name, move to next arg */
-
-       INCREMENT_ARG_LIST(walk_state->arg_types);
-
-       /*
-        * Find the object. This will either insert the object into
-        * the namespace or simply look it up
-        */
-       walk_state->op = NULL;
-
-       status = walk_state->descending_callback(walk_state, op);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
-               return_ACPI_STATUS(status);
-       }
-
-       if (!*op) {
-               return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
-       }
-
-       status = acpi_ps_next_parse_state(walk_state, *op, status);
-       if (ACPI_FAILURE(status)) {
-               if (status == AE_CTRL_PENDING) {
-                       return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
-               }
-               return_ACPI_STATUS(status);
-       }
-
-       acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
-       acpi_gbl_depth++;
-
-       if ((*op)->common.aml_opcode == AML_REGION_OP ||
-           (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
-               /*
-                * Defer final parsing of an operation_region body, because we don't
-                * have enough info in the first pass to parse it correctly (i.e.,
-                * there may be method calls within the term_arg elements of the body.)
-                *
-                * However, we must continue parsing because the opregion is not a
-                * standalone package -- we don't know where the end is at this point.
-                *
-                * (Length is unknown until parse of the body complete)
-                */
-               (*op)->named.data = aml_op_start;
-               (*op)->named.length = 0;
-       }
-
-       return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_create_op
- *
- * PARAMETERS:  walk_state          - Current state
- *              aml_op_start        - Op start in AML
- *              new_op              - Returned Op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Get Op from AML
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ps_create_op(struct acpi_walk_state *walk_state,
-                 u8 * aml_op_start, union acpi_parse_object **new_op)
-{
-       acpi_status status = AE_OK;
-       union acpi_parse_object *op;
-       union acpi_parse_object *named_op = NULL;
-       union acpi_parse_object *parent_scope;
-       u8 argument_count;
-       const struct acpi_opcode_info *op_info;
-
-       ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
-
-       status = acpi_ps_get_aml_opcode(walk_state);
-       if (status == AE_CTRL_PARSE_CONTINUE) {
-               return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
-       }
-
-       /* Create Op structure and append to parent's argument list */
-
-       walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
-       op = acpi_ps_alloc_op(walk_state->opcode);
-       if (!op) {
-               return_ACPI_STATUS(AE_NO_MEMORY);
-       }
-
-       if (walk_state->op_info->flags & AML_NAMED) {
-               status =
-                   acpi_ps_build_named_op(walk_state, aml_op_start, op,
-                                          &named_op);
-               acpi_ps_free_op(op);
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-
-               *new_op = named_op;
-               return_ACPI_STATUS(AE_OK);
-       }
-
-       /* Not a named opcode, just allocate Op and append to parent */
-
-       if (walk_state->op_info->flags & AML_CREATE) {
-               /*
-                * Backup to beginning of create_XXXfield declaration
-                * body_length is unknown until we parse the body
-                */
-               op->named.data = aml_op_start;
-               op->named.length = 0;
-       }
-
-       if (walk_state->opcode == AML_BANK_FIELD_OP) {
-               /*
-                * Backup to beginning of bank_field declaration
-                * body_length is unknown until we parse the body
-                */
-               op->named.data = aml_op_start;
-               op->named.length = 0;
-       }
-
-       parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
-       acpi_ps_append_arg(parent_scope, op);
-
-       if (parent_scope) {
-               op_info =
-                   acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
-               if (op_info->flags & AML_HAS_TARGET) {
-                       argument_count =
-                           acpi_ps_get_argument_count(op_info->type);
-                       if (parent_scope->common.arg_list_length >
-                           argument_count) {
-                               op->common.flags |= ACPI_PARSEOP_TARGET;
-                       }
-               } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
-                       op->common.flags |= ACPI_PARSEOP_TARGET;
-               }
-       }
-
-       if (walk_state->descending_callback != NULL) {
-               /*
-                * Find the object. This will either insert the object into
-                * the namespace or simply look it up
-                */
-               walk_state->op = *new_op = op;
-
-               status = walk_state->descending_callback(walk_state, &op);
-               status = acpi_ps_next_parse_state(walk_state, op, status);
-               if (status == AE_CTRL_PENDING) {
-                       status = AE_CTRL_PARSE_PENDING;
-               }
-       }
-
-       return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ps_get_arguments
  *
  * PARAMETERS:  walk_state          - Current state
@@ -711,288 +376,6 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op,
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ps_complete_op
- *
- * PARAMETERS:  walk_state          - Current state
- *              op                  - Returned Op
- *              status              - Parse status before complete Op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Complete Op
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ps_complete_op(struct acpi_walk_state *walk_state,
-                   union acpi_parse_object **op, acpi_status status)
-{
-       acpi_status status2;
-
-       ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
-
-       /*
-        * Finished one argument of the containing scope
-        */
-       walk_state->parser_state.scope->parse_scope.arg_count--;
-
-       /* Close this Op (will result in parse subtree deletion) */
-
-       status2 = acpi_ps_complete_this_op(walk_state, *op);
-       if (ACPI_FAILURE(status2)) {
-               return_ACPI_STATUS(status2);
-       }
-
-       *op = NULL;
-
-       switch (status) {
-       case AE_OK:
-               break;
-
-       case AE_CTRL_TRANSFER:
-
-               /* We are about to transfer to a called method */
-
-               walk_state->prev_op = NULL;
-               walk_state->prev_arg_types = walk_state->arg_types;
-               return_ACPI_STATUS(status);
-
-       case AE_CTRL_END:
-
-               acpi_ps_pop_scope(&(walk_state->parser_state), op,
-                                 &walk_state->arg_types,
-                                 &walk_state->arg_count);
-
-               if (*op) {
-                       walk_state->op = *op;
-                       walk_state->op_info =
-                           acpi_ps_get_opcode_info((*op)->common.aml_opcode);
-                       walk_state->opcode = (*op)->common.aml_opcode;
-
-                       status = walk_state->ascending_callback(walk_state);
-                       status =
-                           acpi_ps_next_parse_state(walk_state, *op, status);
-
-                       status2 = acpi_ps_complete_this_op(walk_state, *op);
-                       if (ACPI_FAILURE(status2)) {
-                               return_ACPI_STATUS(status2);
-                       }
-               }
-
-               status = AE_OK;
-               break;
-
-       case AE_CTRL_BREAK:
-       case AE_CTRL_CONTINUE:
-
-               /* Pop off scopes until we find the While */
-
-               while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
-                       acpi_ps_pop_scope(&(walk_state->parser_state), op,
-                                         &walk_state->arg_types,
-                                         &walk_state->arg_count);
-               }
-
-               /* Close this iteration of the While loop */
-
-               walk_state->op = *op;
-               walk_state->op_info =
-                   acpi_ps_get_opcode_info((*op)->common.aml_opcode);
-               walk_state->opcode = (*op)->common.aml_opcode;
-
-               status = walk_state->ascending_callback(walk_state);
-               status = acpi_ps_next_parse_state(walk_state, *op, status);
-
-               status2 = acpi_ps_complete_this_op(walk_state, *op);
-               if (ACPI_FAILURE(status2)) {
-                       return_ACPI_STATUS(status2);
-               }
-
-               status = AE_OK;
-               break;
-
-       case AE_CTRL_TERMINATE:
-
-               /* Clean up */
-               do {
-                       if (*op) {
-                               status2 =
-                                   acpi_ps_complete_this_op(walk_state, *op);
-                               if (ACPI_FAILURE(status2)) {
-                                       return_ACPI_STATUS(status2);
-                               }
-
-                               acpi_ut_delete_generic_state
-                                   (acpi_ut_pop_generic_state
-                                    (&walk_state->control_state));
-                       }
-
-                       acpi_ps_pop_scope(&(walk_state->parser_state), op,
-                                         &walk_state->arg_types,
-                                         &walk_state->arg_count);
-
-               } while (*op);
-
-               return_ACPI_STATUS(AE_OK);
-
-       default:                /* All other non-AE_OK status */
-
-               do {
-                       if (*op) {
-                               status2 =
-                                   acpi_ps_complete_this_op(walk_state, *op);
-                               if (ACPI_FAILURE(status2)) {
-                                       return_ACPI_STATUS(status2);
-                               }
-                       }
-
-                       acpi_ps_pop_scope(&(walk_state->parser_state), op,
-                                         &walk_state->arg_types,
-                                         &walk_state->arg_count);
-
-               } while (*op);
-
-#if 0
-               /*
-                * TBD: Cleanup parse ops on error
-                */
-               if (*op == NULL) {
-                       acpi_ps_pop_scope(parser_state, op,
-                                         &walk_state->arg_types,
-                                         &walk_state->arg_count);
-               }
-#endif
-               walk_state->prev_op = NULL;
-               walk_state->prev_arg_types = walk_state->arg_types;
-               return_ACPI_STATUS(status);
-       }
-
-       /* This scope complete? */
-
-       if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
-               acpi_ps_pop_scope(&(walk_state->parser_state), op,
-                                 &walk_state->arg_types,
-                                 &walk_state->arg_count);
-               ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
-       } else {
-               *op = NULL;
-       }
-
-       return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_complete_final_op
- *
- * PARAMETERS:  walk_state          - Current state
- *              op                  - Current Op
- *              status              - Current parse status before complete last
- *                                    Op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Complete last Op.
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
-                         union acpi_parse_object *op, acpi_status status)
-{
-       acpi_status status2;
-
-       ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
-
-       /*
-        * Complete the last Op (if not completed), and clear the scope stack.
-        * It is easily possible to end an AML "package" with an unbounded number
-        * of open scopes (such as when several ASL blocks are closed with
-        * sequential closing braces). We want to terminate each one cleanly.
-        */
-       ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
-                         op));
-       do {
-               if (op) {
-                       if (walk_state->ascending_callback != NULL) {
-                               walk_state->op = op;
-                               walk_state->op_info =
-                                   acpi_ps_get_opcode_info(op->common.
-                                                           aml_opcode);
-                               walk_state->opcode = op->common.aml_opcode;
-
-                               status =
-                                   walk_state->ascending_callback(walk_state);
-                               status =
-                                   acpi_ps_next_parse_state(walk_state, op,
-                                                            status);
-                               if (status == AE_CTRL_PENDING) {
-                                       status =
-                                           acpi_ps_complete_op(walk_state, &op,
-                                                               AE_OK);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);
-                                       }
-                               }
-
-                               if (status == AE_CTRL_TERMINATE) {
-                                       status = AE_OK;
-
-                                       /* Clean up */
-                                       do {
-                                               if (op) {
-                                                       status2 =
-                                                           acpi_ps_complete_this_op
-                                                           (walk_state, op);
-                                                       if (ACPI_FAILURE
-                                                           (status2)) {
-                                                               return_ACPI_STATUS
-                                                                   (status2);
-                                                       }
-                                               }
-
-                                               acpi_ps_pop_scope(&
-                                                                 (walk_state->
-                                                                  parser_state),
-                                                                 &op,
-                                                                 &walk_state->
-                                                                 arg_types,
-                                                                 &walk_state->
-                                                                 arg_count);
-
-                                       } while (op);
-
-                                       return_ACPI_STATUS(status);
-                               }
-
-                               else if (ACPI_FAILURE(status)) {
-
-                                       /* First error is most important */
-
-                                       (void)
-                                           acpi_ps_complete_this_op(walk_state,
-                                                                    op);
-                                       return_ACPI_STATUS(status);
-                               }
-                       }
-
-                       status2 = acpi_ps_complete_this_op(walk_state, op);
-                       if (ACPI_FAILURE(status2)) {
-                               return_ACPI_STATUS(status2);
-                       }
-               }
-
-               acpi_ps_pop_scope(&(walk_state->parser_state), &op,
-                                 &walk_state->arg_types,
-                                 &walk_state->arg_count);
-
-       } while (op);
-
-       return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ps_parse_loop
  *
  * PARAMETERS:  walk_state          - Current state
@@ -1177,10 +560,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
                walk_state->op_info =
                    acpi_ps_get_opcode_info(op->common.aml_opcode);
                if (walk_state->op_info->flags & AML_NAMED) {
-                       if (acpi_gbl_depth) {
-                               acpi_gbl_depth--;
-                       }
-
                        if (op->common.aml_opcode == AML_REGION_OP ||
                            op->common.aml_opcode == AML_DATA_REGION_OP) {
                                /*
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
new file mode 100644 (file)
index 0000000..12c4028
--- /dev/null
@@ -0,0 +1,647 @@
+/******************************************************************************
+ *
+ * Module Name: psobject - Support for parse objects
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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 "acparser.h"
+#include "amlcode.h"
+
+#define _COMPONENT          ACPI_PARSER
+ACPI_MODULE_NAME("psobject")
+
+/* Local prototypes */
+static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_aml_opcode
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Extract the next AML opcode from the input stream.
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
+{
+
+       ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
+
+       walk_state->aml_offset =
+           (u32)ACPI_PTR_DIFF(walk_state->parser_state.aml,
+                              walk_state->parser_state.aml_start);
+       walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
+
+       /*
+        * First cut to determine what we have found:
+        * 1) A valid AML opcode
+        * 2) A name string
+        * 3) An unknown/invalid opcode
+        */
+       walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
+
+       switch (walk_state->op_info->class) {
+       case AML_CLASS_ASCII:
+       case AML_CLASS_PREFIX:
+               /*
+                * Starts with a valid prefix or ASCII char, this is a name
+                * string. Convert the bare name string to a namepath.
+                */
+               walk_state->opcode = AML_INT_NAMEPATH_OP;
+               walk_state->arg_types = ARGP_NAMESTRING;
+               break;
+
+       case AML_CLASS_UNKNOWN:
+
+               /* The opcode is unrecognized. Complain and skip unknown opcodes */
+
+               if (walk_state->pass_number == 2) {
+                       ACPI_ERROR((AE_INFO,
+                                   "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
+                                   walk_state->opcode,
+                                   (u32)(walk_state->aml_offset +
+                                         sizeof(struct acpi_table_header))));
+
+                       ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
+                                        48);
+
+#ifdef ACPI_ASL_COMPILER
+                       /*
+                        * This is executed for the disassembler only. Output goes
+                        * to the disassembled ASL output file.
+                        */
+                       acpi_os_printf
+                           ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
+                            walk_state->opcode,
+                            (u32)(walk_state->aml_offset +
+                                  sizeof(struct acpi_table_header)));
+
+                       /* Dump the context surrounding the invalid opcode */
+
+                       acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
+                                            aml - 16), 48, DB_BYTE_DISPLAY,
+                                           (walk_state->aml_offset +
+                                            sizeof(struct acpi_table_header) -
+                                            16));
+                       acpi_os_printf(" */\n");
+#endif
+               }
+
+               /* Increment past one-byte or two-byte opcode */
+
+               walk_state->parser_state.aml++;
+               if (walk_state->opcode > 0xFF) {        /* Can only happen if first byte is 0x5B */
+                       walk_state->parser_state.aml++;
+               }
+
+               return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
+
+       default:
+
+               /* Found opcode info, this is a normal opcode */
+
+               walk_state->parser_state.aml +=
+                   acpi_ps_get_opcode_size(walk_state->opcode);
+               walk_state->arg_types = walk_state->op_info->parse_args;
+               break;
+       }
+
+       return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_build_named_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              aml_op_start        - Begin of named Op in AML
+ *              unnamed_op          - Early Op (not a named Op)
+ *              op                  - Returned Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse a named Op
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
+                      u8 *aml_op_start,
+                      union acpi_parse_object *unnamed_op,
+                      union acpi_parse_object **op)
+{
+       acpi_status status = AE_OK;
+       union acpi_parse_object *arg = NULL;
+
+       ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
+
+       unnamed_op->common.value.arg = NULL;
+       unnamed_op->common.arg_list_length = 0;
+       unnamed_op->common.aml_opcode = walk_state->opcode;
+
+       /*
+        * Get and append arguments until we find the node that contains
+        * the name (the type ARGP_NAME).
+        */
+       while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
+              (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
+               status =
+                   acpi_ps_get_next_arg(walk_state,
+                                        &(walk_state->parser_state),
+                                        GET_CURRENT_ARG_TYPE(walk_state->
+                                                             arg_types), &arg);
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+
+               acpi_ps_append_arg(unnamed_op, arg);
+               INCREMENT_ARG_LIST(walk_state->arg_types);
+       }
+
+       /*
+        * Make sure that we found a NAME and didn't run out of arguments
+        */
+       if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
+               return_ACPI_STATUS(AE_AML_NO_OPERAND);
+       }
+
+       /* We know that this arg is a name, move to next arg */
+
+       INCREMENT_ARG_LIST(walk_state->arg_types);
+
+       /*
+        * Find the object. This will either insert the object into
+        * the namespace or simply look it up
+        */
+       walk_state->op = NULL;
+
+       status = walk_state->descending_callback(walk_state, op);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
+               return_ACPI_STATUS(status);
+       }
+
+       if (!*op) {
+               return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
+       }
+
+       status = acpi_ps_next_parse_state(walk_state, *op, status);
+       if (ACPI_FAILURE(status)) {
+               if (status == AE_CTRL_PENDING) {
+                       return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
+               }
+               return_ACPI_STATUS(status);
+       }
+
+       acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
+
+       if ((*op)->common.aml_opcode == AML_REGION_OP ||
+           (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
+               /*
+                * Defer final parsing of an operation_region body, because we don't
+                * have enough info in the first pass to parse it correctly (i.e.,
+                * there may be method calls within the term_arg elements of the body.)
+                *
+                * However, we must continue parsing because the opregion is not a
+                * standalone package -- we don't know where the end is at this point.
+                *
+                * (Length is unknown until parse of the body complete)
+                */
+               (*op)->named.data = aml_op_start;
+               (*op)->named.length = 0;
+       }
+
+       return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_create_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              aml_op_start        - Op start in AML
+ *              new_op              - Returned Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get Op from AML
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_create_op(struct acpi_walk_state *walk_state,
+                 u8 *aml_op_start, union acpi_parse_object **new_op)
+{
+       acpi_status status = AE_OK;
+       union acpi_parse_object *op;
+       union acpi_parse_object *named_op = NULL;
+       union acpi_parse_object *parent_scope;
+       u8 argument_count;
+       const struct acpi_opcode_info *op_info;
+
+       ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
+
+       status = acpi_ps_get_aml_opcode(walk_state);
+       if (status == AE_CTRL_PARSE_CONTINUE) {
+               return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
+       }
+
+       /* Create Op structure and append to parent's argument list */
+
+       walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
+       op = acpi_ps_alloc_op(walk_state->opcode);
+       if (!op) {
+               return_ACPI_STATUS(AE_NO_MEMORY);
+       }
+
+       if (walk_state->op_info->flags & AML_NAMED) {
+               status =
+                   acpi_ps_build_named_op(walk_state, aml_op_start, op,
+                                          &named_op);
+               acpi_ps_free_op(op);
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+
+               *new_op = named_op;
+               return_ACPI_STATUS(AE_OK);
+       }
+
+       /* Not a named opcode, just allocate Op and append to parent */
+
+       if (walk_state->op_info->flags & AML_CREATE) {
+               /*
+                * Backup to beginning of create_XXXfield declaration
+                * body_length is unknown until we parse the body
+                */
+               op->named.data = aml_op_start;
+               op->named.length = 0;
+       }
+
+       if (walk_state->opcode == AML_BANK_FIELD_OP) {
+               /*
+                * Backup to beginning of bank_field declaration
+                * body_length is unknown until we parse the body
+                */
+               op->named.data = aml_op_start;
+               op->named.length = 0;
+       }
+
+       parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
+       acpi_ps_append_arg(parent_scope, op);
+
+       if (parent_scope) {
+               op_info =
+                   acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
+               if (op_info->flags & AML_HAS_TARGET) {
+                       argument_count =
+                           acpi_ps_get_argument_count(op_info->type);
+                       if (parent_scope->common.arg_list_length >
+                           argument_count) {
+                               op->common.flags |= ACPI_PARSEOP_TARGET;
+                       }
+               } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
+                       op->common.flags |= ACPI_PARSEOP_TARGET;
+               }
+       }
+
+       if (walk_state->descending_callback != NULL) {
+               /*
+                * Find the object. This will either insert the object into
+                * the namespace or simply look it up
+                */
+               walk_state->op = *new_op = op;
+
+               status = walk_state->descending_callback(walk_state, &op);
+               status = acpi_ps_next_parse_state(walk_state, op, status);
+               if (status == AE_CTRL_PENDING) {
+                       status = AE_CTRL_PARSE_PENDING;
+               }
+       }
+
+       return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_complete_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              op                  - Returned Op
+ *              status              - Parse status before complete Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Complete Op
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_complete_op(struct acpi_walk_state *walk_state,
+                   union acpi_parse_object **op, acpi_status status)
+{
+       acpi_status status2;
+
+       ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
+
+       /*
+        * Finished one argument of the containing scope
+        */
+       walk_state->parser_state.scope->parse_scope.arg_count--;
+
+       /* Close this Op (will result in parse subtree deletion) */
+
+       status2 = acpi_ps_complete_this_op(walk_state, *op);
+       if (ACPI_FAILURE(status2)) {
+               return_ACPI_STATUS(status2);
+       }
+
+       *op = NULL;
+
+       switch (status) {
+       case AE_OK:
+               break;
+
+       case AE_CTRL_TRANSFER:
+
+               /* We are about to transfer to a called method */
+
+               walk_state->prev_op = NULL;
+               walk_state->prev_arg_types = walk_state->arg_types;
+               return_ACPI_STATUS(status);
+
+       case AE_CTRL_END:
+
+               acpi_ps_pop_scope(&(walk_state->parser_state), op,
+                                 &walk_state->arg_types,
+                                 &walk_state->arg_count);
+
+               if (*op) {
+                       walk_state->op = *op;
+                       walk_state->op_info =
+                           acpi_ps_get_opcode_info((*op)->common.aml_opcode);
+                       walk_state->opcode = (*op)->common.aml_opcode;
+
+                       status = walk_state->ascending_callback(walk_state);
+                       status =
+                           acpi_ps_next_parse_state(walk_state, *op, status);
+
+                       status2 = acpi_ps_complete_this_op(walk_state, *op);
+                       if (ACPI_FAILURE(status2)) {
+                               return_ACPI_STATUS(status2);
+                       }
+               }
+
+               status = AE_OK;
+               break;
+
+       case AE_CTRL_BREAK:
+       case AE_CTRL_CONTINUE:
+
+               /* Pop off scopes until we find the While */
+
+               while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
+                       acpi_ps_pop_scope(&(walk_state->parser_state), op,
+                                         &walk_state->arg_types,
+                                         &walk_state->arg_count);
+               }
+
+               /* Close this iteration of the While loop */
+
+               walk_state->op = *op;
+               walk_state->op_info =
+                   acpi_ps_get_opcode_info((*op)->common.aml_opcode);
+               walk_state->opcode = (*op)->common.aml_opcode;
+
+               status = walk_state->ascending_callback(walk_state);
+               status = acpi_ps_next_parse_state(walk_state, *op, status);
+
+               status2 = acpi_ps_complete_this_op(walk_state, *op);
+               if (ACPI_FAILURE(status2)) {
+                       return_ACPI_STATUS(status2);
+               }
+
+               status = AE_OK;
+               break;
+
+       case AE_CTRL_TERMINATE:
+
+               /* Clean up */
+               do {
+                       if (*op) {
+                               status2 =
+                                   acpi_ps_complete_this_op(walk_state, *op);
+                               if (ACPI_FAILURE(status2)) {
+                                       return_ACPI_STATUS(status2);
+                               }
+
+                               acpi_ut_delete_generic_state
+                                   (acpi_ut_pop_generic_state
+                                    (&walk_state->control_state));
+                       }
+
+                       acpi_ps_pop_scope(&(walk_state->parser_state), op,
+                                         &walk_state->arg_types,
+                                         &walk_state->arg_count);
+
+               } while (*op);
+
+               return_ACPI_STATUS(AE_OK);
+
+       default:                /* All other non-AE_OK status */
+
+               do {
+                       if (*op) {
+                               status2 =
+                                   acpi_ps_complete_this_op(walk_state, *op);
+                               if (ACPI_FAILURE(status2)) {
+                                       return_ACPI_STATUS(status2);
+                               }
+                       }
+
+                       acpi_ps_pop_scope(&(walk_state->parser_state), op,
+                                         &walk_state->arg_types,
+                                         &walk_state->arg_count);
+
+               } while (*op);
+
+#if 0
+               /*
+                * TBD: Cleanup parse ops on error
+                */
+               if (*op == NULL) {
+                       acpi_ps_pop_scope(parser_state, op,
+                                         &walk_state->arg_types,
+                                         &walk_state->arg_count);
+               }
+#endif
+               walk_state->prev_op = NULL;
+               walk_state->prev_arg_types = walk_state->arg_types;
+               return_ACPI_STATUS(status);
+       }
+
+       /* This scope complete? */
+
+       if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
+               acpi_ps_pop_scope(&(walk_state->parser_state), op,
+                                 &walk_state->arg_types,
+                                 &walk_state->arg_count);
+               ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
+       } else {
+               *op = NULL;
+       }
+
+       return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_complete_final_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              op                  - Current Op
+ *              status              - Current parse status before complete last
+ *                                    Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Complete last Op.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
+                         union acpi_parse_object *op, acpi_status status)
+{
+       acpi_status status2;
+
+       ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
+
+       /*
+        * Complete the last Op (if not completed), and clear the scope stack.
+        * It is easily possible to end an AML "package" with an unbounded number
+        * of open scopes (such as when several ASL blocks are closed with
+        * sequential closing braces). We want to terminate each one cleanly.
+        */
+       ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
+                         op));
+       do {
+               if (op) {
+                       if (walk_state->ascending_callback != NULL) {
+                               walk_state->op = op;
+                               walk_state->op_info =
+                                   acpi_ps_get_opcode_info(op->common.
+                                                           aml_opcode);
+                               walk_state->opcode = op->common.aml_opcode;
+
+                               status =
+                                   walk_state->ascending_callback(walk_state);
+                               status =
+                                   acpi_ps_next_parse_state(walk_state, op,
+                                                            status);
+                               if (status == AE_CTRL_PENDING) {
+                                       status =
+                                           acpi_ps_complete_op(walk_state, &op,
+                                                               AE_OK);
+                                       if (ACPI_FAILURE(status)) {
+                                               return_ACPI_STATUS(status);
+                                       }
+                               }
+
+                               if (status == AE_CTRL_TERMINATE) {
+                                       status = AE_OK;
+
+                                       /* Clean up */
+                                       do {
+                                               if (op) {
+                                                       status2 =
+                                                           acpi_ps_complete_this_op
+                                                           (walk_state, op);
+                                                       if (ACPI_FAILURE
+                                                           (status2)) {
+                                                               return_ACPI_STATUS
+                                                                   (status2);
+                                                       }
+                                               }
+
+                                               acpi_ps_pop_scope(&
+                                                                 (walk_state->
+                                                                  parser_state),
+                                                                 &op,
+                                                                 &walk_state->
+                                                                 arg_types,
+                                                                 &walk_state->
+                                                                 arg_count);
+
+                                       } while (op);
+
+                                       return_ACPI_STATUS(status);
+                               }
+
+                               else if (ACPI_FAILURE(status)) {
+
+                                       /* First error is most important */
+
+                                       (void)
+                                           acpi_ps_complete_this_op(walk_state,
+                                                                    op);
+                                       return_ACPI_STATUS(status);
+                               }
+                       }
+
+                       status2 = acpi_ps_complete_this_op(walk_state, op);
+                       if (ACPI_FAILURE(status2)) {
+                               return_ACPI_STATUS(status2);
+                       }
+               }
+
+               acpi_ps_pop_scope(&(walk_state->parser_state), &op,
+                                 &walk_state->arg_types,
+                                 &walk_state->arg_count);
+
+       } while (op);
+
+       return_ACPI_STATUS(status);
+}
index 1793d93..1b659e5 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "acparser.h"
 #include "acopcode.h"
 #include "amlcode.h"
 
 #define _COMPONENT          ACPI_PARSER
 ACPI_MODULE_NAME("psopcode")
 
-static const u8 acpi_gbl_argument_count[] =
-    { 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 };
-
 /*******************************************************************************
  *
  * NAME:        acpi_gbl_aml_op_info
@@ -63,7 +59,6 @@ static const u8 acpi_gbl_argument_count[] =
  *              the operand type.
  *
  ******************************************************************************/
-
 /*
  * Summary of opcode types/flags
  *
@@ -181,7 +176,6 @@ static const u8 acpi_gbl_argument_count[] =
        AML_CREATE_QWORD_FIELD_OP
 
  ******************************************************************************/
-
 /*
  * Master Opcode information table. A summary of everything we know about each
  * opcode, all in one place.
@@ -656,169 +650,3 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
 
 /*! [End] no source code translation !*/
 };
-
-/*
- * This table is directly indexed by the opcodes, and returns an
- * index into the table above
- */
-static const u8 acpi_gbl_short_op_index[256] = {
-/*              0     1     2     3     4     5     6     7  */
-/*              8     9     A     B     C     D     E     F  */
-/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
-/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
-/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
-/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
-/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
-/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
-/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
-/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
-/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
-/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
-/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
-/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
-/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
-/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
-/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
-/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
-/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
-/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
-};
-
-/*
- * This table is indexed by the second opcode of the extended opcode
- * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
- */
-static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = {
-/*              0     1     2     3     4     5     6     7  */
-/*              8     9     A     B     C     D     E     F  */
-/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
-/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
-/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
-/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
-/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-/* 0x88 */ 0x7C,
-};
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_get_opcode_info
- *
- * PARAMETERS:  opcode              - The AML opcode
- *
- * RETURN:      A pointer to the info about the opcode.
- *
- * DESCRIPTION: Find AML opcode description based on the opcode.
- *              NOTE: This procedure must ALWAYS return a valid pointer!
- *
- ******************************************************************************/
-
-const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode)
-{
-       ACPI_FUNCTION_NAME(ps_get_opcode_info);
-
-       /*
-        * Detect normal 8-bit opcode or extended 16-bit opcode
-        */
-       if (!(opcode & 0xFF00)) {
-
-               /* Simple (8-bit) opcode: 0-255, can't index beyond table  */
-
-               return (&acpi_gbl_aml_op_info
-                       [acpi_gbl_short_op_index[(u8) opcode]]);
-       }
-
-       if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
-           (((u8) opcode) <= MAX_EXTENDED_OPCODE)) {
-
-               /* Valid extended (16-bit) opcode */
-
-               return (&acpi_gbl_aml_op_info
-                       [acpi_gbl_long_op_index[(u8) opcode]]);
-       }
-
-       /* Unknown AML opcode */
-
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                         "Unknown AML opcode [%4.4X]\n", opcode));
-
-       return (&acpi_gbl_aml_op_info[_UNK]);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_get_opcode_name
- *
- * PARAMETERS:  opcode              - The AML opcode
- *
- * RETURN:      A pointer to the name of the opcode (ASCII String)
- *              Note: Never returns NULL.
- *
- * DESCRIPTION: Translate an opcode into a human-readable string
- *
- ******************************************************************************/
-
-char *acpi_ps_get_opcode_name(u16 opcode)
-{
-#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
-
-       const struct acpi_opcode_info *op;
-
-       op = acpi_ps_get_opcode_info(opcode);
-
-       /* Always guaranteed to return a valid pointer */
-
-       return (op->name);
-
-#else
-       return ("OpcodeName unavailable");
-
-#endif
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_get_argument_count
- *
- * PARAMETERS:  op_type             - Type associated with the AML opcode
- *
- * RETURN:      Argument count
- *
- * DESCRIPTION: Obtain the number of expected arguments for an AML opcode
- *
- ******************************************************************************/
-
-u8 acpi_ps_get_argument_count(u32 op_type)
-{
-
-       if (op_type <= AML_TYPE_EXEC_6A_0T_1R) {
-               return (acpi_gbl_argument_count[op_type]);
-       }
-
-       return (0);
-}
diff --git a/drivers/acpi/acpica/psopinfo.c b/drivers/acpi/acpica/psopinfo.c
new file mode 100644 (file)
index 0000000..9ba5301
--- /dev/null
@@ -0,0 +1,223 @@
+/******************************************************************************
+ *
+ * Module Name: psopinfo - AML opcode information functions and dispatch tables
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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 "acparser.h"
+#include "acopcode.h"
+#include "amlcode.h"
+
+#define _COMPONENT          ACPI_PARSER
+ACPI_MODULE_NAME("psopinfo")
+
+extern const u8 acpi_gbl_short_op_index[];
+extern const u8 acpi_gbl_long_op_index[];
+
+static const u8 acpi_gbl_argument_count[] =
+    { 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 };
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_opcode_info
+ *
+ * PARAMETERS:  opcode              - The AML opcode
+ *
+ * RETURN:      A pointer to the info about the opcode.
+ *
+ * DESCRIPTION: Find AML opcode description based on the opcode.
+ *              NOTE: This procedure must ALWAYS return a valid pointer!
+ *
+ ******************************************************************************/
+
+const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode)
+{
+       ACPI_FUNCTION_NAME(ps_get_opcode_info);
+
+       /*
+        * Detect normal 8-bit opcode or extended 16-bit opcode
+        */
+       if (!(opcode & 0xFF00)) {
+
+               /* Simple (8-bit) opcode: 0-255, can't index beyond table  */
+
+               return (&acpi_gbl_aml_op_info
+                       [acpi_gbl_short_op_index[(u8)opcode]]);
+       }
+
+       if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
+           (((u8)opcode) <= MAX_EXTENDED_OPCODE)) {
+
+               /* Valid extended (16-bit) opcode */
+
+               return (&acpi_gbl_aml_op_info
+                       [acpi_gbl_long_op_index[(u8)opcode]]);
+       }
+
+       /* Unknown AML opcode */
+
+       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                         "Unknown AML opcode [%4.4X]\n", opcode));
+
+       return (&acpi_gbl_aml_op_info[_UNK]);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_opcode_name
+ *
+ * PARAMETERS:  opcode              - The AML opcode
+ *
+ * RETURN:      A pointer to the name of the opcode (ASCII String)
+ *              Note: Never returns NULL.
+ *
+ * DESCRIPTION: Translate an opcode into a human-readable string
+ *
+ ******************************************************************************/
+
+char *acpi_ps_get_opcode_name(u16 opcode)
+{
+#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
+
+       const struct acpi_opcode_info *op;
+
+       op = acpi_ps_get_opcode_info(opcode);
+
+       /* Always guaranteed to return a valid pointer */
+
+       return (op->name);
+
+#else
+       return ("OpcodeName unavailable");
+
+#endif
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_argument_count
+ *
+ * PARAMETERS:  op_type             - Type associated with the AML opcode
+ *
+ * RETURN:      Argument count
+ *
+ * DESCRIPTION: Obtain the number of expected arguments for an AML opcode
+ *
+ ******************************************************************************/
+
+u8 acpi_ps_get_argument_count(u32 op_type)
+{
+
+       if (op_type <= AML_TYPE_EXEC_6A_0T_1R) {
+               return (acpi_gbl_argument_count[op_type]);
+       }
+
+       return (0);
+}
+
+/*
+ * This table is directly indexed by the opcodes It returns
+ * an index into the opcode table (acpi_gbl_aml_op_info)
+ */
+const u8 acpi_gbl_short_op_index[256] = {
+/*              0     1     2     3     4     5     6     7  */
+/*              8     9     A     B     C     D     E     F  */
+/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
+/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
+/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
+/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
+/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
+/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
+/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
+/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
+/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
+/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
+/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
+/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
+/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
+/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
+};
+
+/*
+ * This table is indexed by the second opcode of the extended opcode
+ * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
+ */
+const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = {
+/*              0     1     2     3     4     5     6     7  */
+/*              8     9     A     B     C     D     E     F  */
+/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
+/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
+/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+/* 0x88 */ 0x7C,
+};
index 2494caf..abc4c48 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 608dc20..6a4b6fb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index fdb2e71..c1934bf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 4137dcb..91fa73a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -202,14 +202,6 @@ u8 acpi_ps_is_leading_char(u32 c)
 }
 
 /*
- * Is "c" a namestring prefix character?
- */
-u8 acpi_ps_is_prefix_char(u32 c)
-{
-       return ((u8) (c == '\\' || c == '^'));
-}
-
-/*
  * Get op's name (4-byte name segment) or 0 if unnamed
  */
 #ifdef ACPI_FUTURE_USAGE
index ab96cf4..abd6562 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 963e162..f682542 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 856ff07..f3a9276 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 147feb6..7816d4e 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -84,7 +84,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field)
                bit_field &= (u16) (bit_field - 1);
        }
 
-       return bits_set;
+       return (bits_set);
 }
 
 /*******************************************************************************
@@ -407,7 +407,9 @@ acpi_rs_get_list_length(u8 * aml_buffer,
 
                /* Validate the Resource Type and Resource Length */
 
-               status = acpi_ut_validate_resource(aml_buffer, &resource_index);
+               status =
+                   acpi_ut_validate_resource(NULL, aml_buffer,
+                                             &resource_index);
                if (ACPI_FAILURE(status)) {
                        /*
                         * Exit on failure. Cannot continue because the descriptor length
index 311cbc4..f8b55b4 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -98,7 +98,7 @@ acpi_buffer_to_resource(u8 *aml_buffer,
 
        /* Perform the AML-to-Resource conversion */
 
-       status = acpi_ut_walk_aml_resources(aml_buffer, aml_buffer_length,
+       status = acpi_ut_walk_aml_resources(NULL, aml_buffer, aml_buffer_length,
                                            acpi_rs_convert_aml_to_resources,
                                            &current_resource_ptr);
        if (status == AE_AML_NO_RESOURCE_END_TAG) {
@@ -174,7 +174,7 @@ acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
        /* Do the conversion */
 
        resource = output_buffer->pointer;
-       status = acpi_ut_walk_aml_resources(aml_start, aml_buffer_length,
+       status = acpi_ut_walk_aml_resources(NULL, aml_start, aml_buffer_length,
                                            acpi_rs_convert_aml_to_resources,
                                            &resource);
        if (ACPI_FAILURE(status)) {
@@ -480,8 +480,7 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
        status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed);
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
-                         (u32) aml_size_needed,
-                         acpi_format_exception(status)));
+                         (u32)aml_size_needed, acpi_format_exception(status)));
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
index 4d11b07..cab5144 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -77,419 +77,16 @@ static void acpi_rs_dump_address_common(union acpi_resource_data *resource);
 static void
 acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
 
-#define ACPI_RSD_OFFSET(f)          (u8) ACPI_OFFSET (union acpi_resource_data,f)
-#define ACPI_PRT_OFFSET(f)          (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f)
-#define ACPI_RSD_TABLE_SIZE(name)   (sizeof(name) / sizeof (struct acpi_rsdump_info))
-
-/*******************************************************************************
- *
- * Resource Descriptor info tables
- *
- * Note: The first table entry must be a Title or Literal and must contain
- * the table length (number of table entries)
- *
- ******************************************************************************/
-
-struct acpi_rsdump_info acpi_rs_dump_irq[7] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length),
-        "Descriptor Length", NULL},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
-        acpi_gbl_he_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
-        acpi_gbl_ll_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing",
-        acpi_gbl_shr_decode},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count),
-        "Interrupt Count", NULL},
-       {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]),
-        "Interrupt List", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed",
-        acpi_gbl_typ_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering",
-        acpi_gbl_bm_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type",
-        acpi_gbl_siz_decode},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count",
-        NULL},
-       {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List",
-        NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
-        "Start-Dependent-Functions", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length),
-        "Descriptor Length", NULL},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
-        "Compatibility Priority", acpi_gbl_config_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
-        "Performance/Robustness", acpi_gbl_config_decode}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf),
-        "End-Dependent-Functions", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_io[6] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding",
-        acpi_gbl_io_decode},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length",
-        NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io),
-        "Fixed I/O", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length),
-        "Address Length", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_vendor[3] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor),
-        "Vendor Specific", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL},
-       {ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data",
-        NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "EndTag",
-        NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_memory24[6] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24),
-        "24-Bit Memory Range", NULL},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect),
-        "Write Protect", acpi_gbl_rw_decode},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum",
-        NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum",
-        NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment",
-        NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length),
-        "Address Length", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_memory32[6] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32),
-        "32-Bit Memory Range", NULL},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect),
-        "Write Protect", acpi_gbl_rw_decode},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum",
-        NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum",
-        NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment",
-        NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length),
-        "Address Length", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32),
-        "32-Bit Fixed Memory Range", NULL},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect),
-        "Write Protect", acpi_gbl_rw_decode},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address",
-        NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length),
-        "Address Length", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_address16[8] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16),
-        "16-Bit WORD Address Space", NULL},
-       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity",
-        NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum",
-        NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum",
-        NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset),
-        "Translation Offset", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length),
-        "Address Length", NULL},
-       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_address32[8] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32),
-        "32-Bit DWORD Address Space", NULL},
-       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity",
-        NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum",
-        NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum",
-        NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset),
-        "Translation Offset", NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length),
-        "Address Length", NULL},
-       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_address64[8] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64),
-        "64-Bit QWORD Address Space", NULL},
-       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity",
-        NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum",
-        NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum",
-        NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset),
-        "Translation Offset", NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length),
-        "Address Length", NULL},
-       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64),
-        "64-Bit Extended Address Space", NULL},
-       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity),
-        "Granularity", NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum),
-        "Address Minimum", NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum),
-        "Address Maximum", NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset),
-        "Translation Offset", NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length),
-        "Address Length", NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific),
-        "Type-Specific Attribute", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq),
-        "Extended IRQ", NULL},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer),
-        "Type", acpi_gbl_consume_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering),
-        "Triggering", acpi_gbl_he_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity",
-        acpi_gbl_ll_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing",
-        acpi_gbl_shr_decode},
-       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL,
-        NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count),
-        "Interrupt Count", NULL},
-       {ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]),
-        "Interrupt List", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg),
-        "Generic Register", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID",
-        NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width",
-        NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset",
-        NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size),
-        "Access Size", NULL},
-       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL}
-};
-
-struct acpi_rsdump_info acpi_rs_dump_gpio[16] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_gpio), "GPIO", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.revision_id), "RevisionId", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.connection_type),
-        "ConnectionType", acpi_gbl_ct_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.producer_consumer),
-        "ProducerConsumer", acpi_gbl_consume_decode},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.pin_config), "PinConfig",
-        acpi_gbl_ppc_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.sharable), "Sharable",
-        acpi_gbl_shr_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.io_restriction),
-        "IoRestriction", acpi_gbl_ior_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.triggering), "Triggering",
-        acpi_gbl_he_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.polarity), "Polarity",
-        acpi_gbl_ll_decode},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.drive_strength), "DriveStrength",
-        NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.debounce_timeout),
-        "DebounceTimeout", NULL},
-       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(gpio.resource_source),
-        "ResourceSource", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.pin_table_length),
-        "PinTableLength", NULL},
-       {ACPI_RSD_WORDLIST, ACPI_RSD_OFFSET(gpio.pin_table), "PinTable", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.vendor_length), "VendorLength",
-        NULL},
-       {ACPI_RSD_SHORTLISTX, ACPI_RSD_OFFSET(gpio.vendor_data), "VendorData",
-        NULL},
-};
-
-struct acpi_rsdump_info acpi_rs_dump_fixed_dma[4] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_dma),
-        "FixedDma", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.request_lines),
-        "RequestLines", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.channels), "Channels",
-        NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_dma.width), "TransferWidth",
-        acpi_gbl_dts_decode},
-};
-
-#define ACPI_RS_DUMP_COMMON_SERIAL_BUS \
-       {ACPI_RSD_UINT8,    ACPI_RSD_OFFSET (common_serial_bus.revision_id),    "RevisionId",               NULL}, \
-       {ACPI_RSD_UINT8,    ACPI_RSD_OFFSET (common_serial_bus.type),           "Type",                     acpi_gbl_sbt_decode}, \
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.producer_consumer), "ProducerConsumer",      acpi_gbl_consume_decode}, \
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.slave_mode),     "SlaveMode",                acpi_gbl_sm_decode}, \
-       {ACPI_RSD_UINT8,    ACPI_RSD_OFFSET (common_serial_bus.type_revision_id), "TypeRevisionId",         NULL}, \
-       {ACPI_RSD_UINT16,   ACPI_RSD_OFFSET (common_serial_bus.type_data_length), "TypeDataLength",         NULL}, \
-       {ACPI_RSD_SOURCE,   ACPI_RSD_OFFSET (common_serial_bus.resource_source), "ResourceSource",          NULL}, \
-       {ACPI_RSD_UINT16,   ACPI_RSD_OFFSET (common_serial_bus.vendor_length),  "VendorLength",             NULL}, \
-       {ACPI_RSD_SHORTLISTX,ACPI_RSD_OFFSET (common_serial_bus.vendor_data),   "VendorData",               NULL},
-
-struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[10] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_common_serial_bus),
-        "Common Serial Bus", NULL},
-       ACPI_RS_DUMP_COMMON_SERIAL_BUS
-};
-
-struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[13] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_i2c_serial_bus),
-        "I2C Serial Bus", NULL},
-       ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
-                                       ACPI_RSD_OFFSET(i2c_serial_bus.
-                                                       access_mode),
-                                       "AccessMode", acpi_gbl_am_decode},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(i2c_serial_bus.connection_speed),
-        "ConnectionSpeed", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(i2c_serial_bus.slave_address),
-        "SlaveAddress", NULL},
-};
-
-struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[17] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_spi_serial_bus),
-        "Spi Serial Bus", NULL},
-       ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
-                                       ACPI_RSD_OFFSET(spi_serial_bus.
-                                                       wire_mode), "WireMode",
-                                       acpi_gbl_wm_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(spi_serial_bus.device_polarity),
-        "DevicePolarity", acpi_gbl_dp_decode},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.data_bit_length),
-        "DataBitLength", NULL},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_phase),
-        "ClockPhase", acpi_gbl_cph_decode},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_polarity),
-        "ClockPolarity", acpi_gbl_cpo_decode},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(spi_serial_bus.device_selection),
-        "DeviceSelection", NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(spi_serial_bus.connection_speed),
-        "ConnectionSpeed", NULL},
-};
-
-struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[19] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_uart_serial_bus),
-        "Uart Serial Bus", NULL},
-       ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_2BITFLAG,
-                                       ACPI_RSD_OFFSET(uart_serial_bus.
-                                                       flow_control),
-                                       "FlowControl", acpi_gbl_fc_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.stop_bits),
-        "StopBits", acpi_gbl_sb_decode},
-       {ACPI_RSD_3BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.data_bits),
-        "DataBits", acpi_gbl_bpb_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.endian), "Endian",
-        acpi_gbl_ed_decode},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.parity), "Parity",
-        acpi_gbl_pt_decode},
-       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.lines_enabled),
-        "LinesEnabled", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.rx_fifo_size),
-        "RxFifoSize", NULL},
-       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.tx_fifo_size),
-        "TxFifoSize", NULL},
-       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(uart_serial_bus.default_baud_rate),
-        "ConnectionSpeed", NULL},
-};
-
-/*
- * Tables used for common address descriptor flag fields
- */
-static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL,
-        NULL},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer),
-        "Consumer/Producer", acpi_gbl_consume_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode",
-        acpi_gbl_dec_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed),
-        "Min Relocatability", acpi_gbl_min_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed),
-        "Max Relocatability", acpi_gbl_max_decode}
-};
-
-static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = {
-       {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags),
-        "Resource Type", (void *)"Memory Range"},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect),
-        "Write Protect", acpi_gbl_rw_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching),
-        "Caching", acpi_gbl_mem_decode},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type),
-        "Range Type", acpi_gbl_mtp_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation),
-        "Translation", acpi_gbl_ttp_decode}
-};
-
-static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = {
-       {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags),
-        "Resource Type", (void *)"I/O Range"},
-       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type),
-        "Range Type", acpi_gbl_rng_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation),
-        "Translation", acpi_gbl_ttp_decode},
-       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type),
-        "Translation Type", acpi_gbl_trs_decode}
-};
-
-/*
- * Table used to dump _PRT contents
- */
-static struct acpi_rsdump_info acpi_rs_dump_prt[5] = {
-       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL},
-       {ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL},
-       {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL},
-       {ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL},
-       {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL}
-};
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_rs_dump_descriptor
  *
- * PARAMETERS:  Resource
+ * PARAMETERS:  resource            - Buffer containing the resource
+ *              table               - Table entry to decode the resource
  *
  * RETURN:      None
  *
- * DESCRIPTION:
+ * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
  *
  ******************************************************************************/
 
@@ -654,7 +251,8 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
                        /*
                         * Optional resource_source for Address resources
                         */
-                       acpi_rs_dump_resource_source(ACPI_CAST_PTR(struct
+                       acpi_rs_dump_resource_source(ACPI_CAST_PTR
+                                                    (struct
                                                                   acpi_resource_source,
                                                                   target));
                        break;
@@ -765,8 +363,9 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)
 
        ACPI_FUNCTION_ENTRY();
 
-       if (!(acpi_dbg_level & ACPI_LV_RESOURCES)
-           || !(_COMPONENT & acpi_dbg_layer)) {
+       /* Check if debug output enabled */
+
+       if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
                return;
        }
 
@@ -827,8 +426,9 @@ void acpi_rs_dump_irq_list(u8 * route_table)
 
        ACPI_FUNCTION_ENTRY();
 
-       if (!(acpi_dbg_level & ACPI_LV_RESOURCES)
-           || !(_COMPONENT & acpi_dbg_layer)) {
+       /* Check if debug output enabled */
+
+       if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
                return;
        }
 
diff --git a/drivers/acpi/acpica/rsdumpinfo.c b/drivers/acpi/acpica/rsdumpinfo.c
new file mode 100644 (file)
index 0000000..46192bd
--- /dev/null
@@ -0,0 +1,454 @@
+/*******************************************************************************
+ *
+ * Module Name: rsdumpinfo - Tables used to display resource descriptors.
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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 "acresrc.h"
+
+#define _COMPONENT          ACPI_RESOURCES
+ACPI_MODULE_NAME("rsdumpinfo")
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+#define ACPI_RSD_OFFSET(f)          (u8) ACPI_OFFSET (union acpi_resource_data,f)
+#define ACPI_PRT_OFFSET(f)          (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f)
+#define ACPI_RSD_TABLE_SIZE(name)   (sizeof(name) / sizeof (struct acpi_rsdump_info))
+/*******************************************************************************
+ *
+ * Resource Descriptor info tables
+ *
+ * Note: The first table entry must be a Title or Literal and must contain
+ * the table length (number of table entries)
+ *
+ ******************************************************************************/
+struct acpi_rsdump_info acpi_rs_dump_irq[7] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length),
+        "Descriptor Length", NULL},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
+        acpi_gbl_he_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
+        acpi_gbl_ll_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing",
+        acpi_gbl_shr_decode},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count),
+        "Interrupt Count", NULL},
+       {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]),
+        "Interrupt List", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed",
+        acpi_gbl_typ_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering",
+        acpi_gbl_bm_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type",
+        acpi_gbl_siz_decode},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count",
+        NULL},
+       {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List",
+        NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
+        "Start-Dependent-Functions", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length),
+        "Descriptor Length", NULL},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
+        "Compatibility Priority", acpi_gbl_config_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
+        "Performance/Robustness", acpi_gbl_config_decode}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf),
+        "End-Dependent-Functions", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_io[6] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding",
+        acpi_gbl_io_decode},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length",
+        NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io),
+        "Fixed I/O", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length),
+        "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_vendor[3] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor),
+        "Vendor Specific", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL},
+       {ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data",
+        NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "EndTag",
+        NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_memory24[6] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24),
+        "24-Bit Memory Range", NULL},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect),
+        "Write Protect", acpi_gbl_rw_decode},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum",
+        NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum",
+        NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment",
+        NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length),
+        "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_memory32[6] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32),
+        "32-Bit Memory Range", NULL},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect),
+        "Write Protect", acpi_gbl_rw_decode},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum",
+        NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum",
+        NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment",
+        NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length),
+        "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32),
+        "32-Bit Fixed Memory Range", NULL},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect),
+        "Write Protect", acpi_gbl_rw_decode},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address",
+        NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length),
+        "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_address16[8] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16),
+        "16-Bit WORD Address Space", NULL},
+       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity",
+        NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum",
+        NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum",
+        NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset),
+        "Translation Offset", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length),
+        "Address Length", NULL},
+       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_address32[8] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32),
+        "32-Bit DWORD Address Space", NULL},
+       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity",
+        NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum",
+        NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum",
+        NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset),
+        "Translation Offset", NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length),
+        "Address Length", NULL},
+       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_address64[8] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64),
+        "64-Bit QWORD Address Space", NULL},
+       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity",
+        NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum",
+        NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum",
+        NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset),
+        "Translation Offset", NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length),
+        "Address Length", NULL},
+       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64),
+        "64-Bit Extended Address Space", NULL},
+       {ACPI_RSD_ADDRESS, 0, NULL, NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity),
+        "Granularity", NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum),
+        "Address Minimum", NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum),
+        "Address Maximum", NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset),
+        "Translation Offset", NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length),
+        "Address Length", NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific),
+        "Type-Specific Attribute", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq),
+        "Extended IRQ", NULL},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer),
+        "Type", acpi_gbl_consume_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering),
+        "Triggering", acpi_gbl_he_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity",
+        acpi_gbl_ll_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing",
+        acpi_gbl_shr_decode},
+       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL,
+        NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count),
+        "Interrupt Count", NULL},
+       {ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]),
+        "Interrupt List", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg),
+        "Generic Register", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID",
+        NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width",
+        NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset",
+        NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size),
+        "Access Size", NULL},
+       {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_gpio[16] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_gpio), "GPIO", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.revision_id), "RevisionId", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.connection_type),
+        "ConnectionType", acpi_gbl_ct_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.producer_consumer),
+        "ProducerConsumer", acpi_gbl_consume_decode},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.pin_config), "PinConfig",
+        acpi_gbl_ppc_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.sharable), "Sharing",
+        acpi_gbl_shr_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.io_restriction),
+        "IoRestriction", acpi_gbl_ior_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.triggering), "Triggering",
+        acpi_gbl_he_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.polarity), "Polarity",
+        acpi_gbl_ll_decode},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.drive_strength), "DriveStrength",
+        NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.debounce_timeout),
+        "DebounceTimeout", NULL},
+       {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(gpio.resource_source),
+        "ResourceSource", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.pin_table_length),
+        "PinTableLength", NULL},
+       {ACPI_RSD_WORDLIST, ACPI_RSD_OFFSET(gpio.pin_table), "PinTable", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.vendor_length), "VendorLength",
+        NULL},
+       {ACPI_RSD_SHORTLISTX, ACPI_RSD_OFFSET(gpio.vendor_data), "VendorData",
+        NULL},
+};
+
+struct acpi_rsdump_info acpi_rs_dump_fixed_dma[4] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_dma),
+        "FixedDma", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.request_lines),
+        "RequestLines", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.channels), "Channels",
+        NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_dma.width), "TransferWidth",
+        acpi_gbl_dts_decode},
+};
+
+#define ACPI_RS_DUMP_COMMON_SERIAL_BUS \
+       {ACPI_RSD_UINT8,    ACPI_RSD_OFFSET (common_serial_bus.revision_id),    "RevisionId",               NULL}, \
+       {ACPI_RSD_UINT8,    ACPI_RSD_OFFSET (common_serial_bus.type),           "Type",                     acpi_gbl_sbt_decode}, \
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.producer_consumer), "ProducerConsumer",      acpi_gbl_consume_decode}, \
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.slave_mode),     "SlaveMode",                acpi_gbl_sm_decode}, \
+       {ACPI_RSD_UINT8,    ACPI_RSD_OFFSET (common_serial_bus.type_revision_id), "TypeRevisionId",         NULL}, \
+       {ACPI_RSD_UINT16,   ACPI_RSD_OFFSET (common_serial_bus.type_data_length), "TypeDataLength",         NULL}, \
+       {ACPI_RSD_SOURCE,   ACPI_RSD_OFFSET (common_serial_bus.resource_source), "ResourceSource",          NULL}, \
+       {ACPI_RSD_UINT16,   ACPI_RSD_OFFSET (common_serial_bus.vendor_length),  "VendorLength",             NULL}, \
+       {ACPI_RSD_SHORTLISTX,ACPI_RSD_OFFSET (common_serial_bus.vendor_data),   "VendorData",               NULL},
+
+struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[10] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_common_serial_bus),
+        "Common Serial Bus", NULL},
+       ACPI_RS_DUMP_COMMON_SERIAL_BUS
+};
+
+struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[13] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_i2c_serial_bus),
+        "I2C Serial Bus", NULL},
+       ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
+                                       ACPI_RSD_OFFSET(i2c_serial_bus.
+                                                       access_mode),
+                                       "AccessMode", acpi_gbl_am_decode},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(i2c_serial_bus.connection_speed),
+        "ConnectionSpeed", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(i2c_serial_bus.slave_address),
+        "SlaveAddress", NULL},
+};
+
+struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[17] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_spi_serial_bus),
+        "Spi Serial Bus", NULL},
+       ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG,
+                                       ACPI_RSD_OFFSET(spi_serial_bus.
+                                                       wire_mode), "WireMode",
+                                       acpi_gbl_wm_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(spi_serial_bus.device_polarity),
+        "DevicePolarity", acpi_gbl_dp_decode},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.data_bit_length),
+        "DataBitLength", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_phase),
+        "ClockPhase", acpi_gbl_cph_decode},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_polarity),
+        "ClockPolarity", acpi_gbl_cpo_decode},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(spi_serial_bus.device_selection),
+        "DeviceSelection", NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(spi_serial_bus.connection_speed),
+        "ConnectionSpeed", NULL},
+};
+
+struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[19] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_uart_serial_bus),
+        "Uart Serial Bus", NULL},
+       ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_2BITFLAG,
+                                       ACPI_RSD_OFFSET(uart_serial_bus.
+                                                       flow_control),
+                                       "FlowControl", acpi_gbl_fc_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.stop_bits),
+        "StopBits", acpi_gbl_sb_decode},
+       {ACPI_RSD_3BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.data_bits),
+        "DataBits", acpi_gbl_bpb_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.endian), "Endian",
+        acpi_gbl_ed_decode},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.parity), "Parity",
+        acpi_gbl_pt_decode},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.lines_enabled),
+        "LinesEnabled", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.rx_fifo_size),
+        "RxFifoSize", NULL},
+       {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.tx_fifo_size),
+        "TxFifoSize", NULL},
+       {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(uart_serial_bus.default_baud_rate),
+        "ConnectionSpeed", NULL},
+};
+
+/*
+ * Tables used for common address descriptor flag fields
+ */
+struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL,
+        NULL},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer),
+        "Consumer/Producer", acpi_gbl_consume_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode",
+        acpi_gbl_dec_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed),
+        "Min Relocatability", acpi_gbl_min_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed),
+        "Max Relocatability", acpi_gbl_max_decode}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = {
+       {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags),
+        "Resource Type", (void *)"Memory Range"},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect),
+        "Write Protect", acpi_gbl_rw_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching),
+        "Caching", acpi_gbl_mem_decode},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type),
+        "Range Type", acpi_gbl_mtp_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation),
+        "Translation", acpi_gbl_ttp_decode}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = {
+       {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags),
+        "Resource Type", (void *)"I/O Range"},
+       {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type),
+        "Range Type", acpi_gbl_rng_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation),
+        "Translation", acpi_gbl_ttp_decode},
+       {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type),
+        "Translation Type", acpi_gbl_trs_decode}
+};
+
+/*
+ * Table used to dump _PRT contents
+ */
+struct acpi_rsdump_info acpi_rs_dump_prt[5] = {
+       {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL},
+       {ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL},
+       {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL},
+       {ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL},
+       {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL}
+};
+
+#endif
index a9fa515..41fed78 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f6a0810..ca18375 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e23a9ec..364decc 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@ ACPI_MODULE_NAME("rsirq")
  * acpi_rs_get_irq
  *
  ******************************************************************************/
-struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
+struct acpi_rsconvert_info acpi_rs_get_irq[9] = {
        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
         ACPI_RS_SIZE(struct acpi_resource_irq),
         ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)},
@@ -80,7 +80,7 @@ struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
 
        {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
 
-       /* Get flags: Triggering[0], Polarity[3], Sharing[4] */
+       /* Get flags: Triggering[0], Polarity[3], Sharing[4], Wake[5] */
 
        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
         AML_OFFSET(irq.flags),
@@ -92,7 +92,11 @@ struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
 
        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
         AML_OFFSET(irq.flags),
-        4}
+        4},
+
+       {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.wake_capable),
+        AML_OFFSET(irq.flags),
+        5}
 };
 
 /*******************************************************************************
@@ -101,7 +105,7 @@ struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
  *
  ******************************************************************************/
 
-struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
+struct acpi_rsconvert_info acpi_rs_set_irq[14] = {
        /* Start with a default descriptor of length 3 */
 
        {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
@@ -114,7 +118,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
         AML_OFFSET(irq.irq_mask),
         ACPI_RS_OFFSET(data.irq.interrupt_count)},
 
-       /* Set the flags byte */
+       /* Set flags: Triggering[0], Polarity[3], Sharing[4], Wake[5] */
 
        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
         AML_OFFSET(irq.flags),
@@ -128,6 +132,10 @@ struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
         AML_OFFSET(irq.flags),
         4},
 
+       {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.wake_capable),
+        AML_OFFSET(irq.flags),
+        5},
+
        /*
         * All done if the output descriptor length is required to be 3
         * (i.e., optimization to 2 bytes cannot be attempted)
@@ -181,7 +189,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
  *
  ******************************************************************************/
 
-struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = {
+struct acpi_rsconvert_info acpi_rs_convert_ext_irq[10] = {
        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ,
         ACPI_RS_SIZE(struct acpi_resource_extended_irq),
         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)},
@@ -190,8 +198,10 @@ struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = {
         sizeof(struct aml_resource_extended_irq),
         0},
 
-       /* Flag bits */
-
+       /*
+        * Flags: Producer/Consumer[0], Triggering[1], Polarity[2],
+        *        Sharing[3], Wake[4]
+        */
        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer),
         AML_OFFSET(extended_irq.flags),
         0},
@@ -208,19 +218,21 @@ struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = {
         AML_OFFSET(extended_irq.flags),
         3},
 
+       {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.wake_capable),
+        AML_OFFSET(extended_irq.flags),
+        4},
+
        /* IRQ Table length (Byte4) */
 
        {ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count),
         AML_OFFSET(extended_irq.interrupt_count),
-        sizeof(u32)}
-       ,
+        sizeof(u32)},
 
        /* Copy every IRQ in the table, each is 32 bits */
 
        {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
         AML_OFFSET(extended_irq.interrupts[0]),
-        0}
-       ,
+        0},
 
        /* Optional resource_source (Index and String) */
 
@@ -285,7 +297,6 @@ struct acpi_rsconvert_info acpi_rs_convert_fixed_dma[4] = {
         * request_lines
         * Channels
         */
-
        {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_dma.request_lines),
         AML_OFFSET(fixed_dma.request_lines),
         2},
@@ -293,5 +304,4 @@ struct acpi_rsconvert_info acpi_rs_convert_fixed_dma[4] = {
        {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_dma.width),
         AML_OFFSET(fixed_dma.width),
         1},
-
 };
index 8b64db9..ee2e206 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -217,9 +217,10 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
 
                /* Perform final sanity check on the new AML resource descriptor */
 
-               status =
-                   acpi_ut_validate_resource(ACPI_CAST_PTR
-                                             (union aml_resource, aml), NULL);
+               status = acpi_ut_validate_resource(NULL,
+                                                  ACPI_CAST_PTR(union
+                                                                aml_resource,
+                                                                aml), NULL);
                if (ACPI_FAILURE(status)) {
                        return_ACPI_STATUS(status);
                }
index 4fd611a..ebc773a 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -156,8 +156,7 @@ struct acpi_rsconvert_info acpi_rs_get_vendor_small[3] = {
 
        {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
         0,
-        sizeof(u8)}
-       ,
+        sizeof(u8)},
 
        /* Vendor data */
 
@@ -181,8 +180,7 @@ struct acpi_rsconvert_info acpi_rs_get_vendor_large[3] = {
 
        {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
         0,
-        sizeof(u8)}
-       ,
+        sizeof(u8)},
 
        /* Vendor data */
 
index c6f291c..d5bf05a 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -136,30 +136,30 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                        /*
                         * Mask and shift the flag bit
                         */
-                       ACPI_SET8(destination) = (u8)
-                           ((ACPI_GET8(source) >> info->value) & 0x01);
+                       ACPI_SET8(destination,
+                                 ((ACPI_GET8(source) >> info->value) & 0x01));
                        break;
 
                case ACPI_RSC_2BITFLAG:
                        /*
                         * Mask and shift the flag bits
                         */
-                       ACPI_SET8(destination) = (u8)
-                           ((ACPI_GET8(source) >> info->value) & 0x03);
+                       ACPI_SET8(destination,
+                                 ((ACPI_GET8(source) >> info->value) & 0x03));
                        break;
 
                case ACPI_RSC_3BITFLAG:
                        /*
                         * Mask and shift the flag bits
                         */
-                       ACPI_SET8(destination) = (u8)
-                           ((ACPI_GET8(source) >> info->value) & 0x07);
+                       ACPI_SET8(destination,
+                                 ((ACPI_GET8(source) >> info->value) & 0x07));
                        break;
 
                case ACPI_RSC_COUNT:
 
                        item_count = ACPI_GET8(source);
-                       ACPI_SET8(destination) = (u8) item_count;
+                       ACPI_SET8(destination, item_count);
 
                        resource->length = resource->length +
                            (info->value * (item_count - 1));
@@ -168,7 +168,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                case ACPI_RSC_COUNT16:
 
                        item_count = aml_resource_length;
-                       ACPI_SET16(destination) = item_count;
+                       ACPI_SET16(destination, item_count);
 
                        resource->length = resource->length +
                            (info->value * (item_count - 1));
@@ -181,13 +181,13 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
 
                        resource->length = resource->length + item_count;
                        item_count = item_count / 2;
-                       ACPI_SET16(destination) = item_count;
+                       ACPI_SET16(destination, item_count);
                        break;
 
                case ACPI_RSC_COUNT_GPIO_VEN:
 
                        item_count = ACPI_GET8(source);
-                       ACPI_SET8(destination) = (u8)item_count;
+                       ACPI_SET8(destination, item_count);
 
                        resource->length = resource->length +
                            (info->value * item_count);
@@ -216,7 +216,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                        }
 
                        resource->length = resource->length + item_count;
-                       ACPI_SET16(destination) = item_count;
+                       ACPI_SET16(destination, item_count);
                        break;
 
                case ACPI_RSC_COUNT_SERIAL_VEN:
@@ -224,7 +224,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                        item_count = ACPI_GET16(source) - info->value;
 
                        resource->length = resource->length + item_count;
-                       ACPI_SET16(destination) = item_count;
+                       ACPI_SET16(destination, item_count);
                        break;
 
                case ACPI_RSC_COUNT_SERIAL_RES:
@@ -234,7 +234,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                            - ACPI_GET16(source) - info->value;
 
                        resource->length = resource->length + item_count;
-                       ACPI_SET16(destination) = item_count;
+                       ACPI_SET16(destination, item_count);
                        break;
 
                case ACPI_RSC_LENGTH:
@@ -385,7 +385,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                        }
 
                        target = ACPI_ADD_PTR(char, resource, info->value);
-                       ACPI_SET8(target) = (u8) item_count;
+                       ACPI_SET8(target, item_count);
                        break;
 
                case ACPI_RSC_BITMASK16:
@@ -401,7 +401,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                        }
 
                        target = ACPI_ADD_PTR(char, resource, info->value);
-                       ACPI_SET8(target) = (u8) item_count;
+                       ACPI_SET8(target, item_count);
                        break;
 
                case ACPI_RSC_EXIT_NE:
@@ -514,37 +514,40 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                        /*
                         * Clear the flag byte
                         */
-                       ACPI_SET8(destination) = 0;
+                       ACPI_SET8(destination, 0);
                        break;
 
                case ACPI_RSC_1BITFLAG:
                        /*
                         * Mask and shift the flag bit
                         */
-                       ACPI_SET8(destination) |= (u8)
-                           ((ACPI_GET8(source) & 0x01) << info->value);
+                       ACPI_SET_BIT(*ACPI_CAST8(destination), (u8)
+                                    ((ACPI_GET8(source) & 0x01) << info->
+                                     value));
                        break;
 
                case ACPI_RSC_2BITFLAG:
                        /*
                         * Mask and shift the flag bits
                         */
-                       ACPI_SET8(destination) |= (u8)
-                           ((ACPI_GET8(source) & 0x03) << info->value);
+                       ACPI_SET_BIT(*ACPI_CAST8(destination), (u8)
+                                    ((ACPI_GET8(source) & 0x03) << info->
+                                     value));
                        break;
 
                case ACPI_RSC_3BITFLAG:
                        /*
                         * Mask and shift the flag bits
                         */
-                       ACPI_SET8(destination) |= (u8)
-                           ((ACPI_GET8(source) & 0x07) << info->value);
+                       ACPI_SET_BIT(*ACPI_CAST8(destination), (u8)
+                                    ((ACPI_GET8(source) & 0x07) << info->
+                                     value));
                        break;
 
                case ACPI_RSC_COUNT:
 
                        item_count = ACPI_GET8(source);
-                       ACPI_SET8(destination) = (u8) item_count;
+                       ACPI_SET8(destination, item_count);
 
                        aml_length =
                            (u16) (aml_length +
@@ -561,18 +564,18 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                case ACPI_RSC_COUNT_GPIO_PIN:
 
                        item_count = ACPI_GET16(source);
-                       ACPI_SET16(destination) = (u16)aml_length;
+                       ACPI_SET16(destination, aml_length);
 
                        aml_length = (u16)(aml_length + item_count * 2);
                        target = ACPI_ADD_PTR(void, aml, info->value);
-                       ACPI_SET16(target) = (u16)aml_length;
+                       ACPI_SET16(target, aml_length);
                        acpi_rs_set_resource_length(aml_length, aml);
                        break;
 
                case ACPI_RSC_COUNT_GPIO_VEN:
 
                        item_count = ACPI_GET16(source);
-                       ACPI_SET16(destination) = (u16)item_count;
+                       ACPI_SET16(destination, item_count);
 
                        aml_length =
                            (u16)(aml_length + (info->value * item_count));
@@ -584,7 +587,7 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                        /* Set resource source string length */
 
                        item_count = ACPI_GET16(source);
-                       ACPI_SET16(destination) = (u16)aml_length;
+                       ACPI_SET16(destination, aml_length);
 
                        /* Compute offset for the Vendor Data */
 
@@ -594,7 +597,7 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                        /* Set vendor offset only if there is vendor data */
 
                        if (resource->data.gpio.vendor_length) {
-                               ACPI_SET16(target) = (u16)aml_length;
+                               ACPI_SET16(target, aml_length);
                        }
 
                        acpi_rs_set_resource_length(aml_length, aml);
@@ -603,7 +606,7 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                case ACPI_RSC_COUNT_SERIAL_VEN:
 
                        item_count = ACPI_GET16(source);
-                       ACPI_SET16(destination) = item_count + info->value;
+                       ACPI_SET16(destination, item_count + info->value);
                        aml_length = (u16)(aml_length + item_count);
                        acpi_rs_set_resource_length(aml_length, aml);
                        break;
@@ -686,7 +689,8 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                         * Optional resource_source (Index and String)
                         */
                        aml_length =
-                           acpi_rs_set_resource_source(aml, (acpi_rs_length)
+                           acpi_rs_set_resource_source(aml,
+                                                       (acpi_rs_length)
                                                        aml_length, source);
                        acpi_rs_set_resource_length(aml_length, aml);
                        break;
@@ -706,10 +710,12 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                        /*
                         * 8-bit encoded bitmask (DMA macro)
                         */
-                       ACPI_SET8(destination) = (u8)
-                           acpi_rs_encode_bitmask(source,
-                                                  *ACPI_ADD_PTR(u8, resource,
-                                                                info->value));
+                       ACPI_SET8(destination,
+                                 acpi_rs_encode_bitmask(source,
+                                                        *ACPI_ADD_PTR(u8,
+                                                                      resource,
+                                                                      info->
+                                                                      value)));
                        break;
 
                case ACPI_RSC_BITMASK16:
index 9aa5e68..fe49fc4 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@ ACPI_MODULE_NAME("rsserial")
  * acpi_rs_convert_gpio
  *
  ******************************************************************************/
-struct acpi_rsconvert_info acpi_rs_convert_gpio[17] = {
+struct acpi_rsconvert_info acpi_rs_convert_gpio[18] = {
        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GPIO,
         ACPI_RS_SIZE(struct acpi_resource_gpio),
         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_gpio)},
@@ -75,10 +75,14 @@ struct acpi_rsconvert_info acpi_rs_convert_gpio[17] = {
         AML_OFFSET(gpio.flags),
         0},
 
-       {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.gpio.sharable),
+       {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.gpio.sharable),
         AML_OFFSET(gpio.int_flags),
         3},
 
+       {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.gpio.wake_capable),
+        AML_OFFSET(gpio.int_flags),
+        4},
+
        {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.gpio.io_restriction),
         AML_OFFSET(gpio.int_flags),
         0},
index 37d5241..a44953c 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -108,7 +108,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
                mask |= (0x1 << list[i]);
        }
 
-       return mask;
+       return (mask);
 }
 
 /*******************************************************************************
@@ -358,8 +358,10 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length,
                 *
                 * Zero the entire area of the buffer.
                 */
-               total_length = (u32)
-               ACPI_STRLEN(ACPI_CAST_PTR(char, &aml_resource_source[1])) + 1;
+               total_length =
+                   (u32)
+                   ACPI_STRLEN(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
+                   1;
                total_length = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
 
                ACPI_MEMSET(resource_source->string_ptr, 0, total_length);
@@ -675,7 +677,9 @@ acpi_rs_get_method_data(acpi_handle handle,
        /* Execute the method, no parameters */
 
        status =
-           acpi_ut_evaluate_object(handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
+           acpi_ut_evaluate_object(ACPI_CAST_PTR
+                                   (struct acpi_namespace_node, handle), path,
+                                   ACPI_BTYPE_BUFFER, &obj_desc);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
index 5aad744..15d6eae 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -423,7 +423,7 @@ ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Walk a resource template for the specified evice to find a
+ * DESCRIPTION: Walk a resource template for the specified device to find a
  *              vendor-defined resource that matches the supplied UUID and
  *              UUID subtype. Returns a struct acpi_resource of type Vendor.
  *
@@ -522,57 +522,42 @@ acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_walk_resources
+ * FUNCTION:    acpi_walk_resource_buffer
  *
- * PARAMETERS:  device_handle   - Handle to the device object for the
- *                                device we are querying
- *              name            - Method name of the resources we want.
- *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
- *                                METHOD_NAME__AEI)
+ * PARAMETERS:  buffer          - Formatted buffer returned by one of the
+ *                                various Get*Resource functions
  *              user_function   - Called for each resource
  *              context         - Passed to user_function
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Retrieves the current or possible resource list for the
- *              specified device. The user_function is called once for
- *              each resource in the list.
+ * DESCRIPTION: Walks the input resource template. The user_function is called
+ *              once for each resource in the list.
  *
  ******************************************************************************/
+
 acpi_status
-acpi_walk_resources(acpi_handle device_handle,
-                   char *name,
-                   acpi_walk_resource_callback user_function, void *context)
+acpi_walk_resource_buffer(struct acpi_buffer * buffer,
+                         acpi_walk_resource_callback user_function,
+                         void *context)
 {
-       acpi_status status;
-       struct acpi_buffer buffer;
+       acpi_status status = AE_OK;
        struct acpi_resource *resource;
        struct acpi_resource *resource_end;
 
-       ACPI_FUNCTION_TRACE(acpi_walk_resources);
+       ACPI_FUNCTION_TRACE(acpi_walk_resource_buffer);
 
        /* Parameter validation */
 
-       if (!device_handle || !user_function || !name ||
-           (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
-            !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS) &&
-            !ACPI_COMPARE_NAME(name, METHOD_NAME__AEI))) {
+       if (!buffer || !buffer->pointer || !user_function) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
-       /* Get the _CRS/_PRS/_AEI resource list */
-
-       buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
-       status = acpi_rs_get_method_data(device_handle, name, &buffer);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
-
-       /* Buffer now contains the resource list */
+       /* Buffer contains the resource list and length */
 
-       resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
+       resource = ACPI_CAST_PTR(struct acpi_resource, buffer->pointer);
        resource_end =
-           ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
+           ACPI_ADD_PTR(struct acpi_resource, buffer->pointer, buffer->length);
 
        /* Walk the resource list until the end_tag is found (or buffer end) */
 
@@ -606,11 +591,63 @@ acpi_walk_resources(acpi_handle device_handle,
 
                /* Get the next resource descriptor */
 
-               resource =
-                   ACPI_ADD_PTR(struct acpi_resource, resource,
-                                resource->length);
+               resource = ACPI_NEXT_RESOURCE(resource);
        }
 
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_walk_resource_buffer)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_walk_resources
+ *
+ * PARAMETERS:  device_handle   - Handle to the device object for the
+ *                                device we are querying
+ *              name            - Method name of the resources we want.
+ *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
+ *                                METHOD_NAME__AEI)
+ *              user_function   - Called for each resource
+ *              context         - Passed to user_function
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieves the current or possible resource list for the
+ *              specified device. The user_function is called once for
+ *              each resource in the list.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_walk_resources(acpi_handle device_handle,
+                   char *name,
+                   acpi_walk_resource_callback user_function, void *context)
+{
+       acpi_status status;
+       struct acpi_buffer buffer;
+
+       ACPI_FUNCTION_TRACE(acpi_walk_resources);
+
+       /* Parameter validation */
+
+       if (!device_handle || !user_function || !name ||
+           (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
+            !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS) &&
+            !ACPI_COMPARE_NAME(name, METHOD_NAME__AEI))) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       /* Get the _CRS/_PRS/_AEI resource list */
+
+       buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+       status = acpi_rs_get_method_data(device_handle, name, &buffer);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Walk the resource list and cleanup */
+
+       status = acpi_walk_resource_buffer(&buffer, user_function, context);
        ACPI_FREE(buffer.pointer);
        return_ACPI_STATUS(status);
 }
index 3906518..74181bf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -172,6 +172,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
  * FUNCTION:    acpi_tb_init_generic_address
  *
  * PARAMETERS:  generic_address     - GAS struct to be initialized
+ *              space_id            - ACPI Space ID for this register
  *              byte_width          - Width of this register
  *              address             - Address of the register
  *
@@ -407,8 +408,8 @@ static void acpi_tb_convert_fadt(void)
         * should be zero are indeed zero. This will workaround BIOSs that
         * inadvertently place values in these fields.
         *
-        * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
-        * offset 45, 55, 95, and the word located at offset 109, 110.
+        * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
+        * at offset 45, 55, 95, and the word located at offset 109, 110.
         *
         * Note: The FADT revision value is unreliable. Only the length can be
         * trusted.
index 77d1db2..e4f4f02 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index f540ae4..e57cd38 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 285e24b..ce3d5db 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -147,7 +147,7 @@ acpi_status acpi_tb_initialize_facs(void)
                                         ACPI_CAST_INDIRECT_PTR(struct
                                                                acpi_table_header,
                                                                &acpi_gbl_FACS));
-       return status;
+       return (status);
 }
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
index f563278..b35a5e6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,6 @@
 #include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "acnamesp.h"
 #include "actables.h"
 
 #define _COMPONENT          ACPI_TABLES
@@ -437,7 +436,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
  *
  ******************************************************************************/
 acpi_status
-acpi_install_table_handler(acpi_tbl_handler handler, void *context)
+acpi_install_table_handler(acpi_table_handler handler, void *context)
 {
        acpi_status status;
 
@@ -483,7 +482,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_table_handler)
  * DESCRIPTION: Remove table event handler
  *
  ******************************************************************************/
-acpi_status acpi_remove_table_handler(acpi_tbl_handler handler)
+acpi_status acpi_remove_table_handler(acpi_table_handler handler)
 {
        acpi_status status;
 
index a5e1e4e..67e046e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -192,7 +192,7 @@ static acpi_status acpi_tb_load_namespace(void)
                (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
        }
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
+       ACPI_INFO((AE_INFO, "All ACPI Tables successfully acquired"));
 
       unlock_and_exit:
        (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
index 28f3302..7c2ecfb 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 6488030..698b9d3 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -214,7 +214,7 @@ acpi_ut_check_address_range(acpi_adr_space_type space_id,
 
        if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
            (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
-               return_UINT32(0);
+               return_VALUE(0);
        }
 
        range_info = acpi_gbl_address_range_list[space_id];
@@ -256,7 +256,7 @@ acpi_ut_check_address_range(acpi_adr_space_type space_id,
                range_info = range_info->next;
        }
 
-       return_UINT32(overlap_count);
+       return_VALUE(overlap_count);
 }
 
 /*******************************************************************************
index ed29d47..e0ffb58 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index e1d40ed..e0e8579 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 294692a..e4c9291 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -785,7 +785,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
 
                status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
                if (ACPI_FAILURE(status)) {
-                       return status;
+                       return (status);
                }
                break;
 
@@ -795,7 +795,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
                                                  &dest_desc->event.
                                                  os_semaphore);
                if (ACPI_FAILURE(status)) {
-                       return status;
+                       return (status);
                }
                break;
 
index 5d95166..c57d9cc 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -166,11 +166,9 @@ acpi_debug_print(u32 requested_debug_level,
        acpi_thread_id thread_id;
        va_list args;
 
-       /*
-        * Stay silent if the debug level or component ID is disabled
-        */
-       if (!(requested_debug_level & acpi_dbg_level) ||
-           !(component_id & acpi_dbg_layer)) {
+       /* Check if debug output enabled */
+
+       if (!ACPI_IS_DEBUG_ENABLED(requested_debug_level, component_id)) {
                return;
        }
 
@@ -236,8 +234,9 @@ acpi_debug_print_raw(u32 requested_debug_level,
 {
        va_list args;
 
-       if (!(requested_debug_level & acpi_dbg_level) ||
-           !(component_id & acpi_dbg_layer)) {
+       /* Check if debug output enabled */
+
+       if (!ACPI_IS_DEBUG_ENABLED(requested_debug_level, component_id)) {
                return;
        }
 
@@ -272,9 +271,13 @@ acpi_ut_trace(u32 line_number,
        acpi_gbl_nesting_level++;
        acpi_ut_track_stack_ptr();
 
-       acpi_debug_print(ACPI_LV_FUNCTIONS,
-                        line_number, function_name, module_name, component_id,
-                        "%s\n", acpi_gbl_fn_entry_str);
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                line_number, function_name, module_name,
+                                component_id, "%s\n", acpi_gbl_fn_entry_str);
+       }
 }
 
 ACPI_EXPORT_SYMBOL(acpi_ut_trace)
@@ -304,9 +307,14 @@ acpi_ut_trace_ptr(u32 line_number,
        acpi_gbl_nesting_level++;
        acpi_ut_track_stack_ptr();
 
-       acpi_debug_print(ACPI_LV_FUNCTIONS,
-                        line_number, function_name, module_name, component_id,
-                        "%s %p\n", acpi_gbl_fn_entry_str, pointer);
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                line_number, function_name, module_name,
+                                component_id, "%s %p\n", acpi_gbl_fn_entry_str,
+                                pointer);
+       }
 }
 
 /*******************************************************************************
@@ -335,9 +343,14 @@ acpi_ut_trace_str(u32 line_number,
        acpi_gbl_nesting_level++;
        acpi_ut_track_stack_ptr();
 
-       acpi_debug_print(ACPI_LV_FUNCTIONS,
-                        line_number, function_name, module_name, component_id,
-                        "%s %s\n", acpi_gbl_fn_entry_str, string);
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                line_number, function_name, module_name,
+                                component_id, "%s %s\n", acpi_gbl_fn_entry_str,
+                                string);
+       }
 }
 
 /*******************************************************************************
@@ -366,9 +379,14 @@ acpi_ut_trace_u32(u32 line_number,
        acpi_gbl_nesting_level++;
        acpi_ut_track_stack_ptr();
 
-       acpi_debug_print(ACPI_LV_FUNCTIONS,
-                        line_number, function_name, module_name, component_id,
-                        "%s %08X\n", acpi_gbl_fn_entry_str, integer);
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                line_number, function_name, module_name,
+                                component_id, "%s %08X\n",
+                                acpi_gbl_fn_entry_str, integer);
+       }
 }
 
 /*******************************************************************************
@@ -393,9 +411,13 @@ acpi_ut_exit(u32 line_number,
             const char *module_name, u32 component_id)
 {
 
-       acpi_debug_print(ACPI_LV_FUNCTIONS,
-                        line_number, function_name, module_name, component_id,
-                        "%s\n", acpi_gbl_fn_exit_str);
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                line_number, function_name, module_name,
+                                component_id, "%s\n", acpi_gbl_fn_exit_str);
+       }
 
        acpi_gbl_nesting_level--;
 }
@@ -425,17 +447,23 @@ acpi_ut_status_exit(u32 line_number,
                    u32 component_id, acpi_status status)
 {
 
-       if (ACPI_SUCCESS(status)) {
-               acpi_debug_print(ACPI_LV_FUNCTIONS,
-                                line_number, function_name, module_name,
-                                component_id, "%s %s\n", acpi_gbl_fn_exit_str,
-                                acpi_format_exception(status));
-       } else {
-               acpi_debug_print(ACPI_LV_FUNCTIONS,
-                                line_number, function_name, module_name,
-                                component_id, "%s ****Exception****: %s\n",
-                                acpi_gbl_fn_exit_str,
-                                acpi_format_exception(status));
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               if (ACPI_SUCCESS(status)) {
+                       acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                        line_number, function_name,
+                                        module_name, component_id, "%s %s\n",
+                                        acpi_gbl_fn_exit_str,
+                                        acpi_format_exception(status));
+               } else {
+                       acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                        line_number, function_name,
+                                        module_name, component_id,
+                                        "%s ****Exception****: %s\n",
+                                        acpi_gbl_fn_exit_str,
+                                        acpi_format_exception(status));
+               }
        }
 
        acpi_gbl_nesting_level--;
@@ -465,10 +493,15 @@ acpi_ut_value_exit(u32 line_number,
                   const char *module_name, u32 component_id, u64 value)
 {
 
-       acpi_debug_print(ACPI_LV_FUNCTIONS,
-                        line_number, function_name, module_name, component_id,
-                        "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str,
-                        ACPI_FORMAT_UINT64(value));
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                line_number, function_name, module_name,
+                                component_id, "%s %8.8X%8.8X\n",
+                                acpi_gbl_fn_exit_str,
+                                ACPI_FORMAT_UINT64(value));
+       }
 
        acpi_gbl_nesting_level--;
 }
@@ -497,9 +530,14 @@ acpi_ut_ptr_exit(u32 line_number,
                 const char *module_name, u32 component_id, u8 *ptr)
 {
 
-       acpi_debug_print(ACPI_LV_FUNCTIONS,
-                        line_number, function_name, module_name, component_id,
-                        "%s %p\n", acpi_gbl_fn_exit_str, ptr);
+       /* Check if enabled up-front for performance */
+
+       if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
+               acpi_debug_print(ACPI_LV_FUNCTIONS,
+                                line_number, function_name, module_name,
+                                component_id, "%s %p\n", acpi_gbl_fn_exit_str,
+                                ptr);
+       }
 
        acpi_gbl_nesting_level--;
 }
index 60a1584..11e2e02 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7981054..2541de4 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -340,7 +340,7 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
 {
        union acpi_operand_object **internal_obj;
 
-       ACPI_FUNCTION_TRACE(ut_delete_internal_object_list);
+       ACPI_FUNCTION_ENTRY();
 
        /* Walk the null-terminated internal list */
 
@@ -351,7 +351,7 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
        /* Free the combined parameter pointer list and object array */
 
        ACPI_FREE(obj_list);
-       return_VOID;
+       return;
 }
 
 /*******************************************************************************
@@ -484,7 +484,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
        union acpi_generic_state *state;
        u32 i;
 
-       ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object);
+       ACPI_FUNCTION_NAME(ut_update_object_reference);
 
        while (object) {
 
@@ -493,7 +493,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
                if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) {
                        ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
                                          "Object %p is NS handle\n", object));
-                       return_ACPI_STATUS(AE_OK);
+                       return (AE_OK);
                }
 
                /*
@@ -530,18 +530,42 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
                         */
                        for (i = 0; i < object->package.count; i++) {
                                /*
-                                * Push each element onto the stack for later processing.
-                                * Note: There can be null elements within the package,
-                                * these are simply ignored
+                                * Null package elements are legal and can be simply
+                                * ignored.
                                 */
-                               status =
-                                   acpi_ut_create_update_state_and_push
-                                   (object->package.elements[i], action,
-                                    &state_list);
-                               if (ACPI_FAILURE(status)) {
-                                       goto error_exit;
+                               next_object = object->package.elements[i];
+                               if (!next_object) {
+                                       continue;
+                               }
+
+                               switch (next_object->common.type) {
+                               case ACPI_TYPE_INTEGER:
+                               case ACPI_TYPE_STRING:
+                               case ACPI_TYPE_BUFFER:
+                                       /*
+                                        * For these very simple sub-objects, we can just
+                                        * update the reference count here and continue.
+                                        * Greatly increases performance of this operation.
+                                        */
+                                       acpi_ut_update_ref_count(next_object,
+                                                                action);
+                                       break;
+
+                               default:
+                                       /*
+                                        * For complex sub-objects, push them onto the stack
+                                        * for later processing (this eliminates recursion.)
+                                        */
+                                       status =
+                                           acpi_ut_create_update_state_and_push
+                                           (next_object, action, &state_list);
+                                       if (ACPI_FAILURE(status)) {
+                                               goto error_exit;
+                                       }
+                                       break;
                                }
                        }
+                       next_object = NULL;
                        break;
 
                case ACPI_TYPE_BUFFER_FIELD:
@@ -619,7 +643,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
                }
        }
 
-       return_ACPI_STATUS(AE_OK);
+       return (AE_OK);
 
       error_exit:
 
@@ -633,7 +657,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
                acpi_ut_delete_generic_state(state);
        }
 
-       return_ACPI_STATUS(status);
+       return (status);
 }
 
 /*******************************************************************************
@@ -652,12 +676,12 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
 void acpi_ut_add_reference(union acpi_operand_object *object)
 {
 
-       ACPI_FUNCTION_TRACE_PTR(ut_add_reference, object);
+       ACPI_FUNCTION_NAME(ut_add_reference);
 
        /* Ensure that we have a valid object */
 
        if (!acpi_ut_valid_internal_object(object)) {
-               return_VOID;
+               return;
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -667,7 +691,7 @@ void acpi_ut_add_reference(union acpi_operand_object *object)
        /* Increment the reference count */
 
        (void)acpi_ut_update_object_reference(object, REF_INCREMENT);
-       return_VOID;
+       return;
 }
 
 /*******************************************************************************
@@ -685,7 +709,7 @@ void acpi_ut_add_reference(union acpi_operand_object *object)
 void acpi_ut_remove_reference(union acpi_operand_object *object)
 {
 
-       ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object);
+       ACPI_FUNCTION_NAME(ut_remove_reference);
 
        /*
         * Allow a NULL pointer to be passed in, just ignore it. This saves
@@ -694,13 +718,13 @@ void acpi_ut_remove_reference(union acpi_operand_object *object)
         */
        if (!object ||
            (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) {
-               return_VOID;
+               return;
        }
 
        /* Ensure that we have a valid object */
 
        if (!acpi_ut_valid_internal_object(object)) {
-               return_VOID;
+               return;
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -713,5 +737,5 @@ void acpi_ut_remove_reference(union acpi_operand_object *object)
         * of all subobjects!)
         */
        (void)acpi_ut_update_object_reference(object, REF_DECREMENT);
-       return_VOID;
+       return;
 }
index a9c65fb..c3f3a7e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,7 @@ ACPI_MODULE_NAME("uteval")
  ******************************************************************************/
 
 acpi_status
-acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
+acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node,
                        char *path,
                        u32 expected_return_btypes,
                        union acpi_operand_object **return_desc)
index 23b9894..a0ab7c0 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index ed18931..ffecf4b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -293,11 +293,11 @@ acpi_status acpi_ut_init_globals(void)
 
        /* GPE support */
 
+       acpi_gbl_all_gpes_initialized = FALSE;
        acpi_gbl_gpe_xrupt_list_head = NULL;
        acpi_gbl_gpe_fadt_blocks[0] = NULL;
        acpi_gbl_gpe_fadt_blocks[1] = NULL;
        acpi_current_gpe_count = 0;
-       acpi_gbl_all_gpes_initialized = FALSE;
 
        acpi_gbl_global_event_handler = NULL;
 
@@ -357,17 +357,24 @@ acpi_status acpi_ut_init_globals(void)
        acpi_gbl_root_node_struct.peer = NULL;
        acpi_gbl_root_node_struct.object = NULL;
 
+#ifdef ACPI_DISASSEMBLER
+       acpi_gbl_external_list = NULL;
+#endif
+
 #ifdef ACPI_DEBUG_OUTPUT
        acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
 #endif
 
 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
        acpi_gbl_display_final_mem_stats = FALSE;
+       acpi_gbl_disable_mem_tracking = FALSE;
 #endif
 
        return_ACPI_STATUS(AE_OK);
 }
 
+/* Public globals */
+
 ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
 ACPI_EXPORT_SYMBOL(acpi_dbg_level)
 ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
index 774c3ae..43a170a 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 246798e..c5d1ac4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index b1eb7f1..5c26ad4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,11 +66,11 @@ acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
        lock->num_readers = 0;
        status = acpi_os_create_mutex(&lock->reader_mutex);
        if (ACPI_FAILURE(status)) {
-               return status;
+               return (status);
        }
 
        status = acpi_os_create_mutex(&lock->writer_mutex);
-       return status;
+       return (status);
 }
 
 void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
@@ -108,7 +108,7 @@ acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
 
        status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
        if (ACPI_FAILURE(status)) {
-               return status;
+               return (status);
        }
 
        /* Acquire the write lock only for the first reader */
@@ -121,7 +121,7 @@ acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
        }
 
        acpi_os_release_mutex(lock->reader_mutex);
-       return status;
+       return (status);
 }
 
 acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
@@ -130,7 +130,7 @@ acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
 
        status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
        if (ACPI_FAILURE(status)) {
-               return status;
+               return (status);
        }
 
        /* Release the write lock only for the very last reader */
@@ -141,7 +141,7 @@ acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
        }
 
        acpi_os_release_mutex(lock->reader_mutex);
-       return status;
+       return (status);
 }
 
 /*******************************************************************************
@@ -165,7 +165,7 @@ acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
        acpi_status status;
 
        status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
-       return status;
+       return (status);
 }
 
 void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
index 4956367..909fe66 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 9286a69..785fdd0 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utmisc")
 
-#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
-/*******************************************************************************
- *
- * FUNCTION:    ut_convert_backslashes
- *
- * PARAMETERS:  pathname        - File pathname string to be converted
- *
- * RETURN:      Modifies the input Pathname
- *
- * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
- *              the entire input file pathname string.
- *
- ******************************************************************************/
-void ut_convert_backslashes(char *pathname)
-{
-
-       if (!pathname) {
-               return;
-       }
-
-       while (*pathname) {
-               if (*pathname == '\\') {
-                       *pathname = '/';
-               }
-
-               pathname++;
-       }
-}
-#endif
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_is_pci_root_bridge
@@ -89,7 +59,6 @@ void ut_convert_backslashes(char *pathname)
  * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
  *
  ******************************************************************************/
-
 u8 acpi_ut_is_pci_root_bridge(char *id)
 {
 
@@ -136,362 +105,6 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ut_allocate_owner_id
- *
- * PARAMETERS:  owner_id        - Where the new owner ID is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
- *              track objects created by the table or method, to be deleted
- *              when the method exits or the table is unloaded.
- *
- ******************************************************************************/
-
-acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
-{
-       u32 i;
-       u32 j;
-       u32 k;
-       acpi_status status;
-
-       ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
-
-       /* Guard against multiple allocations of ID to the same location */
-
-       if (*owner_id) {
-               ACPI_ERROR((AE_INFO, "Owner ID [0x%2.2X] already exists",
-                           *owner_id));
-               return_ACPI_STATUS(AE_ALREADY_EXISTS);
-       }
-
-       /* Mutex for the global ID mask */
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
-
-       /*
-        * Find a free owner ID, cycle through all possible IDs on repeated
-        * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
-        * to be scanned twice.
-        */
-       for (i = 0, j = acpi_gbl_last_owner_id_index;
-            i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
-               if (j >= ACPI_NUM_OWNERID_MASKS) {
-                       j = 0;  /* Wraparound to start of mask array */
-               }
-
-               for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
-                       if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
-
-                               /* There are no free IDs in this mask */
-
-                               break;
-                       }
-
-                       if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
-                               /*
-                                * Found a free ID. The actual ID is the bit index plus one,
-                                * making zero an invalid Owner ID. Save this as the last ID
-                                * allocated and update the global ID mask.
-                                */
-                               acpi_gbl_owner_id_mask[j] |= (1 << k);
-
-                               acpi_gbl_last_owner_id_index = (u8)j;
-                               acpi_gbl_next_owner_id_offset = (u8)(k + 1);
-
-                               /*
-                                * Construct encoded ID from the index and bit position
-                                *
-                                * Note: Last [j].k (bit 255) is never used and is marked
-                                * permanently allocated (prevents +1 overflow)
-                                */
-                               *owner_id =
-                                   (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
-
-                               ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
-                                                 "Allocated OwnerId: %2.2X\n",
-                                                 (unsigned int)*owner_id));
-                               goto exit;
-                       }
-               }
-
-               acpi_gbl_next_owner_id_offset = 0;
-       }
-
-       /*
-        * All owner_ids have been allocated. This typically should
-        * not happen since the IDs are reused after deallocation. The IDs are
-        * allocated upon table load (one per table) and method execution, and
-        * they are released when a table is unloaded or a method completes
-        * execution.
-        *
-        * If this error happens, there may be very deep nesting of invoked control
-        * methods, or there may be a bug where the IDs are not released.
-        */
-       status = AE_OWNER_ID_LIMIT;
-       ACPI_ERROR((AE_INFO,
-                   "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
-
-      exit:
-       (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
-       return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_release_owner_id
- *
- * PARAMETERS:  owner_id_ptr        - Pointer to a previously allocated owner_ID
- *
- * RETURN:      None. No error is returned because we are either exiting a
- *              control method or unloading a table. Either way, we would
- *              ignore any error anyway.
- *
- * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
- *
- ******************************************************************************/
-
-void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
-{
-       acpi_owner_id owner_id = *owner_id_ptr;
-       acpi_status status;
-       u32 index;
-       u32 bit;
-
-       ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
-
-       /* Always clear the input owner_id (zero is an invalid ID) */
-
-       *owner_id_ptr = 0;
-
-       /* Zero is not a valid owner_ID */
-
-       if (owner_id == 0) {
-               ACPI_ERROR((AE_INFO, "Invalid OwnerId: 0x%2.2X", owner_id));
-               return_VOID;
-       }
-
-       /* Mutex for the global ID mask */
-
-       status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
-       if (ACPI_FAILURE(status)) {
-               return_VOID;
-       }
-
-       /* Normalize the ID to zero */
-
-       owner_id--;
-
-       /* Decode ID to index/offset pair */
-
-       index = ACPI_DIV_32(owner_id);
-       bit = 1 << ACPI_MOD_32(owner_id);
-
-       /* Free the owner ID only if it is valid */
-
-       if (acpi_gbl_owner_id_mask[index] & bit) {
-               acpi_gbl_owner_id_mask[index] ^= bit;
-       } else {
-               ACPI_ERROR((AE_INFO,
-                           "Release of non-allocated OwnerId: 0x%2.2X",
-                           owner_id + 1));
-       }
-
-       (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
-       return_VOID;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_strupr (strupr)
- *
- * PARAMETERS:  src_string      - The source string to convert
- *
- * RETURN:      None
- *
- * DESCRIPTION: Convert string to uppercase
- *
- * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
- *
- ******************************************************************************/
-
-void acpi_ut_strupr(char *src_string)
-{
-       char *string;
-
-       ACPI_FUNCTION_ENTRY();
-
-       if (!src_string) {
-               return;
-       }
-
-       /* Walk entire string, uppercasing the letters */
-
-       for (string = src_string; *string; string++) {
-               *string = (char)ACPI_TOUPPER(*string);
-       }
-
-       return;
-}
-
-#ifdef ACPI_ASL_COMPILER
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_strlwr (strlwr)
- *
- * PARAMETERS:  src_string      - The source string to convert
- *
- * RETURN:      None
- *
- * DESCRIPTION: Convert string to lowercase
- *
- * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
- *
- ******************************************************************************/
-
-void acpi_ut_strlwr(char *src_string)
-{
-       char *string;
-
-       ACPI_FUNCTION_ENTRY();
-
-       if (!src_string) {
-               return;
-       }
-
-       /* Walk entire string, lowercasing the letters */
-
-       for (string = src_string; *string; string++) {
-               *string = (char)ACPI_TOLOWER(*string);
-       }
-
-       return;
-}
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_ut_stricmp
- *
- * PARAMETERS:  string1             - first string to compare
- *              string2             - second string to compare
- *
- * RETURN:      int that signifies string relationship. Zero means strings
- *              are equal.
- *
- * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
- *              strings with no case sensitivity)
- *
- ******************************************************************************/
-
-int acpi_ut_stricmp(char *string1, char *string2)
-{
-       int c1;
-       int c2;
-
-       do {
-               c1 = tolower((int)*string1);
-               c2 = tolower((int)*string2);
-
-               string1++;
-               string2++;
-       }
-       while ((c1 == c2) && (c1));
-
-       return (c1 - c2);
-}
-#endif
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_print_string
- *
- * PARAMETERS:  string          - Null terminated ASCII string
- *              max_length      - Maximum output length
- *
- * RETURN:      None
- *
- * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
- *              sequences.
- *
- ******************************************************************************/
-
-void acpi_ut_print_string(char *string, u8 max_length)
-{
-       u32 i;
-
-       if (!string) {
-               acpi_os_printf("<\"NULL STRING PTR\">");
-               return;
-       }
-
-       acpi_os_printf("\"");
-       for (i = 0; string[i] && (i < max_length); i++) {
-
-               /* Escape sequences */
-
-               switch (string[i]) {
-               case 0x07:
-                       acpi_os_printf("\\a");  /* BELL */
-                       break;
-
-               case 0x08:
-                       acpi_os_printf("\\b");  /* BACKSPACE */
-                       break;
-
-               case 0x0C:
-                       acpi_os_printf("\\f");  /* FORMFEED */
-                       break;
-
-               case 0x0A:
-                       acpi_os_printf("\\n");  /* LINEFEED */
-                       break;
-
-               case 0x0D:
-                       acpi_os_printf("\\r");  /* CARRIAGE RETURN */
-                       break;
-
-               case 0x09:
-                       acpi_os_printf("\\t");  /* HORIZONTAL TAB */
-                       break;
-
-               case 0x0B:
-                       acpi_os_printf("\\v");  /* VERTICAL TAB */
-                       break;
-
-               case '\'':      /* Single Quote */
-               case '\"':      /* Double Quote */
-               case '\\':      /* Backslash */
-                       acpi_os_printf("\\%c", (int)string[i]);
-                       break;
-
-               default:
-
-                       /* Check for printable character or hex escape */
-
-                       if (ACPI_IS_PRINT(string[i])) {
-                               /* This is a normal character */
-
-                               acpi_os_printf("%c", (int)string[i]);
-                       } else {
-                               /* All others will be Hex escapes */
-
-                               acpi_os_printf("\\x%2.2X", (s32) string[i]);
-                       }
-                       break;
-               }
-       }
-       acpi_os_printf("\"");
-
-       if (i == max_length && string[i]) {
-               acpi_os_printf("...");
-       }
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ut_dword_byte_swap
  *
  * PARAMETERS:  value           - Value to be converted
@@ -559,379 +172,6 @@ void acpi_ut_set_integer_width(u8 revision)
        }
 }
 
-#ifdef ACPI_DEBUG_OUTPUT
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_display_init_pathname
- *
- * PARAMETERS:  type                - Object type of the node
- *              obj_handle          - Handle whose pathname will be displayed
- *              path                - Additional path string to be appended.
- *                                      (NULL if no extra path)
- *
- * RETURN:      acpi_status
- *
- * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
- *
- ******************************************************************************/
-
-void
-acpi_ut_display_init_pathname(u8 type,
-                             struct acpi_namespace_node *obj_handle,
-                             char *path)
-{
-       acpi_status status;
-       struct acpi_buffer buffer;
-
-       ACPI_FUNCTION_ENTRY();
-
-       /* Only print the path if the appropriate debug level is enabled */
-
-       if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
-               return;
-       }
-
-       /* Get the full pathname to the node */
-
-       buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
-       status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
-       if (ACPI_FAILURE(status)) {
-               return;
-       }
-
-       /* Print what we're doing */
-
-       switch (type) {
-       case ACPI_TYPE_METHOD:
-               acpi_os_printf("Executing  ");
-               break;
-
-       default:
-               acpi_os_printf("Initializing ");
-               break;
-       }
-
-       /* Print the object type and pathname */
-
-       acpi_os_printf("%-12s %s",
-                      acpi_ut_get_type_name(type), (char *)buffer.pointer);
-
-       /* Extra path is used to append names like _STA, _INI, etc. */
-
-       if (path) {
-               acpi_os_printf(".%s", path);
-       }
-       acpi_os_printf("\n");
-
-       ACPI_FREE(buffer.pointer);
-}
-#endif
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_valid_acpi_char
- *
- * PARAMETERS:  char            - The character to be examined
- *              position        - Byte position (0-3)
- *
- * RETURN:      TRUE if the character is valid, FALSE otherwise
- *
- * DESCRIPTION: Check for a valid ACPI character. Must be one of:
- *              1) Upper case alpha
- *              2) numeric
- *              3) underscore
- *
- *              We allow a '!' as the last character because of the ASF! table
- *
- ******************************************************************************/
-
-u8 acpi_ut_valid_acpi_char(char character, u32 position)
-{
-
-       if (!((character >= 'A' && character <= 'Z') ||
-             (character >= '0' && character <= '9') || (character == '_'))) {
-
-               /* Allow a '!' in the last position */
-
-               if (character == '!' && position == 3) {
-                       return (TRUE);
-               }
-
-               return (FALSE);
-       }
-
-       return (TRUE);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_valid_acpi_name
- *
- * PARAMETERS:  name            - The name to be examined
- *
- * RETURN:      TRUE if the name is valid, FALSE otherwise
- *
- * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
- *              1) Upper case alpha
- *              2) numeric
- *              3) underscore
- *
- ******************************************************************************/
-
-u8 acpi_ut_valid_acpi_name(u32 name)
-{
-       u32 i;
-
-       ACPI_FUNCTION_ENTRY();
-
-       for (i = 0; i < ACPI_NAME_SIZE; i++) {
-               if (!acpi_ut_valid_acpi_char
-                   ((ACPI_CAST_PTR(char, &name))[i], i)) {
-                       return (FALSE);
-               }
-       }
-
-       return (TRUE);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_repair_name
- *
- * PARAMETERS:  name            - The ACPI name to be repaired
- *
- * RETURN:      Repaired version of the name
- *
- * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
- *              return the new name. NOTE: the Name parameter must reside in
- *              read/write memory, cannot be a const.
- *
- * An ACPI Name must consist of valid ACPI characters. We will repair the name
- * if necessary because we don't want to abort because of this, but we want
- * all namespace names to be printable. A warning message is appropriate.
- *
- * This issue came up because there are in fact machines that exhibit
- * this problem, and we want to be able to enable ACPI support for them,
- * even though there are a few bad names.
- *
- ******************************************************************************/
-
-void acpi_ut_repair_name(char *name)
-{
-       u32 i;
-       u8 found_bad_char = FALSE;
-       u32 original_name;
-
-       ACPI_FUNCTION_NAME(ut_repair_name);
-
-       ACPI_MOVE_NAME(&original_name, name);
-
-       /* Check each character in the name */
-
-       for (i = 0; i < ACPI_NAME_SIZE; i++) {
-               if (acpi_ut_valid_acpi_char(name[i], i)) {
-                       continue;
-               }
-
-               /*
-                * Replace a bad character with something printable, yet technically
-                * still invalid. This prevents any collisions with existing "good"
-                * names in the namespace.
-                */
-               name[i] = '*';
-               found_bad_char = TRUE;
-       }
-
-       if (found_bad_char) {
-
-               /* Report warning only if in strict mode or debug mode */
-
-               if (!acpi_gbl_enable_interpreter_slack) {
-                       ACPI_WARNING((AE_INFO,
-                                     "Found bad character(s) in name, repaired: [%4.4s]\n",
-                                     name));
-               } else {
-                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                         "Found bad character(s) in name, repaired: [%4.4s]\n",
-                                         name));
-               }
-       }
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_strtoul64
- *
- * PARAMETERS:  string          - Null terminated string
- *              base            - Radix of the string: 16 or ACPI_ANY_BASE;
- *                                ACPI_ANY_BASE means 'in behalf of to_integer'
- *              ret_integer     - Where the converted integer is returned
- *
- * RETURN:      Status and Converted value
- *
- * DESCRIPTION: Convert a string into an unsigned value. Performs either a
- *              32-bit or 64-bit conversion, depending on the current mode
- *              of the interpreter.
- *              NOTE: Does not support Octal strings, not needed.
- *
- ******************************************************************************/
-
-acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
-{
-       u32 this_digit = 0;
-       u64 return_value = 0;
-       u64 quotient;
-       u64 dividend;
-       u32 to_integer_op = (base == ACPI_ANY_BASE);
-       u32 mode32 = (acpi_gbl_integer_byte_width == 4);
-       u8 valid_digits = 0;
-       u8 sign_of0x = 0;
-       u8 term = 0;
-
-       ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
-
-       switch (base) {
-       case ACPI_ANY_BASE:
-       case 16:
-               break;
-
-       default:
-               /* Invalid Base */
-               return_ACPI_STATUS(AE_BAD_PARAMETER);
-       }
-
-       if (!string) {
-               goto error_exit;
-       }
-
-       /* Skip over any white space in the buffer */
-
-       while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
-               string++;
-       }
-
-       if (to_integer_op) {
-               /*
-                * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
-                * We need to determine if it is decimal or hexadecimal.
-                */
-               if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
-                       sign_of0x = 1;
-                       base = 16;
-
-                       /* Skip over the leading '0x' */
-                       string += 2;
-               } else {
-                       base = 10;
-               }
-       }
-
-       /* Any string left? Check that '0x' is not followed by white space. */
-
-       if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
-               if (to_integer_op) {
-                       goto error_exit;
-               } else {
-                       goto all_done;
-               }
-       }
-
-       /*
-        * Perform a 32-bit or 64-bit conversion, depending upon the current
-        * execution mode of the interpreter
-        */
-       dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
-
-       /* Main loop: convert the string to a 32- or 64-bit integer */
-
-       while (*string) {
-               if (ACPI_IS_DIGIT(*string)) {
-
-                       /* Convert ASCII 0-9 to Decimal value */
-
-                       this_digit = ((u8)*string) - '0';
-               } else if (base == 10) {
-
-                       /* Digit is out of range; possible in to_integer case only */
-
-                       term = 1;
-               } else {
-                       this_digit = (u8)ACPI_TOUPPER(*string);
-                       if (ACPI_IS_XDIGIT((char)this_digit)) {
-
-                               /* Convert ASCII Hex char to value */
-
-                               this_digit = this_digit - 'A' + 10;
-                       } else {
-                               term = 1;
-                       }
-               }
-
-               if (term) {
-                       if (to_integer_op) {
-                               goto error_exit;
-                       } else {
-                               break;
-                       }
-               } else if ((valid_digits == 0) && (this_digit == 0)
-                          && !sign_of0x) {
-
-                       /* Skip zeros */
-                       string++;
-                       continue;
-               }
-
-               valid_digits++;
-
-               if (sign_of0x
-                   && ((valid_digits > 16)
-                       || ((valid_digits > 8) && mode32))) {
-                       /*
-                        * This is to_integer operation case.
-                        * No any restrictions for string-to-integer conversion,
-                        * see ACPI spec.
-                        */
-                       goto error_exit;
-               }
-
-               /* Divide the digit into the correct position */
-
-               (void)acpi_ut_short_divide((dividend - (u64)this_digit),
-                                          base, &quotient, NULL);
-
-               if (return_value > quotient) {
-                       if (to_integer_op) {
-                               goto error_exit;
-                       } else {
-                               break;
-                       }
-               }
-
-               return_value *= base;
-               return_value += this_digit;
-               string++;
-       }
-
-       /* All done, normal exit */
-
-      all_done:
-
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
-                         ACPI_FORMAT_UINT64(return_value)));
-
-       *ret_integer = return_value;
-       return_ACPI_STATUS(AE_OK);
-
-      error_exit:
-       /* Base was set/validated above */
-
-       if (base == 10) {
-               return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
-       } else {
-               return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
-       }
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_create_update_state_and_push
@@ -1097,3 +337,71 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
 
        return_ACPI_STATUS(AE_AML_INTERNAL);
 }
+
+#ifdef ACPI_DEBUG_OUTPUT
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_display_init_pathname
+ *
+ * PARAMETERS:  type                - Object type of the node
+ *              obj_handle          - Handle whose pathname will be displayed
+ *              path                - Additional path string to be appended.
+ *                                      (NULL if no extra path)
+ *
+ * RETURN:      acpi_status
+ *
+ * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_display_init_pathname(u8 type,
+                             struct acpi_namespace_node *obj_handle,
+                             char *path)
+{
+       acpi_status status;
+       struct acpi_buffer buffer;
+
+       ACPI_FUNCTION_ENTRY();
+
+       /* Only print the path if the appropriate debug level is enabled */
+
+       if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+               return;
+       }
+
+       /* Get the full pathname to the node */
+
+       buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+       status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
+       if (ACPI_FAILURE(status)) {
+               return;
+       }
+
+       /* Print what we're doing */
+
+       switch (type) {
+       case ACPI_TYPE_METHOD:
+               acpi_os_printf("Executing  ");
+               break;
+
+       default:
+               acpi_os_printf("Initializing ");
+               break;
+       }
+
+       /* Print the object type and pathname */
+
+       acpi_os_printf("%-12s %s",
+                      acpi_ut_get_type_name(type), (char *)buffer.pointer);
+
+       /* Extra path is used to append names like _STA, _INI, etc. */
+
+       if (path) {
+               acpi_os_printf(".%s", path);
+       }
+       acpi_os_printf("\n");
+
+       ACPI_FREE(buffer.pointer);
+}
+#endif
index 5ccf57c..22feb99 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 5c52ca7..1099f5c 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -419,7 +419,7 @@ void acpi_ut_delete_object_desc(union acpi_operand_object *object)
 {
        ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);
 
-       /* Object must be a union acpi_operand_object */
+       /* Object must be of type union acpi_operand_object */
 
        if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
                ACPI_ERROR((AE_INFO,
index 676285d..36a7d36 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/utownerid.c b/drivers/acpi/acpica/utownerid.c
new file mode 100644 (file)
index 0000000..835340b
--- /dev/null
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ *
+ * Module Name: utownerid - Support for Table/Method Owner IDs
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utownerid")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_allocate_owner_id
+ *
+ * PARAMETERS:  owner_id        - Where the new owner ID is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
+ *              track objects created by the table or method, to be deleted
+ *              when the method exits or the table is unloaded.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
+{
+       u32 i;
+       u32 j;
+       u32 k;
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
+
+       /* Guard against multiple allocations of ID to the same location */
+
+       if (*owner_id) {
+               ACPI_ERROR((AE_INFO, "Owner ID [0x%2.2X] already exists",
+                           *owner_id));
+               return_ACPI_STATUS(AE_ALREADY_EXISTS);
+       }
+
+       /* Mutex for the global ID mask */
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /*
+        * Find a free owner ID, cycle through all possible IDs on repeated
+        * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
+        * to be scanned twice.
+        */
+       for (i = 0, j = acpi_gbl_last_owner_id_index;
+            i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
+               if (j >= ACPI_NUM_OWNERID_MASKS) {
+                       j = 0;  /* Wraparound to start of mask array */
+               }
+
+               for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
+                       if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
+
+                               /* There are no free IDs in this mask */
+
+                               break;
+                       }
+
+                       if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
+                               /*
+                                * Found a free ID. The actual ID is the bit index plus one,
+                                * making zero an invalid Owner ID. Save this as the last ID
+                                * allocated and update the global ID mask.
+                                */
+                               acpi_gbl_owner_id_mask[j] |= (1 << k);
+
+                               acpi_gbl_last_owner_id_index = (u8)j;
+                               acpi_gbl_next_owner_id_offset = (u8)(k + 1);
+
+                               /*
+                                * Construct encoded ID from the index and bit position
+                                *
+                                * Note: Last [j].k (bit 255) is never used and is marked
+                                * permanently allocated (prevents +1 overflow)
+                                */
+                               *owner_id =
+                                   (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
+
+                               ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
+                                                 "Allocated OwnerId: %2.2X\n",
+                                                 (unsigned int)*owner_id));
+                               goto exit;
+                       }
+               }
+
+               acpi_gbl_next_owner_id_offset = 0;
+       }
+
+       /*
+        * All owner_ids have been allocated. This typically should
+        * not happen since the IDs are reused after deallocation. The IDs are
+        * allocated upon table load (one per table) and method execution, and
+        * they are released when a table is unloaded or a method completes
+        * execution.
+        *
+        * If this error happens, there may be very deep nesting of invoked control
+        * methods, or there may be a bug where the IDs are not released.
+        */
+       status = AE_OWNER_ID_LIMIT;
+       ACPI_ERROR((AE_INFO,
+                   "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
+
+      exit:
+       (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
+       return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_release_owner_id
+ *
+ * PARAMETERS:  owner_id_ptr        - Pointer to a previously allocated owner_ID
+ *
+ * RETURN:      None. No error is returned because we are either exiting a
+ *              control method or unloading a table. Either way, we would
+ *              ignore any error anyway.
+ *
+ * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
+ *
+ ******************************************************************************/
+
+void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
+{
+       acpi_owner_id owner_id = *owner_id_ptr;
+       acpi_status status;
+       u32 index;
+       u32 bit;
+
+       ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
+
+       /* Always clear the input owner_id (zero is an invalid ID) */
+
+       *owner_id_ptr = 0;
+
+       /* Zero is not a valid owner_ID */
+
+       if (owner_id == 0) {
+               ACPI_ERROR((AE_INFO, "Invalid OwnerId: 0x%2.2X", owner_id));
+               return_VOID;
+       }
+
+       /* Mutex for the global ID mask */
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
+       if (ACPI_FAILURE(status)) {
+               return_VOID;
+       }
+
+       /* Normalize the ID to zero */
+
+       owner_id--;
+
+       /* Decode ID to index/offset pair */
+
+       index = ACPI_DIV_32(owner_id);
+       bit = 1 << ACPI_MOD_32(owner_id);
+
+       /* Free the owner ID only if it is valid */
+
+       if (acpi_gbl_owner_id_mask[index] & bit) {
+               acpi_gbl_owner_id_mask[index] ^= bit;
+       } else {
+               ACPI_ERROR((AE_INFO,
+                           "Release of non-allocated OwnerId: 0x%2.2X",
+                           owner_id + 1));
+       }
+
+       (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
+       return_VOID;
+}
index e38bef4..cb7fa49 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -127,7 +127,9 @@ const char *acpi_gbl_rw_decode[] = {
 
 const char *acpi_gbl_shr_decode[] = {
        "Exclusive",
-       "Shared"
+       "Shared",
+       "ExclusiveAndWake",     /* ACPI 5.0 */
+       "SharedAndWake"         /* ACPI 5.0 */
 };
 
 const char *acpi_gbl_siz_decode[] = {
@@ -383,26 +385,16 @@ static const u8 acpi_gbl_resource_types[] = {
        ACPI_VARIABLE_LENGTH    /* 0E *serial_bus */
 };
 
-/*
- * For the iASL compiler/disassembler, we don't want any error messages
- * because the disassembler uses the resource validation code to determine
- * if Buffer objects are actually Resource Templates.
- */
-#ifdef ACPI_ASL_COMPILER
-#define ACPI_RESOURCE_ERROR(plist)
-#else
-#define ACPI_RESOURCE_ERROR(plist)  ACPI_ERROR(plist)
-#endif
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_walk_aml_resources
  *
- * PARAMETERS:  aml             - Pointer to the raw AML resource template
- *              aml_length      - Length of the entire template
- *              user_function   - Called once for each descriptor found. If
- *                                NULL, a pointer to the end_tag is returned
- *              context         - Passed to user_function
+ * PARAMETERS:  walk_state          - Current walk info
+ * PARAMETERS:  aml                 - Pointer to the raw AML resource template
+ *              aml_length          - Length of the entire template
+ *              user_function       - Called once for each descriptor found. If
+ *                                    NULL, a pointer to the end_tag is returned
+ *              context             - Passed to user_function
  *
  * RETURN:      Status
  *
@@ -412,7 +404,8 @@ static const u8 acpi_gbl_resource_types[] = {
  ******************************************************************************/
 
 acpi_status
-acpi_ut_walk_aml_resources(u8 * aml,
+acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
+                          u8 *aml,
                           acpi_size aml_length,
                           acpi_walk_aml_callback user_function, void **context)
 {
@@ -441,7 +434,8 @@ acpi_ut_walk_aml_resources(u8 * aml,
 
                /* Validate the Resource Type and Resource Length */
 
-               status = acpi_ut_validate_resource(aml, &resource_index);
+               status =
+                   acpi_ut_validate_resource(walk_state, aml, &resource_index);
                if (ACPI_FAILURE(status)) {
                        /*
                         * Exit on failure. Cannot continue because the descriptor length
@@ -498,7 +492,8 @@ acpi_ut_walk_aml_resources(u8 * aml,
 
                /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */
 
-               (void)acpi_ut_validate_resource(end_tag, &resource_index);
+               (void)acpi_ut_validate_resource(walk_state, end_tag,
+                                               &resource_index);
                status =
                    user_function(end_tag, 2, offset, resource_index, context);
                if (ACPI_FAILURE(status)) {
@@ -513,9 +508,10 @@ acpi_ut_walk_aml_resources(u8 * aml,
  *
  * FUNCTION:    acpi_ut_validate_resource
  *
- * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
- *              return_index    - Where the resource index is returned. NULL
- *                                if the index is not required.
+ * PARAMETERS:  walk_state          - Current walk info
+ *              aml                 - Pointer to the raw AML resource descriptor
+ *              return_index        - Where the resource index is returned. NULL
+ *                                    if the index is not required.
  *
  * RETURN:      Status, and optionally the Index into the global resource tables
  *
@@ -525,7 +521,9 @@ acpi_ut_walk_aml_resources(u8 * aml,
  *
  ******************************************************************************/
 
-acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
+acpi_status
+acpi_ut_validate_resource(struct acpi_walk_state *walk_state,
+                         void *aml, u8 *return_index)
 {
        union aml_resource *aml_resource;
        u8 resource_type;
@@ -627,10 +625,12 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
                if ((aml_resource->common_serial_bus.type == 0) ||
                    (aml_resource->common_serial_bus.type >
                     AML_RESOURCE_MAX_SERIALBUSTYPE)) {
-                       ACPI_RESOURCE_ERROR((AE_INFO,
-                                            "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
-                                            aml_resource->common_serial_bus.
-                                            type));
+                       if (walk_state) {
+                               ACPI_ERROR((AE_INFO,
+                                           "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
+                                           aml_resource->common_serial_bus.
+                                           type));
+                       }
                        return (AE_AML_INVALID_RESOURCE_TYPE);
                }
        }
@@ -645,18 +645,22 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
 
       invalid_resource:
 
-       ACPI_RESOURCE_ERROR((AE_INFO,
-                            "Invalid/unsupported resource descriptor: Type 0x%2.2X",
-                            resource_type));
+       if (walk_state) {
+               ACPI_ERROR((AE_INFO,
+                           "Invalid/unsupported resource descriptor: Type 0x%2.2X",
+                           resource_type));
+       }
        return (AE_AML_INVALID_RESOURCE_TYPE);
 
       bad_resource_length:
 
-       ACPI_RESOURCE_ERROR((AE_INFO,
-                            "Invalid resource descriptor length: Type "
-                            "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
-                            resource_type, resource_length,
-                            minimum_resource_length));
+       if (walk_state) {
+               ACPI_ERROR((AE_INFO,
+                           "Invalid resource descriptor length: Type "
+                           "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
+                           resource_type, resource_length,
+                           minimum_resource_length));
+       }
        return (AE_AML_BAD_RESOURCE_LENGTH);
 }
 
@@ -800,8 +804,7 @@ u32 acpi_ut_get_descriptor_length(void *aml)
  ******************************************************************************/
 
 acpi_status
-acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc,
-                            u8 ** end_tag)
+acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag)
 {
        acpi_status status;
 
@@ -816,7 +819,7 @@ acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc,
 
        /* Validate the template and get a pointer to the end_tag */
 
-       status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer,
+       status = acpi_ut_walk_aml_resources(NULL, obj_desc->buffer.pointer,
                                            obj_desc->buffer.length, NULL,
                                            (void **)end_tag);
 
index cee0473..a6b729d 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -97,14 +97,13 @@ void
 acpi_ut_push_generic_state(union acpi_generic_state **list_head,
                           union acpi_generic_state *state)
 {
-       ACPI_FUNCTION_TRACE(ut_push_generic_state);
+       ACPI_FUNCTION_ENTRY();
 
        /* Push the state object onto the front of the list (stack) */
 
        state->common.next = *list_head;
        *list_head = state;
-
-       return_VOID;
+       return;
 }
 
 /*******************************************************************************
@@ -124,7 +123,7 @@ union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
 {
        union acpi_generic_state *state;
 
-       ACPI_FUNCTION_TRACE(ut_pop_generic_state);
+       ACPI_FUNCTION_ENTRY();
 
        /* Remove the state object at the head of the list (stack) */
 
@@ -136,7 +135,7 @@ union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
                *list_head = state->common.next;
        }
 
-       return_PTR(state);
+       return (state);
 }
 
 /*******************************************************************************
@@ -186,13 +185,13 @@ struct acpi_thread_state *acpi_ut_create_thread_state(void)
 {
        union acpi_generic_state *state;
 
-       ACPI_FUNCTION_TRACE(ut_create_thread_state);
+       ACPI_FUNCTION_ENTRY();
 
        /* Create the generic state object */
 
        state = acpi_ut_create_generic_state();
        if (!state) {
-               return_PTR(NULL);
+               return (NULL);
        }
 
        /* Init fields specific to the update struct */
@@ -207,7 +206,7 @@ struct acpi_thread_state *acpi_ut_create_thread_state(void)
                state->thread.thread_id = (acpi_thread_id) 1;
        }
 
-       return_PTR((struct acpi_thread_state *)state);
+       return ((struct acpi_thread_state *)state);
 }
 
 /*******************************************************************************
@@ -230,13 +229,13 @@ union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
 {
        union acpi_generic_state *state;
 
-       ACPI_FUNCTION_TRACE_PTR(ut_create_update_state, object);
+       ACPI_FUNCTION_ENTRY();
 
        /* Create the generic state object */
 
        state = acpi_ut_create_generic_state();
        if (!state) {
-               return_PTR(NULL);
+               return (NULL);
        }
 
        /* Init fields specific to the update struct */
@@ -244,8 +243,7 @@ union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
        state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE;
        state->update.object = object;
        state->update.value = action;
-
-       return_PTR(state);
+       return (state);
 }
 
 /*******************************************************************************
@@ -267,13 +265,13 @@ union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
 {
        union acpi_generic_state *state;
 
-       ACPI_FUNCTION_TRACE_PTR(ut_create_pkg_state, internal_object);
+       ACPI_FUNCTION_ENTRY();
 
        /* Create the generic state object */
 
        state = acpi_ut_create_generic_state();
        if (!state) {
-               return_PTR(NULL);
+               return (NULL);
        }
 
        /* Init fields specific to the update struct */
@@ -283,8 +281,7 @@ union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
        state->pkg.dest_object = external_object;
        state->pkg.index = index;
        state->pkg.num_packages = 1;
-
-       return_PTR(state);
+       return (state);
 }
 
 /*******************************************************************************
@@ -304,21 +301,20 @@ union acpi_generic_state *acpi_ut_create_control_state(void)
 {
        union acpi_generic_state *state;
 
-       ACPI_FUNCTION_TRACE(ut_create_control_state);
+       ACPI_FUNCTION_ENTRY();
 
        /* Create the generic state object */
 
        state = acpi_ut_create_generic_state();
        if (!state) {
-               return_PTR(NULL);
+               return (NULL);
        }
 
        /* Init fields specific to the control struct */
 
        state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL;
        state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
-
-       return_PTR(state);
+       return (state);
 }
 
 /*******************************************************************************
@@ -336,12 +332,12 @@ union acpi_generic_state *acpi_ut_create_control_state(void)
 
 void acpi_ut_delete_generic_state(union acpi_generic_state *state)
 {
-       ACPI_FUNCTION_TRACE(ut_delete_generic_state);
+       ACPI_FUNCTION_ENTRY();
 
        /* Ignore null state */
 
        if (state) {
                (void)acpi_os_release_object(acpi_gbl_state_cache, state);
        }
-       return_VOID;
+       return;
 }
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c
new file mode 100644 (file)
index 0000000..b3e36a8
--- /dev/null
@@ -0,0 +1,574 @@
+/*******************************************************************************
+ *
+ * Module Name: utstring - Common functions for strings and characters
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utstring")
+
+/*
+ * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
+ * version of strtoul.
+ */
+#ifdef ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_strlwr (strlwr)
+ *
+ * PARAMETERS:  src_string      - The source string to convert
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Convert string to lowercase
+ *
+ * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
+ *
+ ******************************************************************************/
+void acpi_ut_strlwr(char *src_string)
+{
+       char *string;
+
+       ACPI_FUNCTION_ENTRY();
+
+       if (!src_string) {
+               return;
+       }
+
+       /* Walk entire string, lowercasing the letters */
+
+       for (string = src_string; *string; string++) {
+               *string = (char)ACPI_TOLOWER(*string);
+       }
+
+       return;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_stricmp (stricmp)
+ *
+ * PARAMETERS:  string1             - first string to compare
+ *              string2             - second string to compare
+ *
+ * RETURN:      int that signifies string relationship. Zero means strings
+ *              are equal.
+ *
+ * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
+ *              strings with no case sensitivity)
+ *
+ ******************************************************************************/
+
+int acpi_ut_stricmp(char *string1, char *string2)
+{
+       int c1;
+       int c2;
+
+       do {
+               c1 = tolower((int)*string1);
+               c2 = tolower((int)*string2);
+
+               string1++;
+               string2++;
+       }
+       while ((c1 == c2) && (c1));
+
+       return (c1 - c2);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_strupr (strupr)
+ *
+ * PARAMETERS:  src_string      - The source string to convert
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Convert string to uppercase
+ *
+ * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
+ *
+ ******************************************************************************/
+
+void acpi_ut_strupr(char *src_string)
+{
+       char *string;
+
+       ACPI_FUNCTION_ENTRY();
+
+       if (!src_string) {
+               return;
+       }
+
+       /* Walk entire string, uppercasing the letters */
+
+       for (string = src_string; *string; string++) {
+               *string = (char)ACPI_TOUPPER(*string);
+       }
+
+       return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_strtoul64
+ *
+ * PARAMETERS:  string          - Null terminated string
+ *              base            - Radix of the string: 16 or ACPI_ANY_BASE;
+ *                                ACPI_ANY_BASE means 'in behalf of to_integer'
+ *              ret_integer     - Where the converted integer is returned
+ *
+ * RETURN:      Status and Converted value
+ *
+ * DESCRIPTION: Convert a string into an unsigned value. Performs either a
+ *              32-bit or 64-bit conversion, depending on the current mode
+ *              of the interpreter.
+ *              NOTE: Does not support Octal strings, not needed.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
+{
+       u32 this_digit = 0;
+       u64 return_value = 0;
+       u64 quotient;
+       u64 dividend;
+       u32 to_integer_op = (base == ACPI_ANY_BASE);
+       u32 mode32 = (acpi_gbl_integer_byte_width == 4);
+       u8 valid_digits = 0;
+       u8 sign_of0x = 0;
+       u8 term = 0;
+
+       ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
+
+       switch (base) {
+       case ACPI_ANY_BASE:
+       case 16:
+               break;
+
+       default:
+               /* Invalid Base */
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       if (!string) {
+               goto error_exit;
+       }
+
+       /* Skip over any white space in the buffer */
+
+       while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
+               string++;
+       }
+
+       if (to_integer_op) {
+               /*
+                * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
+                * We need to determine if it is decimal or hexadecimal.
+                */
+               if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
+                       sign_of0x = 1;
+                       base = 16;
+
+                       /* Skip over the leading '0x' */
+                       string += 2;
+               } else {
+                       base = 10;
+               }
+       }
+
+       /* Any string left? Check that '0x' is not followed by white space. */
+
+       if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
+               if (to_integer_op) {
+                       goto error_exit;
+               } else {
+                       goto all_done;
+               }
+       }
+
+       /*
+        * Perform a 32-bit or 64-bit conversion, depending upon the current
+        * execution mode of the interpreter
+        */
+       dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
+
+       /* Main loop: convert the string to a 32- or 64-bit integer */
+
+       while (*string) {
+               if (ACPI_IS_DIGIT(*string)) {
+
+                       /* Convert ASCII 0-9 to Decimal value */
+
+                       this_digit = ((u8)*string) - '0';
+               } else if (base == 10) {
+
+                       /* Digit is out of range; possible in to_integer case only */
+
+                       term = 1;
+               } else {
+                       this_digit = (u8)ACPI_TOUPPER(*string);
+                       if (ACPI_IS_XDIGIT((char)this_digit)) {
+
+                               /* Convert ASCII Hex char to value */
+
+                               this_digit = this_digit - 'A' + 10;
+                       } else {
+                               term = 1;
+                       }
+               }
+
+               if (term) {
+                       if (to_integer_op) {
+                               goto error_exit;
+                       } else {
+                               break;
+                       }
+               } else if ((valid_digits == 0) && (this_digit == 0)
+                          && !sign_of0x) {
+
+                       /* Skip zeros */
+                       string++;
+                       continue;
+               }
+
+               valid_digits++;
+
+               if (sign_of0x
+                   && ((valid_digits > 16)
+                       || ((valid_digits > 8) && mode32))) {
+                       /*
+                        * This is to_integer operation case.
+                        * No any restrictions for string-to-integer conversion,
+                        * see ACPI spec.
+                        */
+                       goto error_exit;
+               }
+
+               /* Divide the digit into the correct position */
+
+               (void)acpi_ut_short_divide((dividend - (u64)this_digit),
+                                          base, &quotient, NULL);
+
+               if (return_value > quotient) {
+                       if (to_integer_op) {
+                               goto error_exit;
+                       } else {
+                               break;
+                       }
+               }
+
+               return_value *= base;
+               return_value += this_digit;
+               string++;
+       }
+
+       /* All done, normal exit */
+
+      all_done:
+
+       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+                         ACPI_FORMAT_UINT64(return_value)));
+
+       *ret_integer = return_value;
+       return_ACPI_STATUS(AE_OK);
+
+      error_exit:
+       /* Base was set/validated above */
+
+       if (base == 10) {
+               return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
+       } else {
+               return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_print_string
+ *
+ * PARAMETERS:  string          - Null terminated ASCII string
+ *              max_length      - Maximum output length
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
+ *              sequences.
+ *
+ ******************************************************************************/
+
+void acpi_ut_print_string(char *string, u8 max_length)
+{
+       u32 i;
+
+       if (!string) {
+               acpi_os_printf("<\"NULL STRING PTR\">");
+               return;
+       }
+
+       acpi_os_printf("\"");
+       for (i = 0; string[i] && (i < max_length); i++) {
+
+               /* Escape sequences */
+
+               switch (string[i]) {
+               case 0x07:
+                       acpi_os_printf("\\a");  /* BELL */
+                       break;
+
+               case 0x08:
+                       acpi_os_printf("\\b");  /* BACKSPACE */
+                       break;
+
+               case 0x0C:
+                       acpi_os_printf("\\f");  /* FORMFEED */
+                       break;
+
+               case 0x0A:
+                       acpi_os_printf("\\n");  /* LINEFEED */
+                       break;
+
+               case 0x0D:
+                       acpi_os_printf("\\r");  /* CARRIAGE RETURN */
+                       break;
+
+               case 0x09:
+                       acpi_os_printf("\\t");  /* HORIZONTAL TAB */
+                       break;
+
+               case 0x0B:
+                       acpi_os_printf("\\v");  /* VERTICAL TAB */
+                       break;
+
+               case '\'':      /* Single Quote */
+               case '\"':      /* Double Quote */
+               case '\\':      /* Backslash */
+                       acpi_os_printf("\\%c", (int)string[i]);
+                       break;
+
+               default:
+
+                       /* Check for printable character or hex escape */
+
+                       if (ACPI_IS_PRINT(string[i])) {
+                               /* This is a normal character */
+
+                               acpi_os_printf("%c", (int)string[i]);
+                       } else {
+                               /* All others will be Hex escapes */
+
+                               acpi_os_printf("\\x%2.2X", (s32) string[i]);
+                       }
+                       break;
+               }
+       }
+       acpi_os_printf("\"");
+
+       if (i == max_length && string[i]) {
+               acpi_os_printf("...");
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_valid_acpi_char
+ *
+ * PARAMETERS:  char            - The character to be examined
+ *              position        - Byte position (0-3)
+ *
+ * RETURN:      TRUE if the character is valid, FALSE otherwise
+ *
+ * DESCRIPTION: Check for a valid ACPI character. Must be one of:
+ *              1) Upper case alpha
+ *              2) numeric
+ *              3) underscore
+ *
+ *              We allow a '!' as the last character because of the ASF! table
+ *
+ ******************************************************************************/
+
+u8 acpi_ut_valid_acpi_char(char character, u32 position)
+{
+
+       if (!((character >= 'A' && character <= 'Z') ||
+             (character >= '0' && character <= '9') || (character == '_'))) {
+
+               /* Allow a '!' in the last position */
+
+               if (character == '!' && position == 3) {
+                       return (TRUE);
+               }
+
+               return (FALSE);
+       }
+
+       return (TRUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_valid_acpi_name
+ *
+ * PARAMETERS:  name            - The name to be examined
+ *
+ * RETURN:      TRUE if the name is valid, FALSE otherwise
+ *
+ * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
+ *              1) Upper case alpha
+ *              2) numeric
+ *              3) underscore
+ *
+ ******************************************************************************/
+
+u8 acpi_ut_valid_acpi_name(u32 name)
+{
+       u32 i;
+
+       ACPI_FUNCTION_ENTRY();
+
+       for (i = 0; i < ACPI_NAME_SIZE; i++) {
+               if (!acpi_ut_valid_acpi_char
+                   ((ACPI_CAST_PTR(char, &name))[i], i)) {
+                       return (FALSE);
+               }
+       }
+
+       return (TRUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_repair_name
+ *
+ * PARAMETERS:  name            - The ACPI name to be repaired
+ *
+ * RETURN:      Repaired version of the name
+ *
+ * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
+ *              return the new name. NOTE: the Name parameter must reside in
+ *              read/write memory, cannot be a const.
+ *
+ * An ACPI Name must consist of valid ACPI characters. We will repair the name
+ * if necessary because we don't want to abort because of this, but we want
+ * all namespace names to be printable. A warning message is appropriate.
+ *
+ * This issue came up because there are in fact machines that exhibit
+ * this problem, and we want to be able to enable ACPI support for them,
+ * even though there are a few bad names.
+ *
+ ******************************************************************************/
+
+void acpi_ut_repair_name(char *name)
+{
+       u32 i;
+       u8 found_bad_char = FALSE;
+       u32 original_name;
+
+       ACPI_FUNCTION_NAME(ut_repair_name);
+
+       ACPI_MOVE_NAME(&original_name, name);
+
+       /* Check each character in the name */
+
+       for (i = 0; i < ACPI_NAME_SIZE; i++) {
+               if (acpi_ut_valid_acpi_char(name[i], i)) {
+                       continue;
+               }
+
+               /*
+                * Replace a bad character with something printable, yet technically
+                * still invalid. This prevents any collisions with existing "good"
+                * names in the namespace.
+                */
+               name[i] = '*';
+               found_bad_char = TRUE;
+       }
+
+       if (found_bad_char) {
+
+               /* Report warning only if in strict mode or debug mode */
+
+               if (!acpi_gbl_enable_interpreter_slack) {
+                       ACPI_WARNING((AE_INFO,
+                                     "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
+                                     original_name, name));
+               } else {
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                         "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
+                                         original_name, name));
+               }
+       }
+}
+
+#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
+/*******************************************************************************
+ *
+ * FUNCTION:    ut_convert_backslashes
+ *
+ * PARAMETERS:  pathname        - File pathname string to be converted
+ *
+ * RETURN:      Modifies the input Pathname
+ *
+ * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
+ *              the entire input file pathname string.
+ *
+ ******************************************************************************/
+
+void ut_convert_backslashes(char *pathname)
+{
+
+       if (!pathname) {
+               return;
+       }
+
+       while (*pathname) {
+               if (*pathname == '\\') {
+                       *pathname = '/';
+               }
+
+               pathname++;
+       }
+}
+#endif
index a424a9e..62774c7 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -436,10 +436,10 @@ acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
        struct acpi_memory_list *mem_list;
        acpi_status status;
 
-       ACPI_FUNCTION_TRACE(ut_remove_allocation);
+       ACPI_FUNCTION_NAME(ut_remove_allocation);
 
        if (acpi_gbl_disable_mem_tracking) {
-               return_ACPI_STATUS(AE_OK);
+               return (AE_OK);
        }
 
        mem_list = acpi_gbl_global_list;
@@ -450,12 +450,12 @@ acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
                ACPI_ERROR((module, line,
                            "Empty allocation list, nothing to free!"));
 
-               return_ACPI_STATUS(AE_OK);
+               return (AE_OK);
        }
 
        status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
        if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
+               return (status);
        }
 
        /* Unlink */
@@ -470,15 +470,15 @@ acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
                (allocation->next)->previous = allocation->previous;
        }
 
+       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n",
+                         &allocation->user_space, allocation->size));
+
        /* Mark the segment as deleted */
 
        ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size);
 
-       ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
-                         allocation->size));
-
        status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
-       return_ACPI_STATUS(status);
+       return (status);
 }
 
 /*******************************************************************************
index 390db0c..48efb44 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "acevents.h"
-#include "acnamesp.h"
 #include "acdebug.h"
-#include "actables.h"
-#include "acinterp.h"
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utxface")
index d4d3826..976b6c7 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -297,9 +297,9 @@ ACPI_EXPORT_SYMBOL(acpi_bios_warning)
  *
  * PARAMETERS:  module_name     - Caller's module name (for error output)
  *              line_number     - Caller's line number (for error output)
- *              Pathname        - Full pathname to the node
+ *              pathname        - Full pathname to the node
  *              node_flags      - From Namespace node for the method/object
- *              Format          - Printf format string + additional args
+ *              format          - Printf format string + additional args
  *
  * RETURN:      None
  *
index 14f5236..41ebaaf 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0a40a85..3122997 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7efaeaa..c5cd5b5 100644 (file)
@@ -1111,7 +1111,7 @@ fail:
        return result;
 }
 
-static int acpi_battery_remove(struct acpi_device *device, int type)
+static int acpi_battery_remove(struct acpi_device *device)
 {
        struct acpi_battery *battery = NULL;
 
index 1f0d457..01708a1 100644 (file)
@@ -178,276 +178,6 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data)
 }
 EXPORT_SYMBOL(acpi_bus_get_private_data);
 
-/* --------------------------------------------------------------------------
-                                 Power Management
-   -------------------------------------------------------------------------- */
-
-static const char *state_string(int state)
-{
-       switch (state) {
-       case ACPI_STATE_D0:
-               return "D0";
-       case ACPI_STATE_D1:
-               return "D1";
-       case ACPI_STATE_D2:
-               return "D2";
-       case ACPI_STATE_D3_HOT:
-               return "D3hot";
-       case ACPI_STATE_D3_COLD:
-               return "D3";
-       default:
-               return "(unknown)";
-       }
-}
-
-static int __acpi_bus_get_power(struct acpi_device *device, int *state)
-{
-       int result = ACPI_STATE_UNKNOWN;
-
-       if (!device || !state)
-               return -EINVAL;
-
-       if (!device->flags.power_manageable) {
-               /* TBD: Non-recursive algorithm for walking up hierarchy. */
-               *state = device->parent ?
-                       device->parent->power.state : ACPI_STATE_D0;
-               goto out;
-       }
-
-       /*
-        * Get the device's power state either directly (via _PSC) or
-        * indirectly (via power resources).
-        */
-       if (device->power.flags.explicit_get) {
-               unsigned long long psc;
-               acpi_status status = acpi_evaluate_integer(device->handle,
-                                                          "_PSC", NULL, &psc);
-               if (ACPI_FAILURE(status))
-                       return -ENODEV;
-
-               result = psc;
-       }
-       /* The test below covers ACPI_STATE_UNKNOWN too. */
-       if (result <= ACPI_STATE_D2) {
-         ; /* Do nothing. */
-       } else if (device->power.flags.power_resources) {
-               int error = acpi_power_get_inferred_state(device, &result);
-               if (error)
-                       return error;
-       } else if (result == ACPI_STATE_D3_HOT) {
-               result = ACPI_STATE_D3;
-       }
-
-       /*
-        * If we were unsure about the device parent's power state up to this
-        * point, the fact that the device is in D0 implies that the parent has
-        * to be in D0 too.
-        */
-       if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN
-           && result == ACPI_STATE_D0)
-               device->parent->power.state = ACPI_STATE_D0;
-
-       *state = result;
-
- out:
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n",
-                         device->pnp.bus_id, state_string(*state)));
-
-       return 0;
-}
-
-
-/**
- * acpi_device_set_power - Set power state of an ACPI device.
- * @device: Device to set the power state of.
- * @state: New power state to set.
- *
- * Callers must ensure that the device is power manageable before using this
- * function.
- */
-int acpi_device_set_power(struct acpi_device *device, int state)
-{
-       int result = 0;
-       acpi_status status = AE_OK;
-       char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
-
-       if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
-               return -EINVAL;
-
-       /* Make sure this is a valid target state */
-
-       if (state == device->power.state) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at %s\n",
-                                 state_string(state)));
-               return 0;
-       }
-
-       if (!device->power.states[state].flags.valid) {
-               printk(KERN_WARNING PREFIX "Device does not support %s\n",
-                      state_string(state));
-               return -ENODEV;
-       }
-       if (device->parent && (state < device->parent->power.state)) {
-               printk(KERN_WARNING PREFIX
-                             "Cannot set device to a higher-powered"
-                             " state than parent\n");
-               return -ENODEV;
-       }
-
-       /* For D3cold we should execute _PS3, not _PS4. */
-       if (state == ACPI_STATE_D3_COLD)
-               object_name[3] = '3';
-
-       /*
-        * Transition Power
-        * ----------------
-        * On transitions to a high-powered state we first apply power (via
-        * power resources) then evalute _PSx.  Conversly for transitions to
-        * a lower-powered state.
-        */
-       if (state < device->power.state) {
-               if (device->power.state >= ACPI_STATE_D3_HOT &&
-                   state != ACPI_STATE_D0) {
-                       printk(KERN_WARNING PREFIX
-                             "Cannot transition to non-D0 state from D3\n");
-                       return -ENODEV;
-               }
-               if (device->power.flags.power_resources) {
-                       result = acpi_power_transition(device, state);
-                       if (result)
-                               goto end;
-               }
-               if (device->power.states[state].flags.explicit_set) {
-                       status = acpi_evaluate_object(device->handle,
-                                                     object_name, NULL, NULL);
-                       if (ACPI_FAILURE(status)) {
-                               result = -ENODEV;
-                               goto end;
-                       }
-               }
-       } else {
-               if (device->power.states[state].flags.explicit_set) {
-                       status = acpi_evaluate_object(device->handle,
-                                                     object_name, NULL, NULL);
-                       if (ACPI_FAILURE(status)) {
-                               result = -ENODEV;
-                               goto end;
-                       }
-               }
-               if (device->power.flags.power_resources) {
-                       result = acpi_power_transition(device, state);
-                       if (result)
-                               goto end;
-               }
-       }
-
-      end:
-       if (result)
-               printk(KERN_WARNING PREFIX
-                             "Device [%s] failed to transition to %s\n",
-                             device->pnp.bus_id, state_string(state));
-       else {
-               device->power.state = state;
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Device [%s] transitioned to %s\n",
-                                 device->pnp.bus_id, state_string(state)));
-       }
-
-       return result;
-}
-EXPORT_SYMBOL(acpi_device_set_power);
-
-
-int acpi_bus_set_power(acpi_handle handle, int state)
-{
-       struct acpi_device *device;
-       int result;
-
-       result = acpi_bus_get_device(handle, &device);
-       if (result)
-               return result;
-
-       if (!device->flags.power_manageable) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                               "Device [%s] is not power manageable\n",
-                               dev_name(&device->dev)));
-               return -ENODEV;
-       }
-
-       return acpi_device_set_power(device, state);
-}
-EXPORT_SYMBOL(acpi_bus_set_power);
-
-
-int acpi_bus_init_power(struct acpi_device *device)
-{
-       int state;
-       int result;
-
-       if (!device)
-               return -EINVAL;
-
-       device->power.state = ACPI_STATE_UNKNOWN;
-
-       result = __acpi_bus_get_power(device, &state);
-       if (result)
-               return result;
-
-       if (device->power.flags.power_resources)
-               result = acpi_power_on_resources(device, state);
-
-       if (!result)
-               device->power.state = state;
-
-       return result;
-}
-
-
-int acpi_bus_update_power(acpi_handle handle, int *state_p)
-{
-       struct acpi_device *device;
-       int state;
-       int result;
-
-       result = acpi_bus_get_device(handle, &device);
-       if (result)
-               return result;
-
-       result = __acpi_bus_get_power(device, &state);
-       if (result)
-               return result;
-
-       result = acpi_device_set_power(device, state);
-       if (!result && state_p)
-               *state_p = state;
-
-       return result;
-}
-EXPORT_SYMBOL_GPL(acpi_bus_update_power);
-
-
-bool acpi_bus_power_manageable(acpi_handle handle)
-{
-       struct acpi_device *device;
-       int result;
-
-       result = acpi_bus_get_device(handle, &device);
-       return result ? false : device->flags.power_manageable;
-}
-
-EXPORT_SYMBOL(acpi_bus_power_manageable);
-
-bool acpi_bus_can_wakeup(acpi_handle handle)
-{
-       struct acpi_device *device;
-       int result;
-
-       result = acpi_bus_get_device(handle, &device);
-       return result ? false : device->wakeup.flags.valid;
-}
-
-EXPORT_SYMBOL(acpi_bus_can_wakeup);
-
 static void acpi_print_osc_error(acpi_handle handle,
        struct acpi_osc_context *context, char *error)
 {
index f0d936b..86c7d54 100644 (file)
@@ -75,7 +75,7 @@ static const struct acpi_device_id button_device_ids[] = {
 MODULE_DEVICE_TABLE(acpi, button_device_ids);
 
 static int acpi_button_add(struct acpi_device *device);
-static int acpi_button_remove(struct acpi_device *device, int type);
+static int acpi_button_remove(struct acpi_device *device);
 static void acpi_button_notify(struct acpi_device *device, u32 event);
 
 #ifdef CONFIG_PM_SLEEP
@@ -433,7 +433,7 @@ static int acpi_button_add(struct acpi_device *device)
        return error;
 }
 
-static int acpi_button_remove(struct acpi_device *device, int type)
+static int acpi_button_remove(struct acpi_device *device)
 {
        struct acpi_button *button = acpi_driver_data(device);
 
index 811910b..5523ba7 100644 (file)
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
-#include <acpi/container.h>
 
 #define PREFIX "ACPI: "
 
-#define ACPI_CONTAINER_DEVICE_NAME     "ACPI container device"
-#define ACPI_CONTAINER_CLASS           "container"
-
-#define INSTALL_NOTIFY_HANDLER         1
-#define UNINSTALL_NOTIFY_HANDLER       2
-
 #define _COMPONENT                     ACPI_CONTAINER_COMPONENT
 ACPI_MODULE_NAME("container");
 
-MODULE_AUTHOR("Anil S Keshavamurthy");
-MODULE_DESCRIPTION("ACPI container driver");
-MODULE_LICENSE("GPL");
-
-static int acpi_container_add(struct acpi_device *device);
-static int acpi_container_remove(struct acpi_device *device, int type);
-
 static const struct acpi_device_id container_device_ids[] = {
        {"ACPI0004", 0},
        {"PNP0A05", 0},
        {"PNP0A06", 0},
        {"", 0},
 };
-MODULE_DEVICE_TABLE(acpi, container_device_ids);
 
-static struct acpi_driver acpi_container_driver = {
-       .name = "container",
-       .class = ACPI_CONTAINER_CLASS,
+static int container_device_attach(struct acpi_device *device,
+                                  const struct acpi_device_id *not_used)
+{
+       /*
+        * FIXME: This is necessary, so that acpi_eject_store() doesn't return
+        * -ENODEV for containers.
+        */
+       return 1;
+}
+
+static struct acpi_scan_handler container_device_handler = {
        .ids = container_device_ids,
-       .ops = {
-               .add = acpi_container_add,
-               .remove = acpi_container_remove,
-               },
+       .attach = container_device_attach,
 };
 
-/*******************************************************************/
-
 static int is_device_present(acpi_handle handle)
 {
        acpi_handle temp;
@@ -92,73 +80,6 @@ static int is_device_present(acpi_handle handle)
        return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT);
 }
 
-static bool is_container_device(const char *hid)
-{
-       const struct acpi_device_id *container_id;
-
-       for (container_id = container_device_ids;
-            container_id->id[0]; container_id++) {
-               if (!strcmp((char *)container_id->id, hid))
-                       return true;
-       }
-
-       return false;
-}
-
-/*******************************************************************/
-static int acpi_container_add(struct acpi_device *device)
-{
-       struct acpi_container *container;
-
-       container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
-       if (!container)
-               return -ENOMEM;
-
-       container->handle = device->handle;
-       strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
-       strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
-       device->driver_data = container;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
-                         acpi_device_name(device), acpi_device_bid(device)));
-
-       return 0;
-}
-
-static int acpi_container_remove(struct acpi_device *device, int type)
-{
-       acpi_status status = AE_OK;
-       struct acpi_container *pc = NULL;
-
-       pc = acpi_driver_data(device);
-       kfree(pc);
-       return status;
-}
-
-static int container_device_add(struct acpi_device **device, acpi_handle handle)
-{
-       acpi_handle phandle;
-       struct acpi_device *pdev;
-       int result;
-
-
-       if (acpi_get_parent(handle, &phandle)) {
-               return -ENODEV;
-       }
-
-       if (acpi_bus_get_device(phandle, &pdev)) {
-               return -ENODEV;
-       }
-
-       if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_DEVICE)) {
-               return -ENODEV;
-       }
-
-       result = acpi_bus_start(*device);
-
-       return result;
-}
-
 static void container_notify_cb(acpi_handle handle, u32 type, void *context)
 {
        struct acpi_device *device = NULL;
@@ -167,6 +88,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
        acpi_status status;
        u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
 
+       acpi_scan_lock_acquire();
+
        switch (type) {
        case ACPI_NOTIFY_BUS_CHECK:
                /* Fall through */
@@ -182,7 +105,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
                                /* device exist and this is a remove request */
                                device->flags.eject_pending = 1;
                                kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
-                               return;
+                               goto out;
                        }
                        break;
                }
@@ -190,11 +113,16 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
                if (!ACPI_FAILURE(status) || device)
                        break;
 
-               result = container_device_add(&device, handle);
+               result = acpi_bus_scan(handle);
                if (result) {
                        acpi_handle_warn(handle, "Failed to add container\n");
                        break;
                }
+               result = acpi_bus_get_device(handle, &device);
+               if (result) {
+                       acpi_handle_warn(handle, "Missing device object\n");
+                       break;
+               }
 
                kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
                ost_code = ACPI_OST_SC_SUCCESS;
@@ -204,98 +132,59 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
                if (!acpi_bus_get_device(handle, &device) && device) {
                        device->flags.eject_pending = 1;
                        kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
-                       return;
+                       goto out;
                }
                break;
 
        default:
                /* non-hotplug event; possibly handled by other handler */
-               return;
+               goto out;
        }
 
        /* Inform firmware that the hotplug operation has completed */
        (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
-       return;
+
+ out:
+       acpi_scan_lock_release();
 }
 
-static acpi_status
-container_walk_namespace_cb(acpi_handle handle,
-                           u32 lvl, void *context, void **rv)
+static bool is_container(acpi_handle handle)
 {
-       char *hid = NULL;
        struct acpi_device_info *info;
-       acpi_status status;
-       int *action = context;
-
-       status = acpi_get_object_info(handle, &info);
-       if (ACPI_FAILURE(status)) {
-               return AE_OK;
-       }
+       bool ret = false;
 
-       if (info->valid & ACPI_VALID_HID)
-               hid = info->hardware_id.string;
+       if (ACPI_FAILURE(acpi_get_object_info(handle, &info)))
+               return false;
 
-       if (hid == NULL) {
-               goto end;
-       }
-
-       if (!is_container_device(hid))
-               goto end;
+       if (info->valid & ACPI_VALID_HID) {
+               const struct acpi_device_id *id;
 
-       switch (*action) {
-       case INSTALL_NOTIFY_HANDLER:
-               acpi_install_notify_handler(handle,
-                                           ACPI_SYSTEM_NOTIFY,
-                                           container_notify_cb, NULL);
-               break;
-       case UNINSTALL_NOTIFY_HANDLER:
-               acpi_remove_notify_handler(handle,
-                                          ACPI_SYSTEM_NOTIFY,
-                                          container_notify_cb);
-               break;
-       default:
-               break;
+               for (id = container_device_ids; id->id[0]; id++) {
+                       ret = !strcmp((char *)id->id, info->hardware_id.string);
+                       if (ret)
+                               break;
+               }
        }
-
-      end:
        kfree(info);
-
-       return AE_OK;
+       return ret;
 }
 
-static int __init acpi_container_init(void)
+static acpi_status acpi_container_register_notify_handler(acpi_handle handle,
+                                                         u32 lvl, void *ctxt,
+                                                         void **retv)
 {
-       int result = 0;
-       int action = INSTALL_NOTIFY_HANDLER;
-
-       result = acpi_bus_register_driver(&acpi_container_driver);
-       if (result < 0) {
-               return (result);
-       }
-
-       /* register notify handler to every container device */
-       acpi_walk_namespace(ACPI_TYPE_DEVICE,
-                           ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX,
-                           container_walk_namespace_cb, NULL, &action, NULL);
+       if (is_container(handle))
+               acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+                                           container_notify_cb, NULL);
 
-       return (0);
+       return AE_OK;
 }
 
-static void __exit acpi_container_exit(void)
+void __init acpi_container_init(void)
 {
-       int action = UNINSTALL_NOTIFY_HANDLER;
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+                           acpi_container_register_notify_handler, NULL,
+                           NULL, NULL);
 
-
-       acpi_walk_namespace(ACPI_TYPE_DEVICE,
-                           ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX,
-                           container_walk_namespace_cb, NULL, &action, NULL);
-
-       acpi_bus_unregister_driver(&acpi_container_driver);
-
-       return;
+       acpi_scan_add_handler(&container_device_handler);
 }
-
-module_init(acpi_container_init);
-module_exit(acpi_container_exit);
diff --git a/drivers/acpi/csrt.c b/drivers/acpi/csrt.c
new file mode 100644 (file)
index 0000000..5c15a91
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Support for Core System Resources Table (CSRT)
+ *
+ * Copyright (C) 2013, Intel Corporation
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *         Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "ACPI: CSRT: " fmt
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sizes.h>
+
+ACPI_MODULE_NAME("CSRT");
+
+static int __init acpi_csrt_parse_shared_info(struct platform_device *pdev,
+                                             const struct acpi_csrt_group *grp)
+{
+       const struct acpi_csrt_shared_info *si;
+       struct resource res[3];
+       size_t nres;
+       int ret;
+
+       memset(res, 0, sizeof(res));
+       nres = 0;
+
+       si = (const struct acpi_csrt_shared_info *)&grp[1];
+       /*
+        * The peripherals that are listed on CSRT typically support only
+        * 32-bit addresses so we only use the low part of MMIO base for
+        * now.
+        */
+       if (!si->mmio_base_high && si->mmio_base_low) {
+               /*
+                * There is no size of the memory resource in shared_info
+                * so we assume that it is 4k here.
+                */
+               res[nres].start = si->mmio_base_low;
+               res[nres].end = res[0].start + SZ_4K - 1;
+               res[nres++].flags = IORESOURCE_MEM;
+       }
+
+       if (si->gsi_interrupt) {
+               int irq = acpi_register_gsi(NULL, si->gsi_interrupt,
+                                           si->interrupt_mode,
+                                           si->interrupt_polarity);
+               res[nres].start = irq;
+               res[nres].end = irq;
+               res[nres++].flags = IORESOURCE_IRQ;
+       }
+
+       if (si->base_request_line || si->num_handshake_signals) {
+               /*
+                * We pass the driver a DMA resource describing the range
+                * of request lines the device supports.
+                */
+               res[nres].start = si->base_request_line;
+               res[nres].end = res[nres].start + si->num_handshake_signals - 1;
+               res[nres++].flags = IORESOURCE_DMA;
+       }
+
+       ret = platform_device_add_resources(pdev, res, nres);
+       if (ret) {
+               if (si->gsi_interrupt)
+                       acpi_unregister_gsi(si->gsi_interrupt);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int __init
+acpi_csrt_parse_resource_group(const struct acpi_csrt_group *grp)
+{
+       struct platform_device *pdev;
+       char vendor[5], name[16];
+       int ret, i;
+
+       vendor[0] = grp->vendor_id;
+       vendor[1] = grp->vendor_id >> 8;
+       vendor[2] = grp->vendor_id >> 16;
+       vendor[3] = grp->vendor_id >> 24;
+       vendor[4] = '\0';
+
+       if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info))
+               return -ENODEV;
+
+       snprintf(name, sizeof(name), "%s%04X", vendor, grp->device_id);
+       pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO);
+       if (!pdev)
+               return -ENOMEM;
+
+       /* Add resources based on the shared info */
+       ret = acpi_csrt_parse_shared_info(pdev, grp);
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pdev);
+       if (ret)
+               goto fail;
+
+       for (i = 0; i < pdev->num_resources; i++)
+               dev_dbg(&pdev->dev, "%pR\n", &pdev->resource[i]);
+
+       return 0;
+
+fail:
+       platform_device_put(pdev);
+       return ret;
+}
+
+/*
+ * CSRT or Core System Resources Table is a proprietary ACPI table
+ * introduced by Microsoft. This table can contain devices that are not in
+ * the system DSDT table. In particular DMA controllers might be described
+ * here.
+ *
+ * We present these devices as normal platform devices that don't have ACPI
+ * IDs or handle. The platform device name will be something like
+ * <VENDOR><DEVID>.<n>.auto for example: INTL9C06.0.auto.
+ */
+void __init acpi_csrt_init(void)
+{
+       struct acpi_csrt_group *grp, *end;
+       struct acpi_table_csrt *csrt;
+       acpi_status status;
+       int ret;
+
+       status = acpi_get_table(ACPI_SIG_CSRT, 0,
+                               (struct acpi_table_header **)&csrt);
+       if (ACPI_FAILURE(status)) {
+               if (status != AE_NOT_FOUND)
+                       pr_warn("failed to get the CSRT table\n");
+               return;
+       }
+
+       pr_debug("parsing CSRT table for devices\n");
+
+       grp = (struct acpi_csrt_group *)(csrt + 1);
+       end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length);
+
+       while (grp < end) {
+               ret = acpi_csrt_parse_resource_group(grp);
+               if (ret) {
+                       pr_warn("error in parsing resource group: %d\n", ret);
+                       return;
+               }
+
+               grp = (struct acpi_csrt_group *)((void *)grp + grp->length);
+       }
+}
index 5d42c24..6adfc70 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * debugfs.c - ACPI debugfs interface to userspace.
+ * custom_method.c - debugfs interface for customizing ACPI control method
  */
 
 #include <linux/init.h>
index c6ff606..dd314ef 100644 (file)
 
 #include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#include "internal.h"
+
+#define _COMPONENT     ACPI_POWER_COMPONENT
+ACPI_MODULE_NAME("device_pm");
 
 static DEFINE_MUTEX(acpi_pm_notifier_lock);
 
@@ -94,6 +100,293 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
 }
 
 /**
+ * acpi_power_state_string - String representation of ACPI device power state.
+ * @state: ACPI device power state to return the string representation of.
+ */
+const char *acpi_power_state_string(int state)
+{
+       switch (state) {
+       case ACPI_STATE_D0:
+               return "D0";
+       case ACPI_STATE_D1:
+               return "D1";
+       case ACPI_STATE_D2:
+               return "D2";
+       case ACPI_STATE_D3_HOT:
+               return "D3hot";
+       case ACPI_STATE_D3_COLD:
+               return "D3cold";
+       default:
+               return "(unknown)";
+       }
+}
+
+/**
+ * acpi_device_get_power - Get power state of an ACPI device.
+ * @device: Device to get the power state of.
+ * @state: Place to store the power state of the device.
+ *
+ * This function does not update the device's power.state field, but it may
+ * update its parent's power.state field (when the parent's power state is
+ * unknown and the device's power state turns out to be D0).
+ */
+int acpi_device_get_power(struct acpi_device *device, int *state)
+{
+       int result = ACPI_STATE_UNKNOWN;
+
+       if (!device || !state)
+               return -EINVAL;
+
+       if (!device->flags.power_manageable) {
+               /* TBD: Non-recursive algorithm for walking up hierarchy. */
+               *state = device->parent ?
+                       device->parent->power.state : ACPI_STATE_D0;
+               goto out;
+       }
+
+       /*
+        * Get the device's power state either directly (via _PSC) or
+        * indirectly (via power resources).
+        */
+       if (device->power.flags.explicit_get) {
+               unsigned long long psc;
+               acpi_status status = acpi_evaluate_integer(device->handle,
+                                                          "_PSC", NULL, &psc);
+               if (ACPI_FAILURE(status))
+                       return -ENODEV;
+
+               result = psc;
+       }
+       /* The test below covers ACPI_STATE_UNKNOWN too. */
+       if (result <= ACPI_STATE_D2) {
+         ; /* Do nothing. */
+       } else if (device->power.flags.power_resources) {
+               int error = acpi_power_get_inferred_state(device, &result);
+               if (error)
+                       return error;
+       } else if (result == ACPI_STATE_D3_HOT) {
+               result = ACPI_STATE_D3;
+       }
+
+       /*
+        * If we were unsure about the device parent's power state up to this
+        * point, the fact that the device is in D0 implies that the parent has
+        * to be in D0 too.
+        */
+       if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN
+           && result == ACPI_STATE_D0)
+               device->parent->power.state = ACPI_STATE_D0;
+
+       *state = result;
+
+ out:
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n",
+                         device->pnp.bus_id, acpi_power_state_string(*state)));
+
+       return 0;
+}
+
+static int acpi_dev_pm_explicit_set(struct acpi_device *adev, int state)
+{
+       if (adev->power.states[state].flags.explicit_set) {
+               char method[5] = { '_', 'P', 'S', '0' + state, '\0' };
+               acpi_status status;
+
+               status = acpi_evaluate_object(adev->handle, method, NULL, NULL);
+               if (ACPI_FAILURE(status))
+                       return -ENODEV;
+       }
+       return 0;
+}
+
+/**
+ * acpi_device_set_power - Set power state of an ACPI device.
+ * @device: Device to set the power state of.
+ * @state: New power state to set.
+ *
+ * Callers must ensure that the device is power manageable before using this
+ * function.
+ */
+int acpi_device_set_power(struct acpi_device *device, int state)
+{
+       int result = 0;
+       bool cut_power = false;
+
+       if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
+               return -EINVAL;
+
+       /* Make sure this is a valid target state */
+
+       if (state == device->power.state) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at %s\n",
+                                 acpi_power_state_string(state)));
+               return 0;
+       }
+
+       if (!device->power.states[state].flags.valid) {
+               printk(KERN_WARNING PREFIX "Device does not support %s\n",
+                      acpi_power_state_string(state));
+               return -ENODEV;
+       }
+       if (device->parent && (state < device->parent->power.state)) {
+               printk(KERN_WARNING PREFIX
+                             "Cannot set device to a higher-powered"
+                             " state than parent\n");
+               return -ENODEV;
+       }
+
+       /* For D3cold we should first transition into D3hot. */
+       if (state == ACPI_STATE_D3_COLD
+           && device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible) {
+               state = ACPI_STATE_D3_HOT;
+               cut_power = true;
+       }
+
+       if (state < device->power.state && state != ACPI_STATE_D0
+           && device->power.state >= ACPI_STATE_D3_HOT) {
+               printk(KERN_WARNING PREFIX
+                       "Cannot transition to non-D0 state from D3\n");
+               return -ENODEV;
+       }
+
+       /*
+        * Transition Power
+        * ----------------
+        * In accordance with the ACPI specification first apply power (via
+        * power resources) and then evalute _PSx.
+        */
+       if (device->power.flags.power_resources) {
+               result = acpi_power_transition(device, state);
+               if (result)
+                       goto end;
+       }
+       result = acpi_dev_pm_explicit_set(device, state);
+       if (result)
+               goto end;
+
+       if (cut_power) {
+               device->power.state = state;
+               state = ACPI_STATE_D3_COLD;
+               result = acpi_power_transition(device, state);
+       }
+
+ end:
+       if (result) {
+               printk(KERN_WARNING PREFIX
+                             "Device [%s] failed to transition to %s\n",
+                             device->pnp.bus_id,
+                             acpi_power_state_string(state));
+       } else {
+               device->power.state = state;
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                 "Device [%s] transitioned to %s\n",
+                                 device->pnp.bus_id,
+                                 acpi_power_state_string(state)));
+       }
+
+       return result;
+}
+EXPORT_SYMBOL(acpi_device_set_power);
+
+int acpi_bus_set_power(acpi_handle handle, int state)
+{
+       struct acpi_device *device;
+       int result;
+
+       result = acpi_bus_get_device(handle, &device);
+       if (result)
+               return result;
+
+       if (!device->flags.power_manageable) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                               "Device [%s] is not power manageable\n",
+                               dev_name(&device->dev)));
+               return -ENODEV;
+       }
+
+       return acpi_device_set_power(device, state);
+}
+EXPORT_SYMBOL(acpi_bus_set_power);
+
+int acpi_bus_init_power(struct acpi_device *device)
+{
+       int state;
+       int result;
+
+       if (!device)
+               return -EINVAL;
+
+       device->power.state = ACPI_STATE_UNKNOWN;
+
+       result = acpi_device_get_power(device, &state);
+       if (result)
+               return result;
+
+       if (state < ACPI_STATE_D3_COLD && device->power.flags.power_resources) {
+               result = acpi_power_on_resources(device, state);
+               if (result)
+                       return result;
+
+               result = acpi_dev_pm_explicit_set(device, state);
+               if (result)
+                       return result;
+       } else if (state == ACPI_STATE_UNKNOWN) {
+               /* No power resources and missing _PSC? Try to force D0. */
+               state = ACPI_STATE_D0;
+               result = acpi_dev_pm_explicit_set(device, state);
+               if (result)
+                       return result;
+       }
+       device->power.state = state;
+       return 0;
+}
+
+int acpi_bus_update_power(acpi_handle handle, int *state_p)
+{
+       struct acpi_device *device;
+       int state;
+       int result;
+
+       result = acpi_bus_get_device(handle, &device);
+       if (result)
+               return result;
+
+       result = acpi_device_get_power(device, &state);
+       if (result)
+               return result;
+
+       if (state == ACPI_STATE_UNKNOWN)
+               state = ACPI_STATE_D0;
+
+       result = acpi_device_set_power(device, state);
+       if (!result && state_p)
+               *state_p = state;
+
+       return result;
+}
+EXPORT_SYMBOL_GPL(acpi_bus_update_power);
+
+bool acpi_bus_power_manageable(acpi_handle handle)
+{
+       struct acpi_device *device;
+       int result;
+
+       result = acpi_bus_get_device(handle, &device);
+       return result ? false : device->flags.power_manageable;
+}
+EXPORT_SYMBOL(acpi_bus_power_manageable);
+
+bool acpi_bus_can_wakeup(acpi_handle handle)
+{
+       struct acpi_device *device;
+       int result;
+
+       result = acpi_bus_get_device(handle, &device);
+       return result ? false : device->wakeup.flags.valid;
+}
+EXPORT_SYMBOL(acpi_bus_can_wakeup);
+
+/**
  * acpi_device_power_state - Get preferred power state of ACPI device.
  * @dev: Device whose preferred target power state to return.
  * @adev: ACPI device node corresponding to @dev.
@@ -213,7 +506,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
        acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
        struct acpi_device *adev;
 
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
+       if (!handle || acpi_bus_get_device(handle, &adev)) {
                dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
                return -ENODEV;
        }
@@ -290,7 +583,7 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
                return -EINVAL;
 
        handle = DEVICE_ACPI_HANDLE(phys_dev);
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
+       if (!handle || acpi_bus_get_device(handle, &adev)) {
                dev_dbg(phys_dev, "ACPI handle without context in %s!\n",
                        __func__);
                return -ENODEV;
@@ -304,7 +597,7 @@ static inline void acpi_wakeup_device(acpi_handle handle, u32 event,
                                      void *context) {}
 #endif /* CONFIG_PM_RUNTIME */
 
- #ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM_SLEEP
 /**
  * __acpi_device_sleep_wake - Enable or disable device to wake up the system.
  * @dev: Device to enable/desible to wake up the system.
@@ -334,7 +627,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
                return -EINVAL;
 
        handle = DEVICE_ACPI_HANDLE(dev);
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
+       if (!handle || acpi_bus_get_device(handle, &adev)) {
                dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
                return -ENODEV;
        }
@@ -353,7 +646,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
  * acpi_dev_pm_get_node - Get ACPI device node for the given physical device.
  * @dev: Device to get the ACPI node for.
  */
-static struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
+struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
 {
        acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
        struct acpi_device *adev;
@@ -665,3 +958,59 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
        }
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
+
+/**
+ * acpi_dev_pm_add_dependent - Add physical device depending for PM.
+ * @handle: Handle of ACPI device node.
+ * @depdev: Device depending on that node for PM.
+ */
+void acpi_dev_pm_add_dependent(acpi_handle handle, struct device *depdev)
+{
+       struct acpi_device_physical_node *dep;
+       struct acpi_device *adev;
+
+       if (!depdev || acpi_bus_get_device(handle, &adev))
+               return;
+
+       mutex_lock(&adev->physical_node_lock);
+
+       list_for_each_entry(dep, &adev->power_dependent, node)
+               if (dep->dev == depdev)
+                       goto out;
+
+       dep = kzalloc(sizeof(*dep), GFP_KERNEL);
+       if (dep) {
+               dep->dev = depdev;
+               list_add_tail(&dep->node, &adev->power_dependent);
+       }
+
+ out:
+       mutex_unlock(&adev->physical_node_lock);
+}
+EXPORT_SYMBOL_GPL(acpi_dev_pm_add_dependent);
+
+/**
+ * acpi_dev_pm_remove_dependent - Remove physical device depending for PM.
+ * @handle: Handle of ACPI device node.
+ * @depdev: Device depending on that node for PM.
+ */
+void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev)
+{
+       struct acpi_device_physical_node *dep;
+       struct acpi_device *adev;
+
+       if (!depdev || acpi_bus_get_device(handle, &adev))
+               return;
+
+       mutex_lock(&adev->physical_node_lock);
+
+       list_for_each_entry(dep, &adev->power_dependent, node)
+               if (dep->dev == depdev) {
+                       list_del(&dep->node);
+                       kfree(dep);
+                       break;
+               }
+
+       mutex_unlock(&adev->physical_node_lock);
+}
+EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent);
index f32bd47..4fdea38 100644 (file)
@@ -310,8 +310,6 @@ static int dock_present(struct dock_station *ds)
 static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
 {
        struct acpi_device *device;
-       struct acpi_device *parent_device;
-       acpi_handle parent;
        int ret;
 
        if (acpi_bus_get_device(handle, &device)) {
@@ -319,16 +317,11 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
                 * no device created for this object,
                 * so we should create one.
                 */
-               acpi_get_parent(handle, &parent);
-               if (acpi_bus_get_device(parent, &parent_device))
-                       parent_device = NULL;
-
-               ret = acpi_bus_add(&device, parent_device, handle,
-                       ACPI_BUS_TYPE_DEVICE);
-               if (ret) {
+               ret = acpi_bus_scan(handle);
+               if (ret)
                        pr_debug("error adding bus, %x\n", -ret);
-                       return NULL;
-               }
+
+               acpi_bus_get_device(handle, &device);
        }
        return device;
 }
@@ -343,13 +336,9 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
 static void dock_remove_acpi_device(acpi_handle handle)
 {
        struct acpi_device *device;
-       int ret;
 
-       if (!acpi_bus_get_device(handle, &device)) {
-               ret = acpi_bus_trim(device, 1);
-               if (ret)
-                       pr_debug("error removing bus, %x\n", -ret);
-       }
+       if (!acpi_bus_get_device(handle, &device))
+               acpi_bus_trim(device);
 }
 
 /**
@@ -755,7 +744,9 @@ static void acpi_dock_deferred_cb(void *context)
 {
        struct dock_data *data = context;
 
+       acpi_scan_lock_acquire();
        dock_notify(data->handle, data->event, data->ds);
+       acpi_scan_lock_release();
        kfree(data);
 }
 
@@ -768,20 +759,31 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
        if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
           && event != ACPI_NOTIFY_EJECT_REQUEST)
                return 0;
+
+       acpi_scan_lock_acquire();
+
        list_for_each_entry(dock_station, &dock_stations, sibling) {
                if (dock_station->handle == handle) {
                        struct dock_data *dd;
+                       acpi_status status;
 
                        dd = kmalloc(sizeof(*dd), GFP_KERNEL);
                        if (!dd)
-                               return 0;
+                               break;
+
                        dd->handle = handle;
                        dd->event = event;
                        dd->ds = dock_station;
-                       acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
-                       return 0 ;
+                       status = acpi_os_hotplug_execute(acpi_dock_deferred_cb,
+                                                        dd);
+                       if (ACPI_FAILURE(status))
+                               kfree(dd);
+
+                       break;
                }
        }
+
+       acpi_scan_lock_release();
        return 0;
 }
 
@@ -836,7 +838,7 @@ static ssize_t show_docked(struct device *dev,
 
        struct dock_station *dock_station = dev->platform_data;
 
-       if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
+       if (!acpi_bus_get_device(dock_station->handle, &tmp))
                return snprintf(buf, PAGE_SIZE, "1\n");
        return snprintf(buf, PAGE_SIZE, "0\n");
 }
index 354007d..d45b287 100644 (file)
@@ -852,7 +852,7 @@ static int acpi_ec_add(struct acpi_device *device)
        return ret;
 }
 
-static int acpi_ec_remove(struct acpi_device *device, int type)
+static int acpi_ec_remove(struct acpi_device *device)
 {
        struct acpi_ec *ec;
        struct acpi_ec_query_handler *handler, *tmp;
index 3bd6a54..f815da8 100644 (file)
@@ -45,7 +45,7 @@ MODULE_DESCRIPTION("ACPI Fan Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_fan_add(struct acpi_device *device);
-static int acpi_fan_remove(struct acpi_device *device, int type);
+static int acpi_fan_remove(struct acpi_device *device);
 
 static const struct acpi_device_id fan_device_ids[] = {
        {"PNP0C0B", 0},
@@ -172,7 +172,7 @@ static int acpi_fan_add(struct acpi_device *device)
        return result;
 }
 
-static int acpi_fan_remove(struct acpi_device *device, int type)
+static int acpi_fan_remove(struct acpi_device *device)
 {
        struct thermal_cooling_device *cdev = acpi_driver_data(device);
 
index 35da181..ef6f155 100644 (file)
@@ -68,6 +68,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
 {
        struct acpi_bus_type *tmp, *ret = NULL;
 
+       if (!type)
+               return NULL;
+
        down_read(&bus_type_sem);
        list_for_each_entry(tmp, &bus_type_list, list) {
                if (tmp->bus == type) {
@@ -95,40 +98,31 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
        return ret;
 }
 
-/* Get device's handler per its address under its parent */
-struct acpi_find_child {
-       acpi_handle handle;
-       u64 address;
-};
-
-static acpi_status
-do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
+static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
+                                     void *addr_p, void **ret_p)
 {
+       unsigned long long addr;
        acpi_status status;
-       struct acpi_device_info *info;
-       struct acpi_find_child *find = context;
-
-       status = acpi_get_object_info(handle, &info);
-       if (ACPI_SUCCESS(status)) {
-               if ((info->address == find->address)
-                       && (info->valid & ACPI_VALID_ADR))
-                       find->handle = handle;
-               kfree(info);
+
+       status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
+       if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
+               *ret_p = handle;
+               return AE_CTRL_TERMINATE;
        }
        return AE_OK;
 }
 
 acpi_handle acpi_get_child(acpi_handle parent, u64 address)
 {
-       struct acpi_find_child find = { NULL, address };
+       void *ret = NULL;
 
        if (!parent)
                return NULL;
-       acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
-                           1, do_acpi_find_child, NULL, &find, NULL);
-       return find.handle;
-}
 
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL,
+                           do_acpi_find_child, &address, &ret);
+       return (acpi_handle)ret;
+}
 EXPORT_SYMBOL(acpi_get_child);
 
 static int acpi_bind_one(struct device *dev, acpi_handle handle)
@@ -269,28 +263,39 @@ static int acpi_platform_notify(struct device *dev)
 {
        struct acpi_bus_type *type;
        acpi_handle handle;
-       int ret = -EINVAL;
+       int ret;
 
        ret = acpi_bind_one(dev, NULL);
-       if (!ret)
-               goto out;
-
-       if (!dev->bus || !dev->parent) {
+       if (ret && (!dev->bus || !dev->parent)) {
                /* bridge devices genernally haven't bus or parent */
                ret = acpi_find_bridge_device(dev, &handle);
-               goto end;
+               if (!ret) {
+                       ret = acpi_bind_one(dev, handle);
+                       if (ret)
+                               goto out;
+               }
        }
+
        type = acpi_get_bus_type(dev->bus);
-       if (!type) {
-               DBG("No ACPI bus support for %s\n", dev_name(dev));
-               ret = -EINVAL;
-               goto end;
+       if (ret) {
+               if (!type || !type->find_device) {
+                       DBG("No ACPI bus support for %s\n", dev_name(dev));
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               ret = type->find_device(dev, &handle);
+               if (ret) {
+                       DBG("Unable to get handle for %s\n", dev_name(dev));
+                       goto out;
+               }
+               ret = acpi_bind_one(dev, handle);
+               if (ret)
+                       goto out;
        }
-       if ((ret = type->find_device(dev, &handle)) != 0)
-               DBG("Can't get handler for %s\n", dev_name(dev));
- end:
-       if (!ret)
-               acpi_bind_one(dev, handle);
+
+       if (type && type->setup)
+               type->setup(dev);
 
  out:
 #if ACPI_GLUE_DEBUG
@@ -309,6 +314,12 @@ static int acpi_platform_notify(struct device *dev)
 
 static int acpi_platform_notify_remove(struct device *dev)
 {
+       struct acpi_bus_type *type;
+
+       type = acpi_get_bus_type(dev->bus);
+       if (type && type->cleanup)
+               type->cleanup(dev);
+
        acpi_unbind_one(dev);
        return 0;
 }
index a0cc796..13b1d39 100644 (file)
@@ -70,7 +70,7 @@ static int acpi_hed_add(struct acpi_device *device)
        return 0;
 }
 
-static int acpi_hed_remove(struct acpi_device *device, int type)
+static int acpi_hed_remove(struct acpi_device *device)
 {
        hed_handle = NULL;
        return 0;
index 3c407cd..7909232 100644 (file)
 
 int init_acpi_device_notify(void);
 int acpi_scan_init(void);
+void acpi_pci_root_init(void);
+void acpi_pci_link_init(void);
+void acpi_platform_init(void);
 int acpi_sysfs_init(void);
+void acpi_csrt_init(void);
+#ifdef CONFIG_ACPI_CONTAINER
+void acpi_container_init(void);
+#else
+static inline void acpi_container_init(void) {}
+#endif
 
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *acpi_debugfs_dir;
@@ -35,15 +44,33 @@ static inline void acpi_debugfs_init(void) { return; }
 #endif
 
 /* --------------------------------------------------------------------------
+                     Device Node Initialization / Removal
+   -------------------------------------------------------------------------- */
+#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
+                         ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
+
+int acpi_device_add(struct acpi_device *device,
+                   void (*release)(struct device *));
+void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
+                            int type, unsigned long long sta);
+void acpi_device_add_finalize(struct acpi_device *device);
+void acpi_free_ids(struct acpi_device *device);
+
+/* --------------------------------------------------------------------------
                                   Power Resource
    -------------------------------------------------------------------------- */
 int acpi_power_init(void);
+void acpi_power_resources_list_free(struct list_head *list);
+int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
+                                struct list_head *list);
+int acpi_add_power_resource(acpi_handle handle);
+void acpi_power_add_remove_device(struct acpi_device *adev, bool add);
+int acpi_power_min_system_level(struct list_head *list);
 int acpi_device_sleep_wake(struct acpi_device *dev,
                            int enable, int sleep_state, int dev_state);
 int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
 int acpi_power_on_resources(struct acpi_device *device, int state);
 int acpi_power_transition(struct acpi_device *device, int state);
-int acpi_bus_init_power(struct acpi_device *device);
 
 int acpi_wakeup_device_init(void);
 void acpi_early_processor_set_pdc(void);
@@ -98,6 +125,4 @@ static inline void suspend_nvs_restore(void) {}
   -------------------------------------------------------------------------- */
 struct platform_device;
 
-struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
-
 #endif /* _ACPI_INTERNAL_H_ */
index cb31298..33e609f 100644 (file)
@@ -116,14 +116,16 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
                        struct acpi_srat_mem_affinity *p =
                            (struct acpi_srat_mem_affinity *)header;
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                         "SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s\n",
+                                         "SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s%s\n",
                                          (unsigned long)p->base_address,
                                          (unsigned long)p->length,
                                          p->proximity_domain,
                                          (p->flags & ACPI_SRAT_MEM_ENABLED)?
                                          "enabled" : "disabled",
                                          (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
-                                         " hot-pluggable" : ""));
+                                         " hot-pluggable" : "",
+                                         (p->flags & ACPI_SRAT_MEM_NON_VOLATILE)?
+                                         " non-volatile" : ""));
                }
 #endif                         /* ACPI_DEBUG_OUTPUT */
                break;
@@ -273,7 +275,7 @@ static int __init acpi_parse_srat(struct acpi_table_header *table)
 
 static int __init
 acpi_table_parse_srat(enum acpi_srat_type id,
-                     acpi_table_entry_handler handler, unsigned int max_entries)
+                     acpi_tbl_entry_handler handler, unsigned int max_entries)
 {
        return acpi_table_parse_entries(ACPI_SIG_SRAT,
                                            sizeof(struct acpi_table_srat), id,
index bd22f86..908b02d 100644 (file)
@@ -787,7 +787,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
 
        acpi_irq_handler = handler;
        acpi_irq_context = context;
-       if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
+       if (request_irq(irq, acpi_irq, IRQF_SHARED | IRQF_NO_SUSPEND, "acpi", acpi_irq)) {
                printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
                acpi_irq_handler = NULL;
                return AE_NOT_ACQUIRED;
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
deleted file mode 100644 (file)
index a1dee29..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *  pci_bind.c - ACPI PCI Device Binding ($Revision: 2 $)
- *
- *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  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; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that 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, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci-acpi.h>
-#include <linux/acpi.h>
-#include <linux/pm_runtime.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-
-#define _COMPONENT             ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_bind");
-
-static int acpi_pci_unbind(struct acpi_device *device)
-{
-       struct pci_dev *dev;
-
-       dev = acpi_get_pci_dev(device->handle);
-       if (!dev)
-               goto out;
-
-       device_set_run_wake(&dev->dev, false);
-       pci_acpi_remove_pm_notifier(device);
-       acpi_power_resource_unregister_device(&dev->dev, device->handle);
-
-       if (!dev->subordinate)
-               goto out;
-
-       acpi_pci_irq_del_prt(pci_domain_nr(dev->bus), dev->subordinate->number);
-
-       device->ops.bind = NULL;
-       device->ops.unbind = NULL;
-
-out:
-       pci_dev_put(dev);
-       return 0;
-}
-
-static int acpi_pci_bind(struct acpi_device *device)
-{
-       acpi_status status;
-       acpi_handle handle;
-       unsigned char bus;
-       struct pci_dev *dev;
-
-       dev = acpi_get_pci_dev(device->handle);
-       if (!dev)
-               return 0;
-
-       pci_acpi_add_pm_notifier(device, dev);
-       acpi_power_resource_register_device(&dev->dev, device->handle);
-       if (device->wakeup.flags.run_wake)
-               device_set_run_wake(&dev->dev, true);
-
-       /*
-        * Install the 'bind' function to facilitate callbacks for
-        * children of the P2P bridge.
-        */
-       if (dev->subordinate) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Device %04x:%02x:%02x.%d is a PCI bridge\n",
-                                 pci_domain_nr(dev->bus), dev->bus->number,
-                                 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)));
-               device->ops.bind = acpi_pci_bind;
-               device->ops.unbind = acpi_pci_unbind;
-       }
-
-       /*
-        * Evaluate and parse _PRT, if exists.  This code allows parsing of
-        * _PRT objects within the scope of non-bridge devices.  Note that
-        * _PRTs within the scope of a PCI bridge assume the bridge's
-        * subordinate bus number.
-        *
-        * TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
-        */
-       status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
-       if (ACPI_FAILURE(status))
-               goto out;
-
-       if (dev->subordinate)
-               bus = dev->subordinate->number;
-       else
-               bus = dev->bus->number;
-
-       acpi_pci_irq_add_prt(device->handle, pci_domain_nr(dev->bus), bus);
-
-out:
-       pci_dev_put(dev);
-       return 0;
-}
-
-int acpi_pci_bind_root(struct acpi_device *device)
-{
-       device->ops.bind = acpi_pci_bind;
-       device->ops.unbind = acpi_pci_unbind;
-
-       return 0;
-}
index a128082..ab764ed 100644 (file)
@@ -53,23 +53,19 @@ ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_FILE_STATUS      "state"
 #define ACPI_PCI_LINK_MAX_POSSIBLE     16
 
-static int acpi_pci_link_add(struct acpi_device *device);
-static int acpi_pci_link_remove(struct acpi_device *device, int type);
+static int acpi_pci_link_add(struct acpi_device *device,
+                            const struct acpi_device_id *not_used);
+static void acpi_pci_link_remove(struct acpi_device *device);
 
 static const struct acpi_device_id link_device_ids[] = {
        {"PNP0C0F", 0},
        {"", 0},
 };
-MODULE_DEVICE_TABLE(acpi, link_device_ids);
 
-static struct acpi_driver acpi_pci_link_driver = {
-       .name = "pci_link",
-       .class = ACPI_PCI_LINK_CLASS,
+static struct acpi_scan_handler pci_link_handler = {
        .ids = link_device_ids,
-       .ops = {
-               .add = acpi_pci_link_add,
-               .remove = acpi_pci_link_remove,
-       },
+       .attach = acpi_pci_link_add,
+       .detach = acpi_pci_link_remove,
 };
 
 /*
@@ -692,7 +688,8 @@ int acpi_pci_link_free_irq(acpi_handle handle)
                                  Driver Interface
    -------------------------------------------------------------------------- */
 
-static int acpi_pci_link_add(struct acpi_device *device)
+static int acpi_pci_link_add(struct acpi_device *device,
+                            const struct acpi_device_id *not_used)
 {
        int result;
        struct acpi_pci_link *link;
@@ -746,7 +743,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
        if (result)
                kfree(link);
 
-       return result;
+       return result < 0 ? result : 1;
 }
 
 static int acpi_pci_link_resume(struct acpi_pci_link *link)
@@ -766,7 +763,7 @@ static void irqrouter_resume(void)
        }
 }
 
-static int acpi_pci_link_remove(struct acpi_device *device, int type)
+static void acpi_pci_link_remove(struct acpi_device *device)
 {
        struct acpi_pci_link *link;
 
@@ -777,7 +774,6 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type)
        mutex_unlock(&acpi_link_lock);
 
        kfree(link);
-       return 0;
 }
 
 /*
@@ -874,20 +870,10 @@ static struct syscore_ops irqrouter_syscore_ops = {
        .resume = irqrouter_resume,
 };
 
-static int __init irqrouter_init_ops(void)
-{
-       if (!acpi_disabled && !acpi_noirq)
-               register_syscore_ops(&irqrouter_syscore_ops);
-
-       return 0;
-}
-
-device_initcall(irqrouter_init_ops);
-
-static int __init acpi_pci_link_init(void)
+void __init acpi_pci_link_init(void)
 {
        if (acpi_noirq)
-               return 0;
+               return;
 
        if (acpi_irq_balance == -1) {
                /* no command line switch: enable balancing in IOAPIC mode */
@@ -896,11 +882,6 @@ static int __init acpi_pci_link_init(void)
                else
                        acpi_irq_balance = 0;
        }
-
-       if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
-               return -ENODEV;
-
-       return 0;
+       register_syscore_ops(&irqrouter_syscore_ops);
+       acpi_scan_add_handler(&pci_link_handler);
 }
-
-subsys_initcall(acpi_pci_link_init);
index 7928d4d..b3cc69c 100644 (file)
@@ -45,9 +45,9 @@
 ACPI_MODULE_NAME("pci_root");
 #define ACPI_PCI_ROOT_CLASS            "pci_bridge"
 #define ACPI_PCI_ROOT_DEVICE_NAME      "PCI Root Bridge"
-static int acpi_pci_root_add(struct acpi_device *device);
-static int acpi_pci_root_remove(struct acpi_device *device, int type);
-static int acpi_pci_root_start(struct acpi_device *device);
+static int acpi_pci_root_add(struct acpi_device *device,
+                            const struct acpi_device_id *not_used);
+static void acpi_pci_root_remove(struct acpi_device *device);
 
 #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \
                                | OSC_ACTIVE_STATE_PWR_SUPPORT \
@@ -58,17 +58,11 @@ static const struct acpi_device_id root_device_ids[] = {
        {"PNP0A03", 0},
        {"", 0},
 };
-MODULE_DEVICE_TABLE(acpi, root_device_ids);
 
-static struct acpi_driver acpi_pci_root_driver = {
-       .name = "pci_root",
-       .class = ACPI_PCI_ROOT_CLASS,
+static struct acpi_scan_handler pci_root_handler = {
        .ids = root_device_ids,
-       .ops = {
-               .add = acpi_pci_root_add,
-               .remove = acpi_pci_root_remove,
-               .start = acpi_pci_root_start,
-               },
+       .attach = acpi_pci_root_add,
+       .detach = acpi_pci_root_remove,
 };
 
 /* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */
@@ -188,21 +182,6 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
        return AE_OK;
 }
 
-static void acpi_pci_bridge_scan(struct acpi_device *device)
-{
-       int status;
-       struct acpi_device *child = NULL;
-
-       if (device->flags.bus_address)
-               if (device->parent && device->parent->ops.bind) {
-                       status = device->parent->ops.bind(device);
-                       if (!status) {
-                               list_for_each_entry(child, &device->children, node)
-                                       acpi_pci_bridge_scan(child);
-                       }
-               }
-}
-
 static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766";
 
 static acpi_status acpi_pci_run_osc(acpi_handle handle,
@@ -445,14 +424,15 @@ out:
 }
 EXPORT_SYMBOL(acpi_pci_osc_control_set);
 
-static int acpi_pci_root_add(struct acpi_device *device)
+static int acpi_pci_root_add(struct acpi_device *device,
+                            const struct acpi_device_id *not_used)
 {
        unsigned long long segment, bus;
        acpi_status status;
        int result;
        struct acpi_pci_root *root;
        acpi_handle handle;
-       struct acpi_device *child;
+       struct acpi_pci_driver *driver;
        u32 flags, base_flags;
        bool is_osc_granted = false;
 
@@ -603,21 +583,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
                goto out_del_root;
        }
 
-       /*
-        * Attach ACPI-PCI Context
-        * -----------------------
-        * Thus binding the ACPI and PCI devices.
-        */
-       result = acpi_pci_bind_root(device);
-       if (result)
-               goto out_del_root;
-
-       /*
-        * Scan and bind all _ADR-Based Devices
-        */
-       list_for_each_entry(child, &device->children, node)
-               acpi_pci_bridge_scan(child);
-
        /* ASPM setting */
        if (is_osc_granted) {
                if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM)
@@ -632,24 +597,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
        if (device->wakeup.flags.run_wake)
                device_set_run_wake(root->bus->bridge, true);
 
-       return 0;
-
-out_del_root:
-       mutex_lock(&acpi_pci_root_lock);
-       list_del(&root->node);
-       mutex_unlock(&acpi_pci_root_lock);
-
-       acpi_pci_irq_del_prt(root->segment, root->secondary.start);
-end:
-       kfree(root);
-       return result;
-}
-
-static int acpi_pci_root_start(struct acpi_device *device)
-{
-       struct acpi_pci_root *root = acpi_driver_data(device);
-       struct acpi_pci_driver *driver;
-
        if (system_state != SYSTEM_BOOTING)
                pci_assign_unassigned_bus_resources(root->bus);
 
@@ -664,11 +611,20 @@ static int acpi_pci_root_start(struct acpi_device *device)
                pci_enable_bridges(root->bus);
 
        pci_bus_add_devices(root->bus);
+       return 1;
 
-       return 0;
+out_del_root:
+       mutex_lock(&acpi_pci_root_lock);
+       list_del(&root->node);
+       mutex_unlock(&acpi_pci_root_lock);
+
+       acpi_pci_irq_del_prt(root->segment, root->secondary.start);
+end:
+       kfree(root);
+       return result;
 }
 
-static int acpi_pci_root_remove(struct acpi_device *device, int type)
+static void acpi_pci_root_remove(struct acpi_device *device)
 {
        acpi_status status;
        acpi_handle handle;
@@ -696,21 +652,14 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
        list_del(&root->node);
        mutex_unlock(&acpi_pci_root_lock);
        kfree(root);
-       return 0;
 }
 
-static int __init acpi_pci_root_init(void)
+void __init acpi_pci_root_init(void)
 {
        acpi_hest_init();
 
-       if (acpi_pci_disabled)
-               return 0;
-
-       pci_acpi_crs_quirks();
-       if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
-               return -ENODEV;
-
-       return 0;
+       if (!acpi_pci_disabled) {
+               pci_acpi_crs_quirks();
+               acpi_scan_add_handler(&pci_root_handler);
+       }
 }
-
-subsys_initcall(acpi_pci_root_init);
index d22585f..2c630c0 100644 (file)
@@ -50,13 +50,12 @@ module_param(debug, bool, 0644);
 ACPI_MODULE_NAME("pci_slot");
 
 #define MY_NAME "pci_slot"
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
+#define err(format, arg...) pr_err("%s: " format , MY_NAME , ## arg)
+#define info(format, arg...) pr_info("%s: " format , MY_NAME , ## arg)
 #define dbg(format, arg...)                                    \
        do {                                                    \
                if (debug)                                      \
-                       printk(KERN_DEBUG "%s: " format,        \
-                               MY_NAME , ## arg);              \
+                       pr_debug("%s: " format, MY_NAME , ## arg); \
        } while (0)
 
 #define SLOT_NAME_SIZE 21              /* Inspired by #define in acpiphp.h */
index 6e7b9d5..b820528 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
+#include <linux/sysfs.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include "sleep.h"
@@ -58,88 +59,121 @@ ACPI_MODULE_NAME("power");
 #define ACPI_POWER_RESOURCE_STATE_ON   0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 
-static int acpi_power_add(struct acpi_device *device);
-static int acpi_power_remove(struct acpi_device *device, int type);
-
-static const struct acpi_device_id power_device_ids[] = {
-       {ACPI_POWER_HID, 0},
-       {"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, power_device_ids);
-
-#ifdef CONFIG_PM_SLEEP
-static int acpi_power_resume(struct device *dev);
-#endif
-static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume);
-
-static struct acpi_driver acpi_power_driver = {
-       .name = "power",
-       .class = ACPI_POWER_CLASS,
-       .ids = power_device_ids,
-       .ops = {
-               .add = acpi_power_add,
-               .remove = acpi_power_remove,
-               },
-       .drv.pm = &acpi_power_pm,
-};
-
-/*
- * A power managed device
- * A device may rely on multiple power resources.
- * */
-struct acpi_power_managed_device {
-       struct device *dev; /* The physical device */
-       acpi_handle *handle;
-};
-
-struct acpi_power_resource_device {
-       struct acpi_power_managed_device *device;
-       struct acpi_power_resource_device *next;
+struct acpi_power_dependent_device {
+       struct list_head node;
+       struct acpi_device *adev;
+       struct work_struct work;
 };
 
 struct acpi_power_resource {
-       struct acpi_device * device;
-       acpi_bus_id name;
+       struct acpi_device device;
+       struct list_head list_node;
+       struct list_head dependent;
+       char *name;
        u32 system_level;
        u32 order;
        unsigned int ref_count;
        struct mutex resource_lock;
+};
 
-       /* List of devices relying on this power resource */
-       struct acpi_power_resource_device *devices;
-       struct mutex devices_lock;
+struct acpi_power_resource_entry {
+       struct list_head node;
+       struct acpi_power_resource *resource;
 };
 
-static struct list_head acpi_power_resource_list;
+static LIST_HEAD(acpi_power_resource_list);
+static DEFINE_MUTEX(power_resource_list_lock);
 
 /* --------------------------------------------------------------------------
                              Power Resource Management
    -------------------------------------------------------------------------- */
 
-static int
-acpi_power_get_context(acpi_handle handle,
-                      struct acpi_power_resource **resource)
+static inline
+struct acpi_power_resource *to_power_resource(struct acpi_device *device)
 {
-       int result = 0;
-       struct acpi_device *device = NULL;
+       return container_of(device, struct acpi_power_resource, device);
+}
+
+static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle)
+{
+       struct acpi_device *device;
 
+       if (acpi_bus_get_device(handle, &device))
+               return NULL;
 
-       if (!resource)
-               return -ENODEV;
+       return to_power_resource(device);
+}
 
-       result = acpi_bus_get_device(handle, &device);
-       if (result) {
-               printk(KERN_WARNING PREFIX "Getting context [%p]\n", handle);
-               return result;
-       }
+static int acpi_power_resources_list_add(acpi_handle handle,
+                                        struct list_head *list)
+{
+       struct acpi_power_resource *resource = acpi_power_get_context(handle);
+       struct acpi_power_resource_entry *entry;
 
-       *resource = acpi_driver_data(device);
-       if (!*resource)
-               return -ENODEV;
+       if (!resource || !list)
+               return -EINVAL;
+
+       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+       if (!entry)
+               return -ENOMEM;
+
+       entry->resource = resource;
+       if (!list_empty(list)) {
+               struct acpi_power_resource_entry *e;
 
+               list_for_each_entry(e, list, node)
+                       if (e->resource->order > resource->order) {
+                               list_add_tail(&entry->node, &e->node);
+                               return 0;
+                       }
+       }
+       list_add_tail(&entry->node, list);
        return 0;
 }
 
+void acpi_power_resources_list_free(struct list_head *list)
+{
+       struct acpi_power_resource_entry *entry, *e;
+
+       list_for_each_entry_safe(entry, e, list, node) {
+               list_del(&entry->node);
+               kfree(entry);
+       }
+}
+
+int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
+                                struct list_head *list)
+{
+       unsigned int i;
+       int err = 0;
+
+       for (i = start; i < package->package.count; i++) {
+               union acpi_object *element = &package->package.elements[i];
+               acpi_handle rhandle;
+
+               if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
+                       err = -ENODATA;
+                       break;
+               }
+               rhandle = element->reference.handle;
+               if (!rhandle) {
+                       err = -ENODEV;
+                       break;
+               }
+               err = acpi_add_power_resource(rhandle);
+               if (err)
+                       break;
+
+               err = acpi_power_resources_list_add(rhandle, list);
+               if (err)
+                       break;
+       }
+       if (err)
+               acpi_power_resources_list_free(list);
+
+       return err;
+}
+
 static int acpi_power_get_state(acpi_handle handle, int *state)
 {
        acpi_status status = AE_OK;
@@ -167,31 +201,23 @@ static int acpi_power_get_state(acpi_handle handle, int *state)
        return 0;
 }
 
-static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
+static int acpi_power_get_list_state(struct list_head *list, int *state)
 {
+       struct acpi_power_resource_entry *entry;
        int cur_state;
-       int i = 0;
 
        if (!list || !state)
                return -EINVAL;
 
        /* The state of the list is 'on' IFF all resources are 'on'. */
-
-       for (i = 0; i < list->count; i++) {
-               struct acpi_power_resource *resource;
-               acpi_handle handle = list->handles[i];
+       list_for_each_entry(entry, list, node) {
+               struct acpi_power_resource *resource = entry->resource;
+               acpi_handle handle = resource->device.handle;
                int result;
 
-               result = acpi_power_get_context(handle, &resource);
-               if (result)
-                       return result;
-
                mutex_lock(&resource->resource_lock);
-
                result = acpi_power_get_state(handle, &cur_state);
-
                mutex_unlock(&resource->resource_lock);
-
                if (result)
                        return result;
 
@@ -203,54 +229,52 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
                          cur_state ? "on" : "off"));
 
        *state = cur_state;
-
        return 0;
 }
 
-/* Resume the device when all power resources in _PR0 are on */
-static void acpi_power_on_device(struct acpi_power_managed_device *device)
+static void acpi_power_resume_dependent(struct work_struct *work)
 {
-       struct acpi_device *acpi_dev;
-       acpi_handle handle = device->handle;
+       struct acpi_power_dependent_device *dep;
+       struct acpi_device_physical_node *pn;
+       struct acpi_device *adev;
        int state;
 
-       if (acpi_bus_get_device(handle, &acpi_dev))
+       dep = container_of(work, struct acpi_power_dependent_device, work);
+       adev = dep->adev;
+       if (acpi_power_get_inferred_state(adev, &state))
                return;
 
-       if(acpi_power_get_inferred_state(acpi_dev, &state))
+       if (state > ACPI_STATE_D0)
                return;
 
-       if (state == ACPI_STATE_D0 && pm_runtime_suspended(device->dev))
-               pm_request_resume(device->dev);
+       mutex_lock(&adev->physical_node_lock);
+
+       list_for_each_entry(pn, &adev->physical_node_list, node)
+               pm_request_resume(pn->dev);
+
+       list_for_each_entry(pn, &adev->power_dependent, node)
+               pm_request_resume(pn->dev);
+
+       mutex_unlock(&adev->physical_node_lock);
 }
 
 static int __acpi_power_on(struct acpi_power_resource *resource)
 {
        acpi_status status = AE_OK;
 
-       status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
+       status = acpi_evaluate_object(resource->device.handle, "_ON", NULL, NULL);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       /* Update the power resource's _device_ power state */
-       resource->device->power.state = ACPI_STATE_D0;
-
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
                          resource->name));
 
        return 0;
 }
 
-static int acpi_power_on(acpi_handle handle)
+static int acpi_power_on(struct acpi_power_resource *resource)
 {
-       int result = 0;
-       bool resume_device = false;
-       struct acpi_power_resource *resource = NULL;
-       struct acpi_power_resource_device *device_list;
-
-       result = acpi_power_get_context(handle, &resource);
-       if (result)
-               return result;
+       int result = 0;;
 
        mutex_lock(&resource->resource_lock);
 
@@ -260,39 +284,38 @@ static int acpi_power_on(acpi_handle handle)
                                  resource->name));
        } else {
                result = __acpi_power_on(resource);
-               if (result)
+               if (result) {
                        resource->ref_count--;
-               else
-                       resume_device = true;
+               } else {
+                       struct acpi_power_dependent_device *dep;
+
+                       list_for_each_entry(dep, &resource->dependent, node)
+                               schedule_work(&dep->work);
+               }
        }
 
        mutex_unlock(&resource->resource_lock);
 
-       if (!resume_device)
-               return result;
-
-       mutex_lock(&resource->devices_lock);
+       return result;
+}
 
-       device_list = resource->devices;
-       while (device_list) {
-               acpi_power_on_device(device_list->device);
-               device_list = device_list->next;
-       }
+static int __acpi_power_off(struct acpi_power_resource *resource)
+{
+       acpi_status status;
 
-       mutex_unlock(&resource->devices_lock);
+       status = acpi_evaluate_object(resource->device.handle, "_OFF",
+                                     NULL, NULL);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
 
-       return result;
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned off\n",
+                         resource->name));
+       return 0;
 }
 
-static int acpi_power_off(acpi_handle handle)
+static int acpi_power_off(struct acpi_power_resource *resource)
 {
        int result = 0;
-       acpi_status status = AE_OK;
-       struct acpi_power_resource *resource = NULL;
-
-       result = acpi_power_get_context(handle, &resource);
-       if (result)
-               return result;
 
        mutex_lock(&resource->resource_lock);
 
@@ -307,19 +330,10 @@ static int acpi_power_off(acpi_handle handle)
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Power resource [%s] still in use\n",
                                  resource->name));
-               goto unlock;
-       }
-
-       status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
-       if (ACPI_FAILURE(status)) {
-               result = -ENODEV;
        } else {
-               /* Update the power resource's _device_ power state */
-               resource->device->power.state = ACPI_STATE_D3;
-
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Power resource [%s] turned off\n",
-                                 resource->name));
+               result = __acpi_power_off(resource);
+               if (result)
+                       resource->ref_count++;
        }
 
  unlock:
@@ -328,148 +342,202 @@ static int acpi_power_off(acpi_handle handle)
        return result;
 }
 
-static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
+static int acpi_power_off_list(struct list_head *list)
 {
-       int i;
+       struct acpi_power_resource_entry *entry;
+       int result = 0;
 
-       for (i = num_res - 1; i >= 0 ; i--)
-               acpi_power_off(list->handles[i]);
-}
+       list_for_each_entry_reverse(entry, list, node) {
+               result = acpi_power_off(entry->resource);
+               if (result)
+                       goto err;
+       }
+       return 0;
 
-static void acpi_power_off_list(struct acpi_handle_list *list)
-{
-       __acpi_power_off_list(list, list->count);
+ err:
+       list_for_each_entry_continue(entry, list, node)
+               acpi_power_on(entry->resource);
+
+       return result;
 }
 
-static int acpi_power_on_list(struct acpi_handle_list *list)
+static int acpi_power_on_list(struct list_head *list)
 {
+       struct acpi_power_resource_entry *entry;
        int result = 0;
-       int i;
 
-       for (i = 0; i < list->count; i++) {
-               result = acpi_power_on(list->handles[i]);
-               if (result) {
-                       __acpi_power_off_list(list, i);
-                       break;
-               }
+       list_for_each_entry(entry, list, node) {
+               result = acpi_power_on(entry->resource);
+               if (result)
+                       goto err;
        }
+       return 0;
+
+ err:
+       list_for_each_entry_continue_reverse(entry, list, node)
+               acpi_power_off(entry->resource);
 
        return result;
 }
 
-static void __acpi_power_resource_unregister_device(struct device *dev,
-               acpi_handle res_handle)
+static void acpi_power_add_dependent(struct acpi_power_resource *resource,
+                                    struct acpi_device *adev)
 {
-       struct acpi_power_resource *resource = NULL;
-       struct acpi_power_resource_device *prev, *curr;
+       struct acpi_power_dependent_device *dep;
 
-       if (acpi_power_get_context(res_handle, &resource))
-               return;
+       mutex_lock(&resource->resource_lock);
+
+       list_for_each_entry(dep, &resource->dependent, node)
+               if (dep->adev == adev)
+                       goto out;
+
+       dep = kzalloc(sizeof(*dep), GFP_KERNEL);
+       if (!dep)
+               goto out;
+
+       dep->adev = adev;
+       INIT_WORK(&dep->work, acpi_power_resume_dependent);
+       list_add_tail(&dep->node, &resource->dependent);
 
-       mutex_lock(&resource->devices_lock);
-       prev = NULL;
-       curr = resource->devices;
-       while (curr) {
-               if (curr->device->dev == dev) {
-                       if (!prev)
-                               resource->devices = curr->next;
-                       else
-                               prev->next = curr->next;
-
-                       kfree(curr);
+ out:
+       mutex_unlock(&resource->resource_lock);
+}
+
+static void acpi_power_remove_dependent(struct acpi_power_resource *resource,
+                                       struct acpi_device *adev)
+{
+       struct acpi_power_dependent_device *dep;
+       struct work_struct *work = NULL;
+
+       mutex_lock(&resource->resource_lock);
+
+       list_for_each_entry(dep, &resource->dependent, node)
+               if (dep->adev == adev) {
+                       list_del(&dep->node);
+                       work = &dep->work;
                        break;
                }
 
-               prev = curr;
-               curr = curr->next;
+       mutex_unlock(&resource->resource_lock);
+
+       if (work) {
+               cancel_work_sync(work);
+               kfree(dep);
        }
-       mutex_unlock(&resource->devices_lock);
 }
 
-/* Unlink dev from all power resources in _PR0 */
-void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle)
-{
-       struct acpi_device *acpi_dev;
-       struct acpi_handle_list *list;
-       int i;
+static struct attribute *attrs[] = {
+       NULL,
+};
 
-       if (!dev || !handle)
-               return;
+static struct attribute_group attr_groups[] = {
+       [ACPI_STATE_D0] = {
+               .name = "power_resources_D0",
+               .attrs = attrs,
+       },
+       [ACPI_STATE_D1] = {
+               .name = "power_resources_D1",
+               .attrs = attrs,
+       },
+       [ACPI_STATE_D2] = {
+               .name = "power_resources_D2",
+               .attrs = attrs,
+       },
+       [ACPI_STATE_D3_HOT] = {
+               .name = "power_resources_D3hot",
+               .attrs = attrs,
+       },
+};
 
-       if (acpi_bus_get_device(handle, &acpi_dev))
+static void acpi_power_hide_list(struct acpi_device *adev, int state)
+{
+       struct acpi_device_power_state *ps = &adev->power.states[state];
+       struct acpi_power_resource_entry *entry;
+
+       if (list_empty(&ps->resources))
                return;
 
-       list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
+       list_for_each_entry_reverse(entry, &ps->resources, node) {
+               struct acpi_device *res_dev = &entry->resource->device;
 
-       for (i = 0; i < list->count; i++)
-               __acpi_power_resource_unregister_device(dev,
-                       list->handles[i]);
+               sysfs_remove_link_from_group(&adev->dev.kobj,
+                                            attr_groups[state].name,
+                                            dev_name(&res_dev->dev));
+       }
+       sysfs_remove_group(&adev->dev.kobj, &attr_groups[state]);
 }
-EXPORT_SYMBOL_GPL(acpi_power_resource_unregister_device);
 
-static int __acpi_power_resource_register_device(
-       struct acpi_power_managed_device *powered_device, acpi_handle handle)
+static void acpi_power_expose_list(struct acpi_device *adev, int state)
 {
-       struct acpi_power_resource *resource = NULL;
-       struct acpi_power_resource_device *power_resource_device;
-       int result;
-
-       result = acpi_power_get_context(handle, &resource);
-       if (result)
-               return result;
+       struct acpi_device_power_state *ps = &adev->power.states[state];
+       struct acpi_power_resource_entry *entry;
+       int ret;
 
-       power_resource_device = kzalloc(
-               sizeof(*power_resource_device), GFP_KERNEL);
-       if (!power_resource_device)
-               return -ENOMEM;
+       if (list_empty(&ps->resources))
+               return;
 
-       power_resource_device->device = powered_device;
+       ret = sysfs_create_group(&adev->dev.kobj, &attr_groups[state]);
+       if (ret)
+               return;
 
-       mutex_lock(&resource->devices_lock);
-       power_resource_device->next = resource->devices;
-       resource->devices = power_resource_device;
-       mutex_unlock(&resource->devices_lock);
+       list_for_each_entry(entry, &ps->resources, node) {
+               struct acpi_device *res_dev = &entry->resource->device;
 
-       return 0;
+               ret = sysfs_add_link_to_group(&adev->dev.kobj,
+                                             attr_groups[state].name,
+                                             &res_dev->dev.kobj,
+                                             dev_name(&res_dev->dev));
+               if (ret) {
+                       acpi_power_hide_list(adev, state);
+                       break;
+               }
+       }
 }
 
-/* Link dev to all power resources in _PR0 */
-int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
+void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
 {
-       struct acpi_device *acpi_dev;
-       struct acpi_handle_list *list;
-       struct acpi_power_managed_device *powered_device;
-       int i, ret;
+       struct acpi_device_power_state *ps;
+       struct acpi_power_resource_entry *entry;
+       int state;
 
-       if (!dev || !handle)
-               return -ENODEV;
+       if (!adev->power.flags.power_resources)
+               return;
 
-       ret = acpi_bus_get_device(handle, &acpi_dev);
-       if (ret || !acpi_dev->power.flags.power_resources)
-               return -ENODEV;
+       ps = &adev->power.states[ACPI_STATE_D0];
+       list_for_each_entry(entry, &ps->resources, node) {
+               struct acpi_power_resource *resource = entry->resource;
 
-       powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL);
-       if (!powered_device)
-               return -ENOMEM;
+               if (add)
+                       acpi_power_add_dependent(resource, adev);
+               else
+                       acpi_power_remove_dependent(resource, adev);
+       }
 
-       powered_device->dev = dev;
-       powered_device->handle = handle;
+       for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++) {
+               if (add)
+                       acpi_power_expose_list(adev, state);
+               else
+                       acpi_power_hide_list(adev, state);
+       }
+}
 
-       list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
+int acpi_power_min_system_level(struct list_head *list)
+{
+       struct acpi_power_resource_entry *entry;
+       int system_level = 5;
 
-       for (i = 0; i < list->count; i++) {
-               ret = __acpi_power_resource_register_device(powered_device,
-                       list->handles[i]);
+       list_for_each_entry(entry, list, node) {
+               struct acpi_power_resource *resource = entry->resource;
 
-               if (ret) {
-                       acpi_power_resource_unregister_device(dev, handle);
-                       break;
-               }
+               if (system_level > resource->system_level)
+                       system_level = resource->system_level;
        }
-
-       return ret;
+       return system_level;
 }
-EXPORT_SYMBOL_GPL(acpi_power_resource_register_device);
+
+/* --------------------------------------------------------------------------
+                             Device Power Management
+   -------------------------------------------------------------------------- */
 
 /**
  * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
@@ -542,7 +610,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
  */
 int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
 {
-       int i, err = 0;
+       int err = 0;
 
        if (!dev || !dev->wakeup.flags.valid)
                return -EINVAL;
@@ -552,24 +620,17 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
        if (dev->wakeup.prepare_count++)
                goto out;
 
-       /* Open power resource */
-       for (i = 0; i < dev->wakeup.resources.count; i++) {
-               int ret = acpi_power_on(dev->wakeup.resources.handles[i]);
-               if (ret) {
-                       printk(KERN_ERR PREFIX "Transition power state\n");
-                       dev->wakeup.flags.valid = 0;
-                       err = -ENODEV;
-                       goto err_out;
-               }
+       err = acpi_power_on_list(&dev->wakeup.resources);
+       if (err) {
+               dev_err(&dev->dev, "Cannot turn wakeup power resources on\n");
+               dev->wakeup.flags.valid = 0;
+       } else {
+               /*
+                * Passing 3 as the third argument below means the device may be
+                * put into arbitrary power state afterward.
+                */
+               err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
        }
-
-       /*
-        * Passing 3 as the third argument below means the device may be placed
-        * in arbitrary power state afterwards.
-        */
-       err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
-
- err_out:
        if (err)
                dev->wakeup.prepare_count = 0;
 
@@ -586,7 +647,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
  */
 int acpi_disable_wakeup_device_power(struct acpi_device *dev)
 {
-       int i, err = 0;
+       int err = 0;
 
        if (!dev || !dev->wakeup.flags.valid)
                return -EINVAL;
@@ -607,15 +668,10 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
        if (err)
                goto out;
 
-       /* Close power resource */
-       for (i = 0; i < dev->wakeup.resources.count; i++) {
-               int ret = acpi_power_off(dev->wakeup.resources.handles[i]);
-               if (ret) {
-                       printk(KERN_ERR PREFIX "Transition power state\n");
-                       dev->wakeup.flags.valid = 0;
-                       err = -ENODEV;
-                       goto out;
-               }
+       err = acpi_power_off_list(&dev->wakeup.resources);
+       if (err) {
+               dev_err(&dev->dev, "Cannot turn wakeup power resources off\n");
+               dev->wakeup.flags.valid = 0;
        }
 
  out:
@@ -623,14 +679,9 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
        return err;
 }
 
-/* --------------------------------------------------------------------------
-                             Device Power Management
-   -------------------------------------------------------------------------- */
-
 int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
 {
        int result = 0;
-       struct acpi_handle_list *list = NULL;
        int list_state = 0;
        int i = 0;
 
@@ -642,8 +693,9 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
         * required for a given D-state are 'on'.
         */
        for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
-               list = &device->power.states[i].resources;
-               if (list->count < 1)
+               struct list_head *list = &device->power.states[i].resources;
+
+               if (list_empty(list))
                        continue;
 
                result = acpi_power_get_list_state(list, &list_state);
@@ -662,7 +714,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
 
 int acpi_power_on_resources(struct acpi_device *device, int state)
 {
-       if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
+       if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3_HOT)
                return -EINVAL;
 
        return acpi_power_on_list(&device->power.states[state].resources);
@@ -675,7 +727,7 @@ int acpi_power_transition(struct acpi_device *device, int state)
        if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
                return -EINVAL;
 
-       if (device->power.state == state)
+       if (device->power.state == state || !device->flags.power_manageable)
                return 0;
 
        if ((device->power.state < ACPI_STATE_D0)
@@ -703,118 +755,126 @@ int acpi_power_transition(struct acpi_device *device, int state)
        return result;
 }
 
-/* --------------------------------------------------------------------------
-                                Driver Interface
-   -------------------------------------------------------------------------- */
+static void acpi_release_power_resource(struct device *dev)
+{
+       struct acpi_device *device = to_acpi_device(dev);
+       struct acpi_power_resource *resource;
+
+       resource = container_of(device, struct acpi_power_resource, device);
+
+       mutex_lock(&power_resource_list_lock);
+       list_del(&resource->list_node);
+       mutex_unlock(&power_resource_list_lock);
+
+       acpi_free_ids(device);
+       kfree(resource);
+}
 
-static int acpi_power_add(struct acpi_device *device)
+static ssize_t acpi_power_in_use_show(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf) {
+       struct acpi_power_resource *resource;
+
+       resource = to_power_resource(to_acpi_device(dev));
+       return sprintf(buf, "%u\n", !!resource->ref_count);
+}
+static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL);
+
+static void acpi_power_sysfs_remove(struct acpi_device *device)
 {
-       int result = 0, state;
-       acpi_status status = AE_OK;
-       struct acpi_power_resource *resource = NULL;
+       device_remove_file(&device->dev, &dev_attr_resource_in_use);
+}
+
+int acpi_add_power_resource(acpi_handle handle)
+{
+       struct acpi_power_resource *resource;
+       struct acpi_device *device = NULL;
        union acpi_object acpi_object;
        struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
+       acpi_status status;
+       int state, result = -ENODEV;
 
+       acpi_bus_get_device(handle, &device);
+       if (device)
+               return 0;
 
-       if (!device)
-               return -EINVAL;
-
-       resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
+       resource = kzalloc(sizeof(*resource), GFP_KERNEL);
        if (!resource)
                return -ENOMEM;
 
-       resource->device = device;
+       device = &resource->device;
+       acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER,
+                               ACPI_STA_DEFAULT);
        mutex_init(&resource->resource_lock);
-       mutex_init(&resource->devices_lock);
-       strcpy(resource->name, device->pnp.bus_id);
+       INIT_LIST_HEAD(&resource->dependent);
+       resource->name = device->pnp.bus_id;
        strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
-       device->driver_data = resource;
+       device->power.state = ACPI_STATE_UNKNOWN;
 
        /* Evalute the object to get the system level and resource order. */
-       status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);
-       if (ACPI_FAILURE(status)) {
-               result = -ENODEV;
-               goto end;
-       }
+       status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
+       if (ACPI_FAILURE(status))
+               goto err;
+
        resource->system_level = acpi_object.power_resource.system_level;
        resource->order = acpi_object.power_resource.resource_order;
 
-       result = acpi_power_get_state(device->handle, &state);
+       result = acpi_power_get_state(handle, &state);
        if (result)
-               goto end;
-
-       switch (state) {
-       case ACPI_POWER_RESOURCE_STATE_ON:
-               device->power.state = ACPI_STATE_D0;
-               break;
-       case ACPI_POWER_RESOURCE_STATE_OFF:
-               device->power.state = ACPI_STATE_D3;
-               break;
-       default:
-               device->power.state = ACPI_STATE_UNKNOWN;
-               break;
-       }
+               goto err;
 
        printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
               acpi_device_bid(device), state ? "on" : "off");
 
-      end:
+       device->flags.match_driver = true;
+       result = acpi_device_add(device, acpi_release_power_resource);
        if (result)
-               kfree(resource);
+               goto err;
 
-       return result;
-}
-
-static int acpi_power_remove(struct acpi_device *device, int type)
-{
-       struct acpi_power_resource *resource;
-
-       if (!device)
-               return -EINVAL;
-
-       resource = acpi_driver_data(device);
-       if (!resource)
-               return -EINVAL;
-
-       kfree(resource);
+       if (!device_create_file(&device->dev, &dev_attr_resource_in_use))
+               device->remove = acpi_power_sysfs_remove;
 
+       mutex_lock(&power_resource_list_lock);
+       list_add(&resource->list_node, &acpi_power_resource_list);
+       mutex_unlock(&power_resource_list_lock);
+       acpi_device_add_finalize(device);
        return 0;
+
+ err:
+       acpi_release_power_resource(&device->dev);
+       return result;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int acpi_power_resume(struct device *dev)
+#ifdef CONFIG_ACPI_SLEEP
+void acpi_resume_power_resources(void)
 {
-       int result = 0, state;
-       struct acpi_device *device;
        struct acpi_power_resource *resource;
 
-       if (!dev)
-               return -EINVAL;
+       mutex_lock(&power_resource_list_lock);
 
-       device = to_acpi_device(dev);
-       resource = acpi_driver_data(device);
-       if (!resource)
-               return -EINVAL;
+       list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
+               int result, state;
 
-       mutex_lock(&resource->resource_lock);
+               mutex_lock(&resource->resource_lock);
 
-       result = acpi_power_get_state(device->handle, &state);
-       if (result)
-               goto unlock;
+               result = acpi_power_get_state(resource->device.handle, &state);
+               if (result)
+                       continue;
 
-       if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count)
-               result = __acpi_power_on(resource);
+               if (state == ACPI_POWER_RESOURCE_STATE_OFF
+                   && resource->ref_count) {
+                       dev_info(&resource->device.dev, "Turning ON\n");
+                       __acpi_power_on(resource);
+               } else if (state == ACPI_POWER_RESOURCE_STATE_ON
+                   && !resource->ref_count) {
+                       dev_info(&resource->device.dev, "Turning OFF\n");
+                       __acpi_power_off(resource);
+               }
 
- unlock:
-       mutex_unlock(&resource->resource_lock);
+               mutex_unlock(&resource->resource_lock);
+       }
 
-       return result;
+       mutex_unlock(&power_resource_list_lock);
 }
 #endif
-
-int __init acpi_power_init(void)
-{
-       INIT_LIST_HEAD(&acpi_power_resource_list);
-       return acpi_bus_register_driver(&acpi_power_driver);
-}
index ef98796..52ce767 100644 (file)
@@ -311,11 +311,12 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
                           dev->pnp.bus_id,
                           (u32) dev->wakeup.sleep_state);
 
-               if (!dev->physical_node_count)
+               if (!dev->physical_node_count) {
                        seq_printf(seq, "%c%-8s\n",
-                               dev->wakeup.flags.run_wake ?
-                               '*' : ' ', "disabled");
-               else {
+                               dev->wakeup.flags.run_wake ? '*' : ' ',
+                               device_may_wakeup(&dev->dev) ?
+                                       "enabled" : "disabled");
+               } else {
                        struct device *ldev;
                        list_for_each_entry(entry, &dev->physical_node_list,
                                        node) {
index e83311b..cbf1f12 100644 (file)
@@ -81,7 +81,7 @@ MODULE_DESCRIPTION("ACPI Processor Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_processor_add(struct acpi_device *device);
-static int acpi_processor_remove(struct acpi_device *device, int type);
+static int acpi_processor_remove(struct acpi_device *device);
 static void acpi_processor_notify(struct acpi_device *device, u32 event);
 static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
@@ -610,7 +610,7 @@ err_free_pr:
        return result;
 }
 
-static int acpi_processor_remove(struct acpi_device *device, int type)
+static int acpi_processor_remove(struct acpi_device *device)
 {
        struct acpi_processor *pr = NULL;
 
@@ -623,7 +623,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
        if (pr->id >= nr_cpu_ids)
                goto free;
 
-       if (type == ACPI_BUS_REMOVAL_EJECT) {
+       if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) {
                if (acpi_processor_handle_eject(pr))
                        return -EINVAL;
        }
@@ -677,36 +677,17 @@ static int is_processor_present(acpi_handle handle)
        return 0;
 }
 
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
-{
-       acpi_handle phandle;
-       struct acpi_device *pdev;
-
-
-       if (acpi_get_parent(handle, &phandle)) {
-               return -ENODEV;
-       }
-
-       if (acpi_bus_get_device(phandle, &pdev)) {
-               return -ENODEV;
-       }
-
-       if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
 static void acpi_processor_hotplug_notify(acpi_handle handle,
                                          u32 event, void *data)
 {
        struct acpi_device *device = NULL;
        struct acpi_eject_event *ej_event = NULL;
        u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
+       acpi_status status;
        int result;
 
+       acpi_scan_lock_acquire();
+
        switch (event) {
        case ACPI_NOTIFY_BUS_CHECK:
        case ACPI_NOTIFY_DEVICE_CHECK:
@@ -721,12 +702,16 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
                if (!acpi_bus_get_device(handle, &device))
                        break;
 
-               result = acpi_processor_device_add(handle, &device);
+               result = acpi_bus_scan(handle);
                if (result) {
                        acpi_handle_err(handle, "Unable to add the device\n");
                        break;
                }
-
+               result = acpi_bus_get_device(handle, &device);
+               if (result) {
+                       acpi_handle_err(handle, "Missing device object\n");
+                       break;
+               }
                ost_code = ACPI_OST_SC_SUCCESS;
                break;
 
@@ -751,25 +736,32 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
                        break;
                }
 
-               ej_event->handle = handle;
+               get_device(&device->dev);
+               ej_event->device = device;
                ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-               acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
-                                       (void *)ej_event);
-
-               /* eject is performed asynchronously */
-               return;
+               /* The eject is carried out asynchronously. */
+               status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
+                                                ej_event);
+               if (ACPI_FAILURE(status)) {
+                       put_device(&device->dev);
+                       kfree(ej_event);
+                       break;
+               }
+               goto out;
 
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Unsupported event [0x%x]\n", event));
 
                /* non-hotplug event; possibly handled by other handler */
-               return;
+               goto out;
        }
 
        /* Inform firmware that the hotplug operation has completed */
        (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
-       return;
+
+ out:
+       acpi_scan_lock_release();
 }
 
 static acpi_status is_processor_device(acpi_handle handle)
index ff0740e..e523245 100644 (file)
@@ -130,7 +130,7 @@ struct acpi_sbs {
 
 #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
 
-static int acpi_sbs_remove(struct acpi_device *device, int type);
+static int acpi_sbs_remove(struct acpi_device *device);
 static int acpi_battery_get_state(struct acpi_battery *battery);
 
 static inline int battery_scale(int log)
@@ -949,11 +949,11 @@ static int acpi_sbs_add(struct acpi_device *device)
        acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
       end:
        if (result)
-               acpi_sbs_remove(device, 0);
+               acpi_sbs_remove(device);
        return result;
 }
 
-static int acpi_sbs_remove(struct acpi_device *device, int type)
+static int acpi_sbs_remove(struct acpi_device *device)
 {
        struct acpi_sbs *sbs;
        int id;
index cf6129a..b78bc60 100644 (file)
@@ -33,7 +33,7 @@ struct acpi_smb_hc {
 };
 
 static int acpi_smbus_hc_add(struct acpi_device *device);
-static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
+static int acpi_smbus_hc_remove(struct acpi_device *device);
 
 static const struct acpi_device_id sbs_device_ids[] = {
        {"ACPI0001", 0},
@@ -296,7 +296,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
 
 extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
 
-static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
+static int acpi_smbus_hc_remove(struct acpi_device *device)
 {
        struct acpi_smb_hc *hc;
 
index c88be6c..daee749 100644 (file)
@@ -29,29 +29,10 @@ extern struct acpi_device *acpi_root;
 
 static const char *dummy_hid = "device";
 
-/*
- * The following ACPI IDs are known to be suitable for representing as
- * platform devices.
- */
-static const struct acpi_device_id acpi_platform_device_ids[] = {
-
-       { "PNP0D40" },
-
-       /* Haswell LPSS devices */
-       { "INT33C0", 0 },
-       { "INT33C1", 0 },
-       { "INT33C2", 0 },
-       { "INT33C3", 0 },
-       { "INT33C4", 0 },
-       { "INT33C5", 0 },
-       { "INT33C6", 0 },
-       { "INT33C7", 0 },
-
-       { }
-};
-
 static LIST_HEAD(acpi_device_list);
 static LIST_HEAD(acpi_bus_id_list);
+static DEFINE_MUTEX(acpi_scan_lock);
+static LIST_HEAD(acpi_scan_handlers_list);
 DEFINE_MUTEX(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 
@@ -61,6 +42,27 @@ struct acpi_device_bus_id{
        struct list_head node;
 };
 
+void acpi_scan_lock_acquire(void)
+{
+       mutex_lock(&acpi_scan_lock);
+}
+EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire);
+
+void acpi_scan_lock_release(void)
+{
+       mutex_unlock(&acpi_scan_lock);
+}
+EXPORT_SYMBOL_GPL(acpi_scan_lock_release);
+
+int acpi_scan_add_handler(struct acpi_scan_handler *handler)
+{
+       if (!handler || !handler->attach)
+               return -EINVAL;
+
+       list_add_tail(&handler->list_node, &acpi_scan_handlers_list);
+       return 0;
+}
+
 /*
  * Creates hid/cid(s) string needed for modalias and uevent
  * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
@@ -115,39 +117,32 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
  */
 void acpi_bus_hot_remove_device(void *context)
 {
-       struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
-       struct acpi_device *device;
-       acpi_handle handle = ej_event->handle;
+       struct acpi_eject_event *ej_event = context;
+       struct acpi_device *device = ej_event->device;
+       acpi_handle handle = device->handle;
        acpi_handle temp;
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status = AE_OK;
        u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
 
-       if (acpi_bus_get_device(handle, &device))
-               goto err_out;
+       mutex_lock(&acpi_scan_lock);
 
-       if (!device)
-               goto err_out;
+       /* If there is no handle, the device node has been unregistered. */
+       if (!device->handle) {
+               dev_dbg(&device->dev, "ACPI handle missing\n");
+               put_device(&device->dev);
+               goto out;
+       }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                "Hot-removing device %s...\n", dev_name(&device->dev)));
 
-       if (acpi_bus_trim(device, 1)) {
-               printk(KERN_ERR PREFIX
-                               "Removing device failed\n");
-               goto err_out;
-       }
-
-       /* device has been freed */
+       acpi_bus_trim(device);
+       /* Device node has been unregistered. */
+       put_device(&device->dev);
        device = NULL;
 
-       /* power off device */
-       status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
-       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
-               printk(KERN_WARNING PREFIX
-                               "Power-off device failed\n");
-
        if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) {
                arg_list.count = 1;
                arg_list.pointer = &arg;
@@ -167,23 +162,46 @@ void acpi_bus_hot_remove_device(void *context)
        status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
        if (ACPI_FAILURE(status)) {
                if (status != AE_NOT_FOUND)
-                       printk(KERN_WARNING PREFIX
-                                       "Eject device failed\n");
-               goto err_out;
-       }
+                       acpi_handle_warn(handle, "Eject failed\n");
 
-       kfree(context);
-       return;
+               /* Tell the firmware the hot-remove operation has failed. */
+               acpi_evaluate_hotplug_ost(handle, ej_event->event,
+                                         ost_code, NULL);
+       }
 
-err_out:
-       /* Inform firmware the hot-remove operation has completed w/ error */
-       (void) acpi_evaluate_hotplug_ost(handle,
-                               ej_event->event, ost_code, NULL);
+ out:
+       mutex_unlock(&acpi_scan_lock);
        kfree(context);
        return;
 }
 EXPORT_SYMBOL(acpi_bus_hot_remove_device);
 
+static ssize_t real_power_state_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct acpi_device *adev = to_acpi_device(dev);
+       int state;
+       int ret;
+
+       ret = acpi_device_get_power(adev, &state);
+       if (ret)
+               return ret;
+
+       return sprintf(buf, "%s\n", acpi_power_state_string(state));
+}
+
+static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL);
+
+static ssize_t power_state_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct acpi_device *adev = to_acpi_device(dev);
+
+       return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state));
+}
+
+static DEVICE_ATTR(power_state, 0444, power_state_show, NULL);
+
 static ssize_t
 acpi_eject_store(struct device *d, struct device_attribute *attr,
                const char *buf, size_t count)
@@ -197,12 +215,10 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
        if ((!count) || (buf[0] != '1')) {
                return -EINVAL;
        }
-#ifndef FORCE_EJECT
-       if (acpi_device->driver == NULL) {
+       if (!acpi_device->driver && !acpi_device->handler) {
                ret = -ENODEV;
                goto err;
        }
-#endif
        status = acpi_get_type(acpi_device->handle, &type);
        if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
                ret = -ENODEV;
@@ -215,7 +231,8 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
                goto err;
        }
 
-       ej_event->handle = acpi_device->handle;
+       get_device(&acpi_device->dev);
+       ej_event->device = acpi_device;
        if (acpi_device->flags.eject_pending) {
                /* event originated from ACPI eject notification */
                ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
@@ -223,11 +240,15 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
        } else {
                /* event originated from user */
                ej_event->event = ACPI_OST_EC_OSPM_EJECT;
-               (void) acpi_evaluate_hotplug_ost(ej_event->handle,
+               (void) acpi_evaluate_hotplug_ost(acpi_device->handle,
                        ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
        }
 
-       acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event);
+       status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event);
+       if (ACPI_FAILURE(status)) {
+               put_device(&acpi_device->dev);
+               kfree(ej_event);
+       }
 err:
        return ret;
 }
@@ -375,8 +396,22 @@ static int acpi_device_setup_files(struct acpi_device *dev)
          * hot-removal function from userland.
          */
        status = acpi_get_handle(dev->handle, "_EJ0", &temp);
-       if (ACPI_SUCCESS(status))
+       if (ACPI_SUCCESS(status)) {
                result = device_create_file(&dev->dev, &dev_attr_eject);
+               if (result)
+                       return result;
+       }
+
+       if (dev->flags.power_manageable) {
+               result = device_create_file(&dev->dev, &dev_attr_power_state);
+               if (result)
+                       return result;
+
+               if (dev->power.flags.power_resources)
+                       result = device_create_file(&dev->dev,
+                                                   &dev_attr_real_power_state);
+       }
+
 end:
        return result;
 }
@@ -386,6 +421,13 @@ static void acpi_device_remove_files(struct acpi_device *dev)
        acpi_status status;
        acpi_handle temp;
 
+       if (dev->flags.power_manageable) {
+               device_remove_file(&dev->dev, &dev_attr_power_state);
+               if (dev->power.flags.power_resources)
+                       device_remove_file(&dev->dev,
+                                          &dev_attr_real_power_state);
+       }
+
        /*
         * If device has _STR, remove 'description' file
         */
@@ -454,9 +496,9 @@ const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
                                               const struct device *dev)
 {
        struct acpi_device *adev;
+       acpi_handle handle = ACPI_HANDLE(dev);
 
-       if (!ids || !ACPI_HANDLE(dev)
-           || ACPI_FAILURE(acpi_bus_get_device(ACPI_HANDLE(dev), &adev)))
+       if (!ids || !handle || acpi_bus_get_device(handle, &adev))
                return NULL;
 
        return __acpi_match_device(adev, ids);
@@ -470,7 +512,7 @@ int acpi_match_device_ids(struct acpi_device *device,
 }
 EXPORT_SYMBOL(acpi_match_device_ids);
 
-static void acpi_free_ids(struct acpi_device *device)
+void acpi_free_ids(struct acpi_device *device)
 {
        struct acpi_hardware_id *id, *tmp;
 
@@ -478,6 +520,23 @@ static void acpi_free_ids(struct acpi_device *device)
                kfree(id->id);
                kfree(id);
        }
+       kfree(device->pnp.unique_id);
+}
+
+static void acpi_free_power_resources_lists(struct acpi_device *device)
+{
+       int i;
+
+       if (device->wakeup.flags.valid)
+               acpi_power_resources_list_free(&device->wakeup.resources);
+
+       if (!device->flags.power_manageable)
+               return;
+
+       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
+               struct acpi_device_power_state *ps = &device->power.states[i];
+               acpi_power_resources_list_free(&ps->resources);
+       }
 }
 
 static void acpi_device_release(struct device *dev)
@@ -485,7 +544,7 @@ static void acpi_device_release(struct device *dev)
        struct acpi_device *acpi_dev = to_acpi_device(dev);
 
        acpi_free_ids(acpi_dev);
-       kfree(acpi_dev->pnp.unique_id);
+       acpi_free_power_resources_lists(acpi_dev);
        kfree(acpi_dev);
 }
 
@@ -494,7 +553,8 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
        struct acpi_device *acpi_dev = to_acpi_device(dev);
        struct acpi_driver *acpi_drv = to_acpi_driver(drv);
 
-       return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
+       return acpi_dev->flags.match_driver
+               && !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
 }
 
 static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -570,7 +630,6 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
 }
 
 static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
-static int acpi_start_single_object(struct acpi_device *);
 static int acpi_device_probe(struct device * dev)
 {
        struct acpi_device *acpi_dev = to_acpi_device(dev);
@@ -579,15 +638,13 @@ static int acpi_device_probe(struct device * dev)
 
        ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
        if (!ret) {
-               if (acpi_dev->bus_ops.acpi_op_start)
-                       acpi_start_single_object(acpi_dev);
-
                if (acpi_drv->ops.notify) {
                        ret = acpi_device_install_notify_handler(acpi_dev);
                        if (ret) {
                                if (acpi_drv->ops.remove)
-                                       acpi_drv->ops.remove(acpi_dev,
-                                                    acpi_dev->removal_type);
+                                       acpi_drv->ops.remove(acpi_dev);
+                               acpi_dev->driver = NULL;
+                               acpi_dev->driver_data = NULL;
                                return ret;
                        }
                }
@@ -609,7 +666,7 @@ static int acpi_device_remove(struct device * dev)
                if (acpi_drv->ops.notify)
                        acpi_device_remove_notify_handler(acpi_dev);
                if (acpi_drv->ops.remove)
-                       acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
+                       acpi_drv->ops.remove(acpi_dev);
        }
        acpi_dev->driver = NULL;
        acpi_dev->driver_data = NULL;
@@ -626,12 +683,25 @@ struct bus_type acpi_bus_type = {
        .uevent         = acpi_device_uevent,
 };
 
-static int acpi_device_register(struct acpi_device *device)
+int acpi_device_add(struct acpi_device *device,
+                   void (*release)(struct device *))
 {
        int result;
        struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
        int found = 0;
 
+       if (device->handle) {
+               acpi_status status;
+
+               status = acpi_attach_data(device->handle, acpi_bus_data_handler,
+                                         device);
+               if (ACPI_FAILURE(status)) {
+                       acpi_handle_err(device->handle,
+                                       "Unable to attach device data\n");
+                       return -ENODEV;
+               }
+       }
+
        /*
         * Linkage
         * -------
@@ -642,11 +712,13 @@ static int acpi_device_register(struct acpi_device *device)
        INIT_LIST_HEAD(&device->wakeup_list);
        INIT_LIST_HEAD(&device->physical_node_list);
        mutex_init(&device->physical_node_lock);
+       INIT_LIST_HEAD(&device->power_dependent);
 
        new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
        if (!new_bus_id) {
-               printk(KERN_ERR PREFIX "Memory allocation error\n");
-               return -ENOMEM;
+               pr_err(PREFIX "Memory allocation error\n");
+               result = -ENOMEM;
+               goto err_detach;
        }
 
        mutex_lock(&acpi_device_lock);
@@ -681,11 +753,11 @@ static int acpi_device_register(struct acpi_device *device)
        if (device->parent)
                device->dev.parent = &device->parent->dev;
        device->dev.bus = &acpi_bus_type;
-       device->dev.release = &acpi_device_release;
-       result = device_register(&device->dev);
+       device->dev.release = release;
+       result = device_add(&device->dev);
        if (result) {
                dev_err(&device->dev, "Error registering device\n");
-               goto end;
+               goto err;
        }
 
        result = acpi_device_setup_files(device);
@@ -695,16 +767,20 @@ static int acpi_device_register(struct acpi_device *device)
 
        device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
        return 0;
-end:
+
+ err:
        mutex_lock(&acpi_device_lock);
        if (device->parent)
                list_del(&device->node);
        list_del(&device->wakeup_list);
        mutex_unlock(&acpi_device_lock);
+
+ err_detach:
+       acpi_detach_data(device->handle, acpi_bus_data_handler);
        return result;
 }
 
-static void acpi_device_unregister(struct acpi_device *device, int type)
+static void acpi_device_unregister(struct acpi_device *device)
 {
        mutex_lock(&acpi_device_lock);
        if (device->parent)
@@ -715,8 +791,20 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
 
        acpi_detach_data(device->handle, acpi_bus_data_handler);
 
+       acpi_power_add_remove_device(device, false);
        acpi_device_remove_files(device);
-       device_unregister(&device->dev);
+       if (device->remove)
+               device->remove(device);
+
+       device_del(&device->dev);
+       /*
+        * Transition the device to D3cold to drop the reference counts of all
+        * power resources the device depends on and turn off the ones that have
+        * no more references.
+        */
+       acpi_device_set_power(device, ACPI_STATE_D3_COLD);
+       device->handle = NULL;
+       put_device(&device->dev);
 }
 
 /* --------------------------------------------------------------------------
@@ -760,24 +848,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
        return 0;
 }
 
-static int acpi_start_single_object(struct acpi_device *device)
-{
-       int result = 0;
-       struct acpi_driver *driver;
-
-
-       if (!(driver = device->driver))
-               return 0;
-
-       if (driver->ops.start) {
-               result = driver->ops.start(device);
-               if (result && driver->ops.remove)
-                       driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
-       }
-
-       return result;
-}
-
 /**
  * acpi_bus_register_driver - register a driver with the ACPI bus
  * @driver: driver being registered
@@ -821,29 +891,23 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver);
    -------------------------------------------------------------------------- */
 static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
 {
+       struct acpi_device *device = NULL;
        acpi_status status;
-       int ret;
-       struct acpi_device *device;
 
        /*
         * Fixed hardware devices do not appear in the namespace and do not
         * have handles, but we fabricate acpi_devices for them, so we have
         * to deal with them specially.
         */
-       if (handle == NULL)
+       if (!handle)
                return acpi_root;
 
        do {
                status = acpi_get_parent(handle, &handle);
-               if (status == AE_NULL_ENTRY)
-                       return NULL;
                if (ACPI_FAILURE(status))
-                       return acpi_root;
-
-               ret = acpi_bus_get_device(handle, &device);
-               if (ret == 0)
-                       return device;
-       } while (1);
+                       return status == AE_NULL_ENTRY ? NULL : acpi_root;
+       } while (acpi_bus_get_device(handle, &device));
+       return device;
 }
 
 acpi_status
@@ -877,52 +941,43 @@ void acpi_bus_data_handler(acpi_handle handle, void *context)
        return;
 }
 
-static int acpi_bus_get_perf_flags(struct acpi_device *device)
-{
-       device->performance.state = ACPI_STATE_UNKNOWN;
-       return 0;
-}
-
-static acpi_status
-acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
-                                            struct acpi_device_wakeup *wakeup)
+static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
+                                       struct acpi_device_wakeup *wakeup)
 {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *package = NULL;
        union acpi_object *element = NULL;
        acpi_status status;
-       int i = 0;
+       int err = -ENODATA;
 
        if (!wakeup)
-               return AE_BAD_PARAMETER;
+               return -EINVAL;
+
+       INIT_LIST_HEAD(&wakeup->resources);
 
        /* _PRW */
        status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
-               return status;
+               return err;
        }
 
        package = (union acpi_object *)buffer.pointer;
 
-       if (!package || (package->package.count < 2)) {
-               status = AE_BAD_DATA;
+       if (!package || package->package.count < 2)
                goto out;
-       }
 
        element = &(package->package.elements[0]);
-       if (!element) {
-               status = AE_BAD_DATA;
+       if (!element)
                goto out;
-       }
+
        if (element->type == ACPI_TYPE_PACKAGE) {
                if ((element->package.count < 2) ||
                    (element->package.elements[0].type !=
                     ACPI_TYPE_LOCAL_REFERENCE)
-                   || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) {
-                       status = AE_BAD_DATA;
+                   || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
                        goto out;
-               }
+
                wakeup->gpe_device =
                    element->package.elements[0].reference.handle;
                wakeup->gpe_number =
@@ -931,38 +986,35 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
                wakeup->gpe_device = NULL;
                wakeup->gpe_number = element->integer.value;
        } else {
-               status = AE_BAD_DATA;
                goto out;
        }
 
        element = &(package->package.elements[1]);
-       if (element->type != ACPI_TYPE_INTEGER) {
-               status = AE_BAD_DATA;
+       if (element->type != ACPI_TYPE_INTEGER)
                goto out;
-       }
+
        wakeup->sleep_state = element->integer.value;
 
-       if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
-               status = AE_NO_MEMORY;
+       err = acpi_extract_power_resources(package, 2, &wakeup->resources);
+       if (err)
                goto out;
-       }
-       wakeup->resources.count = package->package.count - 2;
-       for (i = 0; i < wakeup->resources.count; i++) {
-               element = &(package->package.elements[i + 2]);
-               if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
-                       status = AE_BAD_DATA;
-                       goto out;
-               }
 
-               wakeup->resources.handles[i] = element->reference.handle;
-       }
+       if (!list_empty(&wakeup->resources)) {
+               int sleep_state;
 
+               sleep_state = acpi_power_min_system_level(&wakeup->resources);
+               if (sleep_state < wakeup->sleep_state) {
+                       acpi_handle_warn(handle, "Overriding _PRW sleep state "
+                                        "(S%d) by S%d from power resources\n",
+                                        (int)wakeup->sleep_state, sleep_state);
+                       wakeup->sleep_state = sleep_state;
+               }
+       }
        acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
 
  out:
        kfree(buffer.pointer);
-
-       return status;
+       return err;
 }
 
 static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
@@ -1002,17 +1054,17 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
 {
        acpi_handle temp;
        acpi_status status = 0;
-       int psw_error;
+       int err;
 
        /* Presence of _PRW indicates wake capable */
        status = acpi_get_handle(device->handle, "_PRW", &temp);
        if (ACPI_FAILURE(status))
                return;
 
-       status = acpi_bus_extract_wakeup_device_power_package(device->handle,
-                                                             &device->wakeup);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
+       err = acpi_bus_extract_wakeup_device_power_package(device->handle,
+                                                          &device->wakeup);
+       if (err) {
+               dev_err(&device->dev, "_PRW evaluation error: %d\n", err);
                return;
        }
 
@@ -1025,20 +1077,73 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
         * So it is necessary to call _DSW object first. Only when it is not
         * present will the _PSW object used.
         */
-       psw_error = acpi_device_sleep_wake(device, 0, 0, 0);
-       if (psw_error)
+       err = acpi_device_sleep_wake(device, 0, 0, 0);
+       if (err)
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                "error in _DSW or _PSW evaluation\n"));
 }
 
-static void acpi_bus_add_power_resource(acpi_handle handle);
+static void acpi_bus_init_power_state(struct acpi_device *device, int state)
+{
+       struct acpi_device_power_state *ps = &device->power.states[state];
+       char pathname[5] = { '_', 'P', 'R', '0' + state, '\0' };
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       acpi_handle handle;
+       acpi_status status;
+
+       INIT_LIST_HEAD(&ps->resources);
+
+       /* Evaluate "_PRx" to get referenced power resources */
+       status = acpi_evaluate_object(device->handle, pathname, NULL, &buffer);
+       if (ACPI_SUCCESS(status)) {
+               union acpi_object *package = buffer.pointer;
+
+               if (buffer.length && package
+                   && package->type == ACPI_TYPE_PACKAGE
+                   && package->package.count) {
+                       int err = acpi_extract_power_resources(package, 0,
+                                                              &ps->resources);
+                       if (!err)
+                               device->power.flags.power_resources = 1;
+               }
+               ACPI_FREE(buffer.pointer);
+       }
+
+       /* Evaluate "_PSx" to see if we can do explicit sets */
+       pathname[2] = 'S';
+       status = acpi_get_handle(device->handle, pathname, &handle);
+       if (ACPI_SUCCESS(status))
+               ps->flags.explicit_set = 1;
+
+       /*
+        * State is valid if there are means to put the device into it.
+        * D3hot is only valid if _PR3 present.
+        */
+       if (!list_empty(&ps->resources)
+           || (ps->flags.explicit_set && state < ACPI_STATE_D3_HOT)) {
+               ps->flags.valid = 1;
+               ps->flags.os_accessible = 1;
+       }
+
+       ps->power = -1;         /* Unknown - driver assigned */
+       ps->latency = -1;       /* Unknown - driver assigned */
+}
 
-static int acpi_bus_get_power_flags(struct acpi_device *device)
+static void acpi_bus_get_power_flags(struct acpi_device *device)
 {
-       acpi_status status = 0;
-       acpi_handle handle = NULL;
-       u32 i = 0;
+       acpi_status status;
+       acpi_handle handle;
+       u32 i;
+
+       /* Presence of _PS0|_PR0 indicates 'power manageable' */
+       status = acpi_get_handle(device->handle, "_PS0", &handle);
+       if (ACPI_FAILURE(status)) {
+               status = acpi_get_handle(device->handle, "_PR0", &handle);
+               if (ACPI_FAILURE(status))
+                       return;
+       }
 
+       device->flags.power_manageable = 1;
 
        /*
         * Power Management Flags
@@ -1053,40 +1158,10 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
        /*
         * Enumerate supported power management states
         */
-       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
-               struct acpi_device_power_state *ps = &device->power.states[i];
-               char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
-
-               /* Evaluate "_PRx" to se if power resources are referenced */
-               acpi_evaluate_reference(device->handle, object_name, NULL,
-                                       &ps->resources);
-               if (ps->resources.count) {
-                       int j;
-
-                       device->power.flags.power_resources = 1;
-                       for (j = 0; j < ps->resources.count; j++)
-                               acpi_bus_add_power_resource(ps->resources.handles[j]);
-               }
+       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++)
+               acpi_bus_init_power_state(device, i);
 
-               /* Evaluate "_PSx" to see if we can do explicit sets */
-               object_name[2] = 'S';
-               status = acpi_get_handle(device->handle, object_name, &handle);
-               if (ACPI_SUCCESS(status))
-                       ps->flags.explicit_set = 1;
-
-               /*
-                * State is valid if there are means to put the device into it.
-                * D3hot is only valid if _PR3 present.
-                */
-               if (ps->resources.count ||
-                   (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT)) {
-                       ps->flags.valid = 1;
-                       ps->flags.os_accessible = 1;
-               }
-
-               ps->power = -1; /* Unknown - driver assigned */
-               ps->latency = -1;       /* Unknown - driver assigned */
-       }
+       INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources);
 
        /* Set defaults for D0 and D3 states (always valid) */
        device->power.states[ACPI_STATE_D0].flags.valid = 1;
@@ -1103,17 +1178,17 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
                        device->power.flags.power_resources)
                device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
 
-       acpi_bus_init_power(device);
-
-       return 0;
+       if (acpi_bus_init_power(device)) {
+               acpi_free_power_resources_lists(device);
+               device->flags.power_manageable = 0;
+       }
 }
 
-static int acpi_bus_get_flags(struct acpi_device *device)
+static void acpi_bus_get_flags(struct acpi_device *device)
 {
        acpi_status status = AE_OK;
        acpi_handle temp = NULL;
 
-
        /* Presence of _STA indicates 'dynamic_status' */
        status = acpi_get_handle(device->handle, "_STA", &temp);
        if (ACPI_SUCCESS(status))
@@ -1133,21 +1208,6 @@ static int acpi_bus_get_flags(struct acpi_device *device)
                if (ACPI_SUCCESS(status))
                        device->flags.ejectable = 1;
        }
-
-       /* Power resources cannot be power manageable. */
-       if (device->device_type == ACPI_BUS_TYPE_POWER)
-               return 0;
-
-       /* Presence of _PS0|_PR0 indicates 'power manageable' */
-       status = acpi_get_handle(device->handle, "_PS0", &temp);
-       if (ACPI_FAILURE(status))
-               status = acpi_get_handle(device->handle, "_PR0", &temp);
-       if (ACPI_SUCCESS(status))
-               device->flags.power_manageable = 1;
-
-       /* TBD: Performance management */
-
-       return 0;
 }
 
 static void acpi_device_get_busid(struct acpi_device *device)
@@ -1372,56 +1432,32 @@ static void acpi_device_set_id(struct acpi_device *device)
        }
 }
 
-static int acpi_device_set_context(struct acpi_device *device)
+void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
+                            int type, unsigned long long sta)
 {
-       acpi_status status;
-
-       /*
-        * Context
-        * -------
-        * Attach this 'struct acpi_device' to the ACPI object.  This makes
-        * resolutions from handle->device very efficient.  Fixed hardware
-        * devices have no handles, so we skip them.
-        */
-       if (!device->handle)
-               return 0;
-
-       status = acpi_attach_data(device->handle,
-                                 acpi_bus_data_handler, device);
-       if (ACPI_SUCCESS(status))
-               return 0;
-
-       printk(KERN_ERR PREFIX "Error attaching device data\n");
-       return -ENODEV;
+       INIT_LIST_HEAD(&device->pnp.ids);
+       device->device_type = type;
+       device->handle = handle;
+       device->parent = acpi_bus_get_parent(handle);
+       STRUCT_TO_INT(device->status) = sta;
+       acpi_device_get_busid(device);
+       acpi_device_set_id(device);
+       acpi_bus_get_flags(device);
+       device->flags.match_driver = false;
+       device_initialize(&device->dev);
+       dev_set_uevent_suppress(&device->dev, true);
 }
 
-static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
+void acpi_device_add_finalize(struct acpi_device *device)
 {
-       if (!dev)
-               return -EINVAL;
-
-       dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
-       device_release_driver(&dev->dev);
-
-       if (!rmdevice)
-               return 0;
-
-       /*
-        * unbind _ADR-Based Devices when hot removal
-        */
-       if (dev->flags.bus_address) {
-               if ((dev->parent) && (dev->parent->ops.unbind))
-                       dev->parent->ops.unbind(dev);
-       }
-       acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
-
-       return 0;
+       device->flags.match_driver = true;
+       dev_set_uevent_suppress(&device->dev, false);
+       kobject_uevent(&device->dev.kobj, KOBJ_ADD);
 }
 
 static int acpi_add_single_object(struct acpi_device **child,
                                  acpi_handle handle, int type,
-                                 unsigned long long sta,
-                                 struct acpi_bus_ops *ops)
+                                 unsigned long long sta)
 {
        int result;
        struct acpi_device *device;
@@ -1433,102 +1469,25 @@ static int acpi_add_single_object(struct acpi_device **child,
                return -ENOMEM;
        }
 
-       INIT_LIST_HEAD(&device->pnp.ids);
-       device->device_type = type;
-       device->handle = handle;
-       device->parent = acpi_bus_get_parent(handle);
-       device->bus_ops = *ops; /* workround for not call .start */
-       STRUCT_TO_INT(device->status) = sta;
-
-       acpi_device_get_busid(device);
-
-       /*
-        * Flags
-        * -----
-        * Note that we only look for object handles -- cannot evaluate objects
-        * until we know the device is present and properly initialized.
-        */
-       result = acpi_bus_get_flags(device);
-       if (result)
-               goto end;
-
-       /*
-        * Initialize Device
-        * -----------------
-        * TBD: Synch with Core's enumeration/initialization process.
-        */
-       acpi_device_set_id(device);
-
-       /*
-        * Power Management
-        * ----------------
-        */
-       if (device->flags.power_manageable) {
-               result = acpi_bus_get_power_flags(device);
-               if (result)
-                       goto end;
-       }
-
-       /*
-        * Wakeup device management
-        *-----------------------
-        */
+       acpi_init_device_object(device, handle, type, sta);
+       acpi_bus_get_power_flags(device);
        acpi_bus_get_wakeup_device_flags(device);
 
-       /*
-        * Performance Management
-        * ----------------------
-        */
-       if (device->flags.performance_manageable) {
-               result = acpi_bus_get_perf_flags(device);
-               if (result)
-                       goto end;
-       }
-
-       if ((result = acpi_device_set_context(device)))
-               goto end;
-
-       result = acpi_device_register(device);
-
-       /*
-        * Bind _ADR-Based Devices when hot add
-        */
-       if (device->flags.bus_address) {
-               if (device->parent && device->parent->ops.bind)
-                       device->parent->ops.bind(device);
-       }
-
-end:
-       if (!result) {
-               acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                       "Adding %s [%s] parent %s\n", dev_name(&device->dev),
-                        (char *) buffer.pointer,
-                        device->parent ? dev_name(&device->parent->dev) :
-                                         "(null)"));
-               kfree(buffer.pointer);
-               *child = device;
-       } else
+       result = acpi_device_add(device, acpi_device_release);
+       if (result) {
                acpi_device_release(&device->dev);
+               return result;
+       }
 
-       return result;
-}
-
-#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
-                         ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING)
-
-static void acpi_bus_add_power_resource(acpi_handle handle)
-{
-       struct acpi_bus_ops ops = {
-               .acpi_op_add = 1,
-               .acpi_op_start = 1,
-       };
-       struct acpi_device *device = NULL;
-
-       acpi_bus_get_device(handle, &device);
-       if (!device)
-               acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
-                                       ACPI_STA_DEFAULT, &ops);
+       acpi_power_add_remove_device(device, true);
+       acpi_device_add_finalize(device);
+       acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Added %s [%s] parent %s\n",
+               dev_name(&device->dev), (char *) buffer.pointer,
+               device->parent ? dev_name(&device->parent->dev) : "(null)"));
+       kfree(buffer.pointer);
+       *child = device;
+       return 0;
 }
 
 static int acpi_bus_type_and_status(acpi_handle handle, int *type,
@@ -1570,218 +1529,248 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type,
        return 0;
 }
 
-static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
-                                     void *context, void **return_value)
+static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
+                                     void *not_used, void **return_value)
 {
-       struct acpi_bus_ops *ops = context;
+       struct acpi_device *device = NULL;
        int type;
        unsigned long long sta;
-       struct acpi_device *device;
        acpi_status status;
        int result;
 
+       acpi_bus_get_device(handle, &device);
+       if (device)
+               goto out;
+
        result = acpi_bus_type_and_status(handle, &type, &sta);
        if (result)
                return AE_OK;
 
+       if (type == ACPI_BUS_TYPE_POWER) {
+               acpi_add_power_resource(handle);
+               return AE_OK;
+       }
+
        if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
            !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
                struct acpi_device_wakeup wakeup;
                acpi_handle temp;
 
                status = acpi_get_handle(handle, "_PRW", &temp);
-               if (ACPI_SUCCESS(status))
+               if (ACPI_SUCCESS(status)) {
                        acpi_bus_extract_wakeup_device_power_package(handle,
                                                                     &wakeup);
+                       acpi_power_resources_list_free(&wakeup.resources);
+               }
                return AE_CTRL_DEPTH;
        }
 
-       /*
-        * We may already have an acpi_device from a previous enumeration.  If
-        * so, we needn't add it again, but we may still have to start it.
-        */
-       device = NULL;
-       acpi_bus_get_device(handle, &device);
-       if (ops->acpi_op_add && !device) {
-               acpi_add_single_object(&device, handle, type, sta, ops);
-               /* Is the device a known good platform device? */
-               if (device
-                   && !acpi_match_device_ids(device, acpi_platform_device_ids))
-                       acpi_create_platform_device(device);
-       }
-
+       acpi_add_single_object(&device, handle, type, sta);
        if (!device)
                return AE_CTRL_DEPTH;
 
-       if (ops->acpi_op_start && !(ops->acpi_op_add)) {
-               status = acpi_start_single_object(device);
-               if (ACPI_FAILURE(status))
-                       return AE_CTRL_DEPTH;
-       }
-
+ out:
        if (!*return_value)
                *return_value = device;
+
        return AE_OK;
 }
 
-static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
-                        struct acpi_device **child)
+static int acpi_scan_do_attach_handler(struct acpi_device *device, char *id)
 {
-       acpi_status status;
-       void *device = NULL;
+       struct acpi_scan_handler *handler;
 
-       status = acpi_bus_check_add(handle, 0, ops, &device);
-       if (ACPI_SUCCESS(status))
-               acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
-                                   acpi_bus_check_add, NULL, ops, &device);
+       list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) {
+               const struct acpi_device_id *devid;
 
-       if (child)
-               *child = device;
+               for (devid = handler->ids; devid->id[0]; devid++) {
+                       int ret;
 
-       if (device)
-               return 0;
-       else
-               return -ENODEV;
-}
+                       if (strcmp((char *)devid->id, id))
+                               continue;
 
-/*
- * acpi_bus_add and acpi_bus_start
- *
- * scan a given ACPI tree and (probably recently hot-plugged)
- * create and add or starts found devices.
- *
- * If no devices were found -ENODEV is returned which does not
- * mean that this is a real error, there just have been no suitable
- * ACPI objects in the table trunk from which the kernel could create
- * a device and add/start an appropriate driver.
- */
+                       ret = handler->attach(device, devid);
+                       if (ret > 0) {
+                               device->handler = handler;
+                               return ret;
+                       } else if (ret < 0) {
+                               return ret;
+                       }
+               }
+       }
+       return 0;
+}
 
-int
-acpi_bus_add(struct acpi_device **child,
-            struct acpi_device *parent, acpi_handle handle, int type)
+static int acpi_scan_attach_handler(struct acpi_device *device)
 {
-       struct acpi_bus_ops ops;
+       struct acpi_hardware_id *hwid;
+       int ret = 0;
 
-       memset(&ops, 0, sizeof(ops));
-       ops.acpi_op_add = 1;
+       list_for_each_entry(hwid, &device->pnp.ids, list) {
+               ret = acpi_scan_do_attach_handler(device, hwid->id);
+               if (ret)
+                       break;
 
-       return acpi_bus_scan(handle, &ops, child);
+       }
+       return ret;
 }
-EXPORT_SYMBOL(acpi_bus_add);
 
-int acpi_bus_start(struct acpi_device *device)
+static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
+                                         void *not_used, void **ret_not_used)
 {
-       struct acpi_bus_ops ops;
-       int result;
-
-       if (!device)
-               return -EINVAL;
+       struct acpi_device *device;
+       unsigned long long sta_not_used;
+       int ret;
 
-       memset(&ops, 0, sizeof(ops));
-       ops.acpi_op_start = 1;
+       /*
+        * Ignore errors ignored by acpi_bus_check_add() to avoid terminating
+        * namespace walks prematurely.
+        */
+       if (acpi_bus_type_and_status(handle, &ret, &sta_not_used))
+               return AE_OK;
 
-       result = acpi_bus_scan(device->handle, &ops, NULL);
+       if (acpi_bus_get_device(handle, &device))
+               return AE_CTRL_DEPTH;
 
-       acpi_update_all_gpes();
+       ret = acpi_scan_attach_handler(device);
+       if (ret)
+               return ret > 0 ? AE_OK : AE_CTRL_DEPTH;
 
-       return result;
+       ret = device_attach(&device->dev);
+       return ret >= 0 ? AE_OK : AE_CTRL_DEPTH;
 }
-EXPORT_SYMBOL(acpi_bus_start);
 
-int acpi_bus_trim(struct acpi_device *start, int rmdevice)
+/**
+ * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
+ * @handle: Root of the namespace scope to scan.
+ *
+ * Scan a given ACPI tree (probably recently hot-plugged) and create and add
+ * found devices.
+ *
+ * If no devices were found, -ENODEV is returned, but it does not mean that
+ * there has been a real error.  There just have been no suitable ACPI objects
+ * in the table trunk from which the kernel could create a device and add an
+ * appropriate driver.
+ *
+ * Must be called under acpi_scan_lock.
+ */
+int acpi_bus_scan(acpi_handle handle)
 {
-       acpi_status status;
-       struct acpi_device *parent, *child;
-       acpi_handle phandle, chandle;
-       acpi_object_type type;
-       u32 level = 1;
-       int err = 0;
+       void *device = NULL;
+       int error = 0;
 
-       parent = start;
-       phandle = start->handle;
-       child = chandle = NULL;
+       if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
+               acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+                                   acpi_bus_check_add, NULL, NULL, &device);
 
-       while ((level > 0) && parent && (!err)) {
-               status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
-                                             chandle, &chandle);
+       if (!device)
+               error = -ENODEV;
+       else if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL)))
+               acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+                                   acpi_bus_device_attach, NULL, NULL, NULL);
 
-               /*
-                * If this scope is exhausted then move our way back up.
-                */
-               if (ACPI_FAILURE(status)) {
-                       level--;
-                       chandle = phandle;
-                       acpi_get_parent(phandle, &phandle);
-                       child = parent;
-                       parent = parent->parent;
-
-                       if (level == 0)
-                               err = acpi_bus_remove(child, rmdevice);
-                       else
-                               err = acpi_bus_remove(child, 1);
+       return error;
+}
+EXPORT_SYMBOL(acpi_bus_scan);
 
-                       continue;
-               }
+static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used,
+                                         void *not_used, void **ret_not_used)
+{
+       struct acpi_device *device = NULL;
 
-               status = acpi_get_type(chandle, &type);
-               if (ACPI_FAILURE(status)) {
-                       continue;
-               }
-               /*
-                * If there is a device corresponding to chandle then
-                * parse it (depth-first).
-                */
-               if (acpi_bus_get_device(chandle, &child) == 0) {
-                       level++;
-                       phandle = chandle;
-                       chandle = NULL;
-                       parent = child;
+       if (!acpi_bus_get_device(handle, &device)) {
+               struct acpi_scan_handler *dev_handler = device->handler;
+
+               device->removal_type = ACPI_BUS_REMOVAL_EJECT;
+               if (dev_handler) {
+                       if (dev_handler->detach)
+                               dev_handler->detach(device);
+
+                       device->handler = NULL;
+               } else {
+                       device_release_driver(&device->dev);
                }
-               continue;
        }
-       return err;
+       return AE_OK;
+}
+
+static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
+                                  void *not_used, void **ret_not_used)
+{
+       struct acpi_device *device = NULL;
+
+       if (!acpi_bus_get_device(handle, &device))
+               acpi_device_unregister(device);
+
+       return AE_OK;
+}
+
+/**
+ * acpi_bus_trim - Remove ACPI device node and all of its descendants
+ * @start: Root of the ACPI device nodes subtree to remove.
+ *
+ * Must be called under acpi_scan_lock.
+ */
+void acpi_bus_trim(struct acpi_device *start)
+{
+       /*
+        * Execute acpi_bus_device_detach() as a post-order callback to detach
+        * all ACPI drivers from the device nodes being removed.
+        */
+       acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
+                           acpi_bus_device_detach, NULL, NULL);
+       acpi_bus_device_detach(start->handle, 0, NULL, NULL);
+       /*
+        * Execute acpi_bus_remove() as a post-order callback to remove device
+        * nodes in the given namespace scope.
+        */
+       acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
+                           acpi_bus_remove, NULL, NULL);
+       acpi_bus_remove(start->handle, 0, NULL, NULL);
 }
 EXPORT_SYMBOL_GPL(acpi_bus_trim);
 
 static int acpi_bus_scan_fixed(void)
 {
        int result = 0;
-       struct acpi_device *device = NULL;
-       struct acpi_bus_ops ops;
-
-       memset(&ops, 0, sizeof(ops));
-       ops.acpi_op_add = 1;
-       ops.acpi_op_start = 1;
 
        /*
         * Enumerate all fixed-feature devices.
         */
-       if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) {
+               struct acpi_device *device = NULL;
+
                result = acpi_add_single_object(&device, NULL,
                                                ACPI_BUS_TYPE_POWER_BUTTON,
-                                               ACPI_STA_DEFAULT,
-                                               &ops);
+                                               ACPI_STA_DEFAULT);
+               if (result)
+                       return result;
+
+               result = device_attach(&device->dev);
+               if (result < 0)
+                       return result;
+
                device_init_wakeup(&device->dev, true);
        }
 
-       if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON)) {
+               struct acpi_device *device = NULL;
+
                result = acpi_add_single_object(&device, NULL,
                                                ACPI_BUS_TYPE_SLEEP_BUTTON,
-                                               ACPI_STA_DEFAULT,
-                                               &ops);
+                                               ACPI_STA_DEFAULT);
+               if (result)
+                       return result;
+
+               result = device_attach(&device->dev);
        }
 
-       return result;
+       return result < 0 ? result : 0;
 }
 
 int __init acpi_scan_init(void)
 {
        int result;
-       struct acpi_bus_ops ops;
-
-       memset(&ops, 0, sizeof(ops));
-       ops.acpi_op_add = 1;
-       ops.acpi_op_start = 1;
 
        result = bus_register(&acpi_bus_type);
        if (result) {
@@ -1789,20 +1778,33 @@ int __init acpi_scan_init(void)
                printk(KERN_ERR PREFIX "Could not register bus type\n");
        }
 
-       acpi_power_init();
+       acpi_pci_root_init();
+       acpi_pci_link_init();
+       acpi_platform_init();
+       acpi_csrt_init();
+       acpi_container_init();
 
+       mutex_lock(&acpi_scan_lock);
        /*
         * Enumerate devices in the ACPI namespace.
         */
-       result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root);
-
-       if (!result)
-               result = acpi_bus_scan_fixed();
+       result = acpi_bus_scan(ACPI_ROOT_OBJECT);
+       if (result)
+               goto out;
 
+       result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root);
        if (result)
-               acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
-       else
-               acpi_update_all_gpes();
+               goto out;
+
+       result = acpi_bus_scan_fixed();
+       if (result) {
+               acpi_device_unregister(acpi_root);
+               goto out;
+       }
 
+       acpi_update_all_gpes();
+
+ out:
+       mutex_unlock(&acpi_scan_lock);
        return result;
 }
index 2fcc67d..6d3a06a 100644 (file)
@@ -177,6 +177,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        },
        {
        .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-FW41E_H",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW41E_H"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
        .ident = "Sony Vaio VGN-FW21E",
        .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
@@ -386,6 +394,8 @@ static void acpi_pm_finish(void)
 
        acpi_target_sleep_state = ACPI_STATE_S0;
 
+       acpi_resume_power_resources();
+
        /* If we were woken with the fixed power button, provide a small
         * hint to userspace in the form of a wakeup event on the fixed power
         * button device (if it can be found).
@@ -577,7 +587,28 @@ static const struct platform_suspend_ops acpi_suspend_ops_old = {
        .end = acpi_pm_end,
        .recover = acpi_pm_finish,
 };
-#endif /* CONFIG_SUSPEND */
+
+static void acpi_sleep_suspend_setup(void)
+{
+       int i;
+
+       for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) {
+               acpi_status status;
+               u8 type_a, type_b;
+
+               status = acpi_get_sleep_type_data(i, &type_a, &type_b);
+               if (ACPI_SUCCESS(status)) {
+                       sleep_states[i] = 1;
+                       pr_cont(" S%d", i);
+               }
+       }
+
+       suspend_set_ops(old_suspend_ordering ?
+               &acpi_suspend_ops_old : &acpi_suspend_ops);
+}
+#else /* !CONFIG_SUSPEND */
+static inline void acpi_sleep_suspend_setup(void) {}
+#endif /* !CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATION
 static unsigned long s4_hardware_signature;
@@ -698,7 +729,30 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
        .restore_cleanup = acpi_pm_thaw,
        .recover = acpi_pm_finish,
 };
-#endif /* CONFIG_HIBERNATION */
+
+static void acpi_sleep_hibernate_setup(void)
+{
+       acpi_status status;
+       u8 type_a, type_b;
+
+       status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b);
+       if (ACPI_FAILURE(status))
+               return;
+
+       hibernation_set_ops(old_suspend_ordering ?
+                       &acpi_hibernation_ops_old : &acpi_hibernation_ops);
+       sleep_states[ACPI_STATE_S4] = 1;
+       pr_cont(KERN_CONT " S4");
+       if (nosigcheck)
+               return;
+
+       acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs);
+       if (facs)
+               s4_hardware_signature = facs->hardware_signature;
+}
+#else /* !CONFIG_HIBERNATION */
+static inline void acpi_sleep_hibernate_setup(void) {}
+#endif /* !CONFIG_HIBERNATION */
 
 int acpi_suspend(u32 acpi_state)
 {
@@ -734,9 +788,6 @@ int __init acpi_sleep_init(void)
 {
        acpi_status status;
        u8 type_a, type_b;
-#ifdef CONFIG_SUSPEND
-       int i = 0;
-#endif
 
        if (acpi_disabled)
                return 0;
@@ -744,45 +795,19 @@ int __init acpi_sleep_init(void)
        acpi_sleep_dmi_check();
 
        sleep_states[ACPI_STATE_S0] = 1;
-       printk(KERN_INFO PREFIX "(supports S0");
-
-#ifdef CONFIG_SUSPEND
-       for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) {
-               status = acpi_get_sleep_type_data(i, &type_a, &type_b);
-               if (ACPI_SUCCESS(status)) {
-                       sleep_states[i] = 1;
-                       printk(KERN_CONT " S%d", i);
-               }
-       }
+       pr_info(PREFIX "(supports S0");
 
-       suspend_set_ops(old_suspend_ordering ?
-               &acpi_suspend_ops_old : &acpi_suspend_ops);
-#endif
+       acpi_sleep_suspend_setup();
+       acpi_sleep_hibernate_setup();
 
-#ifdef CONFIG_HIBERNATION
-       status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b);
-       if (ACPI_SUCCESS(status)) {
-               hibernation_set_ops(old_suspend_ordering ?
-                       &acpi_hibernation_ops_old : &acpi_hibernation_ops);
-               sleep_states[ACPI_STATE_S4] = 1;
-               printk(KERN_CONT " S4");
-               if (!nosigcheck) {
-                       acpi_get_table(ACPI_SIG_FACS, 1,
-                               (struct acpi_table_header **)&facs);
-                       if (facs)
-                               s4_hardware_signature =
-                                       facs->hardware_signature;
-               }
-       }
-#endif
        status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
        if (ACPI_SUCCESS(status)) {
                sleep_states[ACPI_STATE_S5] = 1;
-               printk(KERN_CONT " S5");
+               pr_cont(" S5");
                pm_power_off_prepare = acpi_power_off_prepare;
                pm_power_off = acpi_power_off;
        }
-       printk(KERN_CONT ")\n");
+       pr_cont(")\n");
        /*
         * Register the tts_notifier to reboot notifier list so that the _TTS
         * object can also be evaluated when the system enters S5.
index 74d59c8..0143540 100644 (file)
@@ -6,3 +6,5 @@ extern void acpi_disable_wakeup_devices(u8 sleep_state);
 
 extern struct list_head acpi_wakeup_device_list;
 extern struct mutex acpi_device_lock;
+
+extern void acpi_resume_power_resources(void);
index ea61ca9..41c0504 100644 (file)
@@ -498,7 +498,7 @@ static int get_status(u32 index, acpi_event_status *status,
                result = acpi_get_gpe_device(index, handle);
                if (result) {
                        ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
-                                       "Invalid GPE 0x%x\n", index));
+                                       "Invalid GPE 0x%x", index));
                        goto end;
                }
                result = acpi_get_gpe_status(*handle, index, status);
index 2572d97..d67a1fe 100644 (file)
@@ -204,7 +204,7 @@ int __init
 acpi_table_parse_entries(char *id,
                             unsigned long table_size,
                             int entry_id,
-                            acpi_table_entry_handler handler,
+                            acpi_tbl_entry_handler handler,
                             unsigned int max_entries)
 {
        struct acpi_table_header *table_header = NULL;
@@ -269,7 +269,7 @@ err:
 
 int __init
 acpi_table_parse_madt(enum acpi_madt_type id,
-                     acpi_table_entry_handler handler, unsigned int max_entries)
+                     acpi_tbl_entry_handler handler, unsigned int max_entries)
 {
        return acpi_table_parse_entries(ACPI_SIG_MADT,
                                            sizeof(struct acpi_table_madt), id,
@@ -285,7 +285,7 @@ acpi_table_parse_madt(enum acpi_madt_type id,
  * Scan the ACPI System Descriptor Table (STD) for a table matching @id,
  * run @handler on it.  Return 0 if table found, return on if not.
  */
-int __init acpi_table_parse(char *id, acpi_table_handler handler)
+int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
 {
        struct acpi_table_header *table = NULL;
        acpi_size tbl_size;
index 506fbd4..8470771 100644 (file)
@@ -97,7 +97,7 @@ module_param(psv, int, 0644);
 MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
 
 static int acpi_thermal_add(struct acpi_device *device);
-static int acpi_thermal_remove(struct acpi_device *device, int type);
+static int acpi_thermal_remove(struct acpi_device *device);
 static void acpi_thermal_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id  thermal_device_ids[] = {
@@ -288,7 +288,7 @@ do {        \
        if (flags != ACPI_TRIPS_INIT)   \
                ACPI_EXCEPTION((AE_INFO, AE_ERROR,      \
                "ACPI thermal trip point %s changed\n"  \
-               "Please send acpidump to linux-acpi@vger.kernel.org\n", str)); \
+               "Please send acpidump to linux-acpi@vger.kernel.org", str)); \
 } while (0)
 
 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
@@ -531,6 +531,10 @@ static void acpi_thermal_check(void *data)
 {
        struct acpi_thermal *tz = data;
 
+       if (!tz->tz_enabled) {
+               pr_warn("thermal zone is disabled \n");
+               return;
+       }
        thermal_zone_device_update(tz->thermal_zone);
 }
 
@@ -1111,7 +1115,7 @@ end:
        return result;
 }
 
-static int acpi_thermal_remove(struct acpi_device *device, int type)
+static int acpi_thermal_remove(struct acpi_device *device)
 {
        struct acpi_thermal *tz = NULL;
 
index ac9a69c..313f959 100644 (file)
@@ -88,7 +88,7 @@ module_param(use_bios_initial_backlight, bool, 0644);
 
 static int register_count = 0;
 static int acpi_video_bus_add(struct acpi_device *device);
-static int acpi_video_bus_remove(struct acpi_device *device, int type);
+static int acpi_video_bus_remove(struct acpi_device *device);
 static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id video_device_ids[] = {
@@ -673,7 +673,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
                        br->levels[i] = br->levels[i - level_ac_battery];
                count += level_ac_battery;
        } else if (level_ac_battery > 2)
-               ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
+               ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package"));
 
        /* Check if the _BCL package is in a reversed order */
        if (max_level == br->levels[2]) {
@@ -682,7 +682,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
                        acpi_video_cmp_level, NULL);
        } else if (max_level != br->levels[count - 1])
                ACPI_ERROR((AE_INFO,
-                           "Found unordered _BCL package\n"));
+                           "Found unordered _BCL package"));
 
        br->count = count;
        device->brightness = br;
@@ -1740,7 +1740,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
        return error;
 }
 
-static int acpi_video_bus_remove(struct acpi_device *device, int type)
+static int acpi_video_bus_remove(struct acpi_device *device)
 {
        struct acpi_video_bus *video = NULL;
 
index ef01ac0..6fc67f7 100644 (file)
@@ -1029,30 +1029,20 @@ static void ata_acpi_register_power_resource(struct ata_device *dev)
 {
        struct scsi_device *sdev = dev->sdev;
        acpi_handle handle;
-       struct device *device;
 
        handle = ata_dev_acpi_handle(dev);
-       if (!handle)
-               return;
-
-       device = &sdev->sdev_gendev;
-
-       acpi_power_resource_register_device(device, handle);
+       if (handle)
+               acpi_dev_pm_remove_dependent(handle, &sdev->sdev_gendev);
 }
 
 static void ata_acpi_unregister_power_resource(struct ata_device *dev)
 {
        struct scsi_device *sdev = dev->sdev;
        acpi_handle handle;
-       struct device *device;
 
        handle = ata_dev_acpi_handle(dev);
-       if (!handle)
-               return;
-
-       device = &sdev->sdev_gendev;
-
-       acpi_power_resource_unregister_device(device, handle);
+       if (handle)
+               acpi_dev_pm_remove_dependent(handle, &sdev->sdev_gendev);
 }
 
 void ata_acpi_bind(struct ata_device *dev)
index 6a0955e..53ecac5 100644 (file)
@@ -636,82 +636,82 @@ struct rx_buf_desc {
 #define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE  
 #define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE  
 
-typedef volatile u_int  freg_t;
+typedef volatile u_int ffreg_t;
 typedef u_int   rreg_t;
 
 typedef struct _ffredn_t {
-        freg_t  idlehead_high;  /* Idle cell header (high)              */
-        freg_t  idlehead_low;   /* Idle cell header (low)               */
-        freg_t  maxrate;        /* Maximum rate                         */
-        freg_t  stparms;        /* Traffic Management Parameters        */
-        freg_t  abrubr_abr;     /* ABRUBR Priority Byte 1, TCR Byte 0   */
-        freg_t  rm_type;        /*                                      */
-        u_int   filler5[0x17 - 0x06];
-        freg_t  cmd_reg;        /* Command register                     */
-        u_int   filler18[0x20 - 0x18];
-        freg_t  cbr_base;       /* CBR Pointer Base                     */
-        freg_t  vbr_base;       /* VBR Pointer Base                     */
-        freg_t  abr_base;       /* ABR Pointer Base                     */
-        freg_t  ubr_base;       /* UBR Pointer Base                     */
-        u_int   filler24;
-        freg_t  vbrwq_base;     /* VBR Wait Queue Base                  */
-        freg_t  abrwq_base;     /* ABR Wait Queue Base                  */
-        freg_t  ubrwq_base;     /* UBR Wait Queue Base                  */
-        freg_t  vct_base;       /* Main VC Table Base                   */
-        freg_t  vcte_base;      /* Extended Main VC Table Base          */
-        u_int   filler2a[0x2C - 0x2A];
-        freg_t  cbr_tab_beg;    /* CBR Table Begin                      */
-        freg_t  cbr_tab_end;    /* CBR Table End                        */
-        freg_t  cbr_pointer;    /* CBR Pointer                          */
-        u_int   filler2f[0x30 - 0x2F];
-        freg_t  prq_st_adr;     /* Packet Ready Queue Start Address     */
-        freg_t  prq_ed_adr;     /* Packet Ready Queue End Address       */
-        freg_t  prq_rd_ptr;     /* Packet Ready Queue read pointer      */
-        freg_t  prq_wr_ptr;     /* Packet Ready Queue write pointer     */
-        freg_t  tcq_st_adr;     /* Transmit Complete Queue Start Address*/
-        freg_t  tcq_ed_adr;     /* Transmit Complete Queue End Address  */
-        freg_t  tcq_rd_ptr;     /* Transmit Complete Queue read pointer */
-        freg_t  tcq_wr_ptr;     /* Transmit Complete Queue write pointer*/
-        u_int   filler38[0x40 - 0x38];
-        freg_t  queue_base;     /* Base address for PRQ and TCQ         */
-        freg_t  desc_base;      /* Base address of descriptor table     */
-        u_int   filler42[0x45 - 0x42];
-        freg_t  mode_reg_0;     /* Mode register 0                      */
-        freg_t  mode_reg_1;     /* Mode register 1                      */
-        freg_t  intr_status_reg;/* Interrupt Status register            */
-        freg_t  mask_reg;       /* Mask Register                        */
-        freg_t  cell_ctr_high1; /* Total cell transfer count (high)     */
-        freg_t  cell_ctr_lo1;   /* Total cell transfer count (low)      */
-        freg_t  state_reg;      /* Status register                      */
-        u_int   filler4c[0x58 - 0x4c];
-        freg_t  curr_desc_num;  /* Contains the current descriptor num  */
-        freg_t  next_desc;      /* Next descriptor                      */
-        freg_t  next_vc;        /* Next VC                              */
-        u_int   filler5b[0x5d - 0x5b];
-        freg_t  present_slot_cnt;/* Present slot count                  */
-        u_int   filler5e[0x6a - 0x5e];
-        freg_t  new_desc_num;   /* New descriptor number                */
-        freg_t  new_vc;         /* New VC                               */
-        freg_t  sched_tbl_ptr;  /* Schedule table pointer               */
-        freg_t  vbrwq_wptr;     /* VBR wait queue write pointer         */
-        freg_t  vbrwq_rptr;     /* VBR wait queue read pointer          */
-        freg_t  abrwq_wptr;     /* ABR wait queue write pointer         */
-        freg_t  abrwq_rptr;     /* ABR wait queue read pointer          */
-        freg_t  ubrwq_wptr;     /* UBR wait queue write pointer         */
-        freg_t  ubrwq_rptr;     /* UBR wait queue read pointer          */
-        freg_t  cbr_vc;         /* CBR VC                               */
-        freg_t  vbr_sb_vc;      /* VBR SB VC                            */
-        freg_t  abr_sb_vc;      /* ABR SB VC                            */
-        freg_t  ubr_sb_vc;      /* UBR SB VC                            */
-        freg_t  vbr_next_link;  /* VBR next link                        */
-        freg_t  abr_next_link;  /* ABR next link                        */
-        freg_t  ubr_next_link;  /* UBR next link                        */
-        u_int   filler7a[0x7c-0x7a];
-        freg_t  out_rate_head;  /* Out of rate head                     */
-        u_int   filler7d[0xca-0x7d]; /* pad out to full address space   */
-        freg_t  cell_ctr_high1_nc;/* Total cell transfer count (high)   */
-        freg_t  cell_ctr_lo1_nc;/* Total cell transfer count (low)      */
-        u_int   fillercc[0x100-0xcc]; /* pad out to full address space   */
+       ffreg_t idlehead_high;  /* Idle cell header (high)              */
+       ffreg_t idlehead_low;   /* Idle cell header (low)               */
+       ffreg_t maxrate;        /* Maximum rate                         */
+       ffreg_t stparms;        /* Traffic Management Parameters        */
+       ffreg_t abrubr_abr;     /* ABRUBR Priority Byte 1, TCR Byte 0   */
+       ffreg_t rm_type;        /*                                      */
+       u_int   filler5[0x17 - 0x06];
+       ffreg_t cmd_reg;        /* Command register                     */
+       u_int   filler18[0x20 - 0x18];
+       ffreg_t cbr_base;       /* CBR Pointer Base                     */
+       ffreg_t vbr_base;       /* VBR Pointer Base                     */
+       ffreg_t abr_base;       /* ABR Pointer Base                     */
+       ffreg_t ubr_base;       /* UBR Pointer Base                     */
+       u_int   filler24;
+       ffreg_t vbrwq_base;     /* VBR Wait Queue Base                  */
+       ffreg_t abrwq_base;     /* ABR Wait Queue Base                  */
+       ffreg_t ubrwq_base;     /* UBR Wait Queue Base                  */
+       ffreg_t vct_base;       /* Main VC Table Base                   */
+       ffreg_t vcte_base;      /* Extended Main VC Table Base          */
+       u_int   filler2a[0x2C - 0x2A];
+       ffreg_t cbr_tab_beg;    /* CBR Table Begin                      */
+       ffreg_t cbr_tab_end;    /* CBR Table End                        */
+       ffreg_t cbr_pointer;    /* CBR Pointer                          */
+       u_int   filler2f[0x30 - 0x2F];
+       ffreg_t prq_st_adr;     /* Packet Ready Queue Start Address     */
+       ffreg_t prq_ed_adr;     /* Packet Ready Queue End Address       */
+       ffreg_t prq_rd_ptr;     /* Packet Ready Queue read pointer      */
+       ffreg_t prq_wr_ptr;     /* Packet Ready Queue write pointer     */
+       ffreg_t tcq_st_adr;     /* Transmit Complete Queue Start Address*/
+       ffreg_t tcq_ed_adr;     /* Transmit Complete Queue End Address  */
+       ffreg_t tcq_rd_ptr;     /* Transmit Complete Queue read pointer */
+       ffreg_t tcq_wr_ptr;     /* Transmit Complete Queue write pointer*/
+       u_int   filler38[0x40 - 0x38];
+       ffreg_t queue_base;     /* Base address for PRQ and TCQ         */
+       ffreg_t desc_base;      /* Base address of descriptor table     */
+       u_int   filler42[0x45 - 0x42];
+       ffreg_t mode_reg_0;     /* Mode register 0                      */
+       ffreg_t mode_reg_1;     /* Mode register 1                      */
+       ffreg_t intr_status_reg;/* Interrupt Status register            */
+       ffreg_t mask_reg;       /* Mask Register                        */
+       ffreg_t cell_ctr_high1; /* Total cell transfer count (high)     */
+       ffreg_t cell_ctr_lo1;   /* Total cell transfer count (low)      */
+       ffreg_t state_reg;      /* Status register                      */
+       u_int   filler4c[0x58 - 0x4c];
+       ffreg_t curr_desc_num;  /* Contains the current descriptor num  */
+       ffreg_t next_desc;      /* Next descriptor                      */
+       ffreg_t next_vc;        /* Next VC                              */
+       u_int   filler5b[0x5d - 0x5b];
+       ffreg_t present_slot_cnt;/* Present slot count                  */
+       u_int   filler5e[0x6a - 0x5e];
+       ffreg_t new_desc_num;   /* New descriptor number                */
+       ffreg_t new_vc;         /* New VC                               */
+       ffreg_t sched_tbl_ptr;  /* Schedule table pointer               */
+       ffreg_t vbrwq_wptr;     /* VBR wait queue write pointer         */
+       ffreg_t vbrwq_rptr;     /* VBR wait queue read pointer          */
+       ffreg_t abrwq_wptr;     /* ABR wait queue write pointer         */
+       ffreg_t abrwq_rptr;     /* ABR wait queue read pointer          */
+       ffreg_t ubrwq_wptr;     /* UBR wait queue write pointer         */
+       ffreg_t ubrwq_rptr;     /* UBR wait queue read pointer          */
+       ffreg_t cbr_vc;         /* CBR VC                               */
+       ffreg_t vbr_sb_vc;      /* VBR SB VC                            */
+       ffreg_t abr_sb_vc;      /* ABR SB VC                            */
+       ffreg_t ubr_sb_vc;      /* UBR SB VC                            */
+       ffreg_t vbr_next_link;  /* VBR next link                        */
+       ffreg_t abr_next_link;  /* ABR next link                        */
+       ffreg_t ubr_next_link;  /* UBR next link                        */
+       u_int   filler7a[0x7c-0x7a];
+       ffreg_t out_rate_head;  /* Out of rate head                     */
+       u_int   filler7d[0xca-0x7d]; /* pad out to full address space   */
+       ffreg_t cell_ctr_high1_nc;/* Total cell transfer count (high)   */
+       ffreg_t cell_ctr_lo1_nc;/* Total cell transfer count (low)      */
+       u_int   fillercc[0x100-0xcc]; /* pad out to full address space   */
 } ffredn_t;
 
 typedef struct _rfredn_t {
index acc3a8d..9a6b05a 100644 (file)
@@ -433,8 +433,7 @@ static bool genpd_abort_poweroff(struct generic_pm_domain *genpd)
  */
 void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
 {
-       if (!work_pending(&genpd->power_off_work))
-               queue_work(pm_wq, &genpd->power_off_work);
+       queue_work(pm_wq, &genpd->power_off_work);
 }
 
 /**
index 50b2831..32ee0fc 100644 (file)
@@ -162,7 +162,7 @@ unsigned long opp_get_voltage(struct opp *opp)
 
        return v;
 }
-EXPORT_SYMBOL(opp_get_voltage);
+EXPORT_SYMBOL_GPL(opp_get_voltage);
 
 /**
  * opp_get_freq() - Gets the frequency corresponding to an available opp
@@ -192,7 +192,7 @@ unsigned long opp_get_freq(struct opp *opp)
 
        return f;
 }
-EXPORT_SYMBOL(opp_get_freq);
+EXPORT_SYMBOL_GPL(opp_get_freq);
 
 /**
  * opp_get_opp_count() - Get number of opps available in the opp list
@@ -225,7 +225,7 @@ int opp_get_opp_count(struct device *dev)
 
        return count;
 }
-EXPORT_SYMBOL(opp_get_opp_count);
+EXPORT_SYMBOL_GPL(opp_get_opp_count);
 
 /**
  * opp_find_freq_exact() - search for an exact frequency
@@ -276,7 +276,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq,
 
        return opp;
 }
-EXPORT_SYMBOL(opp_find_freq_exact);
+EXPORT_SYMBOL_GPL(opp_find_freq_exact);
 
 /**
  * opp_find_freq_ceil() - Search for an rounded ceil freq
@@ -323,7 +323,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)
 
        return opp;
 }
-EXPORT_SYMBOL(opp_find_freq_ceil);
+EXPORT_SYMBOL_GPL(opp_find_freq_ceil);
 
 /**
  * opp_find_freq_floor() - Search for a rounded floor freq
@@ -374,7 +374,7 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)
 
        return opp;
 }
-EXPORT_SYMBOL(opp_find_freq_floor);
+EXPORT_SYMBOL_GPL(opp_find_freq_floor);
 
 /**
  * opp_add()  - Add an OPP table from a table definitions
@@ -568,7 +568,7 @@ int opp_enable(struct device *dev, unsigned long freq)
 {
        return opp_set_availability(dev, freq, true);
 }
-EXPORT_SYMBOL(opp_enable);
+EXPORT_SYMBOL_GPL(opp_enable);
 
 /**
  * opp_disable() - Disable a specific OPP
@@ -590,7 +590,7 @@ int opp_disable(struct device *dev, unsigned long freq)
 {
        return opp_set_availability(dev, freq, false);
 }
-EXPORT_SYMBOL(opp_disable);
+EXPORT_SYMBOL_GPL(opp_disable);
 
 #ifdef CONFIG_CPU_FREQ
 /**
@@ -661,6 +661,7 @@ int opp_init_cpufreq_table(struct device *dev,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(opp_init_cpufreq_table);
 
 /**
  * opp_free_cpufreq_table() - free the cpufreq table
@@ -678,6 +679,7 @@ void opp_free_cpufreq_table(struct device *dev,
        kfree(*table);
        *table = NULL;
 }
+EXPORT_SYMBOL_GPL(opp_free_cpufreq_table);
 #endif         /* CONFIG_CPU_FREQ */
 
 /**
@@ -738,4 +740,5 @@ int of_init_opp_table(struct device *dev)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(of_init_opp_table);
 #endif
index e6ee5e8..79715e7 100644 (file)
@@ -382,6 +382,12 @@ static void wakeup_source_activate(struct wakeup_source *ws)
 {
        unsigned int cec;
 
+       /*
+        * active wakeup source should bring the system
+        * out of PM_SUSPEND_FREEZE state
+        */
+       freeze_wake();
+
        ws->active = true;
        ws->active_count++;
        ws->last_time = ktime_get();
index 19e3fbf..cb0c454 100644 (file)
@@ -94,11 +94,16 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
 #ifdef CONFIG_BCMA_DRIVER_GPIO
 /* driver_gpio.c */
 int bcma_gpio_init(struct bcma_drv_cc *cc);
+int bcma_gpio_unregister(struct bcma_drv_cc *cc);
 #else
 static inline int bcma_gpio_init(struct bcma_drv_cc *cc)
 {
        return -ENOTSUPP;
 }
+static inline int bcma_gpio_unregister(struct bcma_drv_cc *cc)
+{
+       return 0;
+}
 #endif /* CONFIG_BCMA_DRIVER_GPIO */
 
 #endif
index dbda91e..1f0b83e 100644 (file)
@@ -21,7 +21,7 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)
        struct bcma_bus *bus = cc->core->bus;
 
        if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
-           cc->core->id.rev != 0x38) {
+           cc->core->id.rev != 38) {
                bcma_err(bus, "NAND flash on unsupported board!\n");
                return -ENOTSUPP;
        }
index 9a6f585..71f755c 100644 (file)
@@ -96,3 +96,8 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
 
        return gpiochip_add(chip);
 }
+
+int bcma_gpio_unregister(struct bcma_drv_cc *cc)
+{
+       return gpiochip_remove(&cc->gpio);
+}
index 4a92f64..324f9de 100644 (file)
@@ -268,6 +268,13 @@ int bcma_bus_register(struct bcma_bus *bus)
 void bcma_bus_unregister(struct bcma_bus *bus)
 {
        struct bcma_device *cores[3];
+       int err;
+
+       err = bcma_gpio_unregister(&bus->drv_cc);
+       if (err == -EBUSY)
+               bcma_err(bus, "Some GPIOs are still in use.\n");
+       else if (err)
+               bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
 
        cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
        cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
index f58a4a4..2b8303a 100644 (file)
@@ -168,7 +168,7 @@ static void wake_all_senders(struct drbd_tconn *tconn) {
 }
 
 /* must hold resource->req_lock */
-static void start_new_tl_epoch(struct drbd_tconn *tconn)
+void start_new_tl_epoch(struct drbd_tconn *tconn)
 {
        /* no point closing an epoch, if it is empty, anyways. */
        if (tconn->current_tle_writes == 0)
index 016de6b..c08d229 100644 (file)
@@ -267,6 +267,7 @@ struct bio_and_error {
        int error;
 };
 
+extern void start_new_tl_epoch(struct drbd_tconn *tconn);
 extern void drbd_req_destroy(struct kref *kref);
 extern void _req_may_be_done(struct drbd_request *req,
                struct bio_and_error *m);
index 53bf618..0fe220c 100644 (file)
@@ -931,6 +931,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
        enum drbd_state_rv rv = SS_SUCCESS;
        enum sanitize_state_warnings ssw;
        struct after_state_chg_work *ascw;
+       bool did_remote, should_do_remote;
 
        os = drbd_read_state(mdev);
 
@@ -981,11 +982,17 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
            (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))
                atomic_inc(&mdev->local_cnt);
 
+       did_remote = drbd_should_do_remote(mdev->state);
        mdev->state.i = ns.i;
+       should_do_remote = drbd_should_do_remote(mdev->state);
        mdev->tconn->susp = ns.susp;
        mdev->tconn->susp_nod = ns.susp_nod;
        mdev->tconn->susp_fen = ns.susp_fen;
 
+       /* put replicated vs not-replicated requests in seperate epochs */
+       if (did_remote != should_do_remote)
+               start_new_tl_epoch(mdev->tconn);
+
        if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING)
                drbd_print_uuids(mdev, "attached to UUIDs");
 
index 9694dd9..3fd1009 100644 (file)
@@ -626,12 +626,13 @@ static void mtip_timeout_function(unsigned long int data)
                }
        }
 
-       if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+       if (cmdto_cnt) {
                print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
-
-               mtip_restart_port(port);
+               if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+                       mtip_restart_port(port);
+                       wake_up_interruptible(&port->svc_wait);
+               }
                clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
-               wake_up_interruptible(&port->svc_wait);
        }
 
        if (port->ic_pause_timer) {
@@ -3887,7 +3888,12 @@ static int mtip_block_remove(struct driver_data *dd)
         * Delete our gendisk structure. This also removes the device
         * from /dev
         */
-       del_gendisk(dd->disk);
+       if (dd->disk) {
+               if (dd->disk->queue)
+                       del_gendisk(dd->disk);
+               else
+                       put_disk(dd->disk);
+       }
 
        spin_lock(&rssd_index_lock);
        ida_remove(&rssd_index_ida, dd->index);
@@ -3921,7 +3927,13 @@ static int mtip_block_shutdown(struct driver_data *dd)
                "Shutting down %s ...\n", dd->disk->disk_name);
 
        /* Delete our gendisk structure, and cleanup the blk queue. */
-       del_gendisk(dd->disk);
+       if (dd->disk) {
+               if (dd->disk->queue)
+                       del_gendisk(dd->disk);
+               else
+                       put_disk(dd->disk);
+       }
+
 
        spin_lock(&rssd_index_lock);
        ida_remove(&rssd_index_ida, dd->index);
index 74374fb..5ac841f 100644 (file)
@@ -161,10 +161,12 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 static void make_response(struct xen_blkif *blkif, u64 id,
                          unsigned short op, int st);
 
-#define foreach_grant(pos, rbtree, node) \
-       for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node); \
+#define foreach_grant_safe(pos, n, rbtree, node) \
+       for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \
+            (n) = rb_next(&(pos)->node); \
             &(pos)->node != NULL; \
-            (pos) = container_of(rb_next(&(pos)->node), typeof(*(pos)), node))
+            (pos) = container_of(n, typeof(*(pos)), node), \
+            (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL)
 
 
 static void add_persistent_gnt(struct rb_root *root,
@@ -217,10 +219,11 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)
        struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        struct persistent_gnt *persistent_gnt;
+       struct rb_node *n;
        int ret = 0;
        int segs_to_unmap = 0;
 
-       foreach_grant(persistent_gnt, root, node) {
+       foreach_grant_safe(persistent_gnt, n, root, node) {
                BUG_ON(persistent_gnt->handle ==
                        BLKBACK_INVALID_HANDLE);
                gnttab_set_unmap_op(&unmap[segs_to_unmap],
@@ -230,9 +233,6 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)
                        persistent_gnt->handle);
 
                pages[segs_to_unmap] = persistent_gnt->page;
-               rb_erase(&persistent_gnt->node, root);
-               kfree(persistent_gnt);
-               num--;
 
                if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST ||
                        !rb_next(&persistent_gnt->node)) {
@@ -241,6 +241,10 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)
                        BUG_ON(ret);
                        segs_to_unmap = 0;
                }
+
+               rb_erase(&persistent_gnt->node, root);
+               kfree(persistent_gnt);
+               num--;
        }
        BUG_ON(num != 0);
 }
index 96e9b00..11043c1 100644 (file)
@@ -792,6 +792,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 {
        struct llist_node *all_gnts;
        struct grant *persistent_gnt;
+       struct llist_node *n;
 
        /* Prevent new requests being issued until we fix things up. */
        spin_lock_irq(&info->io_lock);
@@ -804,7 +805,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
        /* Remove all persistent grants */
        if (info->persistent_gnts_c) {
                all_gnts = llist_del_all(&info->persistent_gnts);
-               llist_for_each_entry(persistent_gnt, all_gnts, node) {
+               llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) {
                        gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
                        __free_page(pfn_to_page(persistent_gnt->pfn));
                        kfree(persistent_gnt);
@@ -835,7 +836,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
                             struct blkif_response *bret)
 {
-       int i;
+       int i = 0;
        struct bio_vec *bvec;
        struct req_iterator iter;
        unsigned long flags;
@@ -852,7 +853,8 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
                 */
                rq_for_each_segment(bvec, s->request, iter) {
                        BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE);
-                       i = offset >> PAGE_SHIFT;
+                       if (bvec->bv_offset < offset)
+                               i++;
                        BUG_ON(i >= s->req.u.rw.nr_segments);
                        shared_data = kmap_atomic(
                                pfn_to_page(s->grants_used[i]->pfn));
@@ -861,7 +863,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
                                bvec->bv_len);
                        bvec_kunmap_irq(bvec_data, &flags);
                        kunmap_atomic(shared_data);
-                       offset += bvec->bv_len;
+                       offset = bvec->bv_offset + bvec->bv_len;
                }
        }
        /* Add the persistent grant into the list of free grants */
index fe6d4be..e3f9a99 100644 (file)
@@ -1041,7 +1041,7 @@ static int hpet_acpi_add(struct acpi_device *device)
        return hpet_alloc(&data);
 }
 
-static int hpet_acpi_remove(struct acpi_device *device, int type)
+static int hpet_acpi_remove(struct acpi_device *device)
 {
        /* XXX need to unregister clocksource, dealloc mem, etc */
        return -EINVAL;
index d780295..6386a98 100644 (file)
@@ -1142,7 +1142,7 @@ static int sonypi_acpi_add(struct acpi_device *device)
        return 0;
 }
 
-static int sonypi_acpi_remove(struct acpi_device *device, int type)
+static int sonypi_acpi_remove(struct acpi_device *device)
 {
        sonypi_acpi_device = NULL;
        return 0;
index 684b0d5..ee4dbea 100644 (file)
@@ -2062,7 +2062,8 @@ static void virtcons_remove(struct virtio_device *vdev)
        /* Disable interrupts for vqs */
        vdev->config->reset(vdev);
        /* Finish up work that's lined up */
-       cancel_work_sync(&portdev->control_work);
+       if (use_multiport(portdev))
+               cancel_work_sync(&portdev->control_work);
 
        list_for_each_entry_safe(port, port2, &portdev->ports, list)
                unplug_port(port);
index ee90e87..ee11460 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_ARCH_U8500)      += ux500/
 obj-$(CONFIG_ARCH_VT8500)      += clk-vt8500.o
 obj-$(CONFIG_ARCH_SUNXI)       += clk-sunxi.o
 obj-$(CONFIG_ARCH_ZYNQ)                += clk-zynq.o
+obj-$(CONFIG_X86)              += x86/
 
 # Chip specific
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
index 52fecad..3a0b723 100644 (file)
@@ -182,8 +182,10 @@ static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate,
                reg |= HB_PLL_EXT_ENA;
                reg &= ~HB_PLL_EXT_BYPASS;
        } else {
+               writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
                reg &= ~HB_PLL_DIVQ_MASK;
                reg |= divq << HB_PLL_DIVQ_SHIFT;
+               writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
        }
        writel(reg, hbclk->reg);
 
index 8fa5408..ebf141d 100644 (file)
@@ -193,6 +193,7 @@ static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
        { "runit", NULL, 7 },
        { "xor0", NULL, 8 },
        { "audio", NULL, 9 },
+       { "powersave", "cpuclk", 11 },
        { "sata0", NULL, 14 },
        { "sata1", NULL, 15 },
        { "xor1", NULL, 16 },
diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile
new file mode 100644 (file)
index 0000000..f9ba4fa
--- /dev/null
@@ -0,0 +1,2 @@
+clk-x86-lpss-objs              := clk-lpss.o clk-lpt.o
+obj-$(CONFIG_X86_INTEL_LPSS)   += clk-x86-lpss.o
diff --git a/drivers/clk/x86/clk-lpss.c b/drivers/clk/x86/clk-lpss.c
new file mode 100644 (file)
index 0000000..b5e229f
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Intel Low Power Subsystem clocks.
+ *
+ * Copyright (C) 2013, Intel Corporation
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *         Heikki Krogerus <heikki.krogerus@linux.intel.com>
+ *
+ * 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.
+ */
+
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+static int clk_lpss_is_mmio_resource(struct acpi_resource *res, void *data)
+{
+       struct resource r;
+       return !acpi_dev_resource_memory(res, &r);
+}
+
+static acpi_status clk_lpss_find_mmio(acpi_handle handle, u32 level,
+                                     void *data, void **retval)
+{
+       struct resource_list_entry *rentry;
+       struct list_head resource_list;
+       struct acpi_device *adev;
+       const char *uid = data;
+       int ret;
+
+       if (acpi_bus_get_device(handle, &adev))
+               return AE_OK;
+
+       if (uid) {
+               if (!adev->pnp.unique_id)
+                       return AE_OK;
+               if (strcmp(uid, adev->pnp.unique_id))
+                       return AE_OK;
+       }
+
+       INIT_LIST_HEAD(&resource_list);
+       ret = acpi_dev_get_resources(adev, &resource_list,
+                                    clk_lpss_is_mmio_resource, NULL);
+       if (ret < 0)
+               return AE_NO_MEMORY;
+
+       list_for_each_entry(rentry, &resource_list, node)
+               if (resource_type(&rentry->res) == IORESOURCE_MEM) {
+                       *(struct resource *)retval = rentry->res;
+                       break;
+               }
+
+       acpi_dev_free_resource_list(&resource_list);
+       return AE_OK;
+}
+
+/**
+ * clk_register_lpss_gate - register LPSS clock gate
+ * @name: name of this clock gate
+ * @parent_name: parent clock name
+ * @hid: ACPI _HID of the device
+ * @uid: ACPI _UID of the device (optional)
+ * @offset: LPSS PRV_CLOCK_PARAMS offset
+ *
+ * Creates and registers LPSS clock gate.
+ */
+struct clk *clk_register_lpss_gate(const char *name, const char *parent_name,
+                                  const char *hid, const char *uid,
+                                  unsigned offset)
+{
+       struct resource res = { };
+       void __iomem *mmio_base;
+       acpi_status status;
+       struct clk *clk;
+
+       /*
+        * First try to look the device and its mmio resource from the
+        * ACPI namespace.
+        */
+       status = acpi_get_devices(hid, clk_lpss_find_mmio, (void *)uid,
+                                 (void **)&res);
+       if (ACPI_FAILURE(status) || !res.start)
+               return ERR_PTR(-ENODEV);
+
+       mmio_base = ioremap(res.start, resource_size(&res));
+       if (!mmio_base)
+               return ERR_PTR(-ENOMEM);
+
+       clk = clk_register_gate(NULL, name, parent_name, 0, mmio_base + offset,
+                               0, 0, NULL);
+       if (IS_ERR(clk))
+               iounmap(mmio_base);
+
+       return clk;
+}
diff --git a/drivers/clk/x86/clk-lpss.h b/drivers/clk/x86/clk-lpss.h
new file mode 100644 (file)
index 0000000..e9460f4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Intel Low Power Subsystem clock.
+ *
+ * Copyright (C) 2013, Intel Corporation
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *         Heikki Krogerus <heikki.krogerus@linux.intel.com>
+ *
+ * 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 __CLK_LPSS_H
+#define __CLK_LPSS_H
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+
+#ifdef CONFIG_ACPI
+extern struct clk *clk_register_lpss_gate(const char *name,
+                                         const char *parent_name,
+                                         const char *hid, const char *uid,
+                                         unsigned offset);
+#else
+static inline struct clk *clk_register_lpss_gate(const char *name,
+                                                const char *parent_name,
+                                                const char *hid,
+                                                const char *uid,
+                                                unsigned offset)
+{
+       return ERR_PTR(-ENODEV);
+}
+#endif
+
+#endif /* __CLK_LPSS_H */
diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c
new file mode 100644 (file)
index 0000000..81298ae
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Intel Lynxpoint LPSS clocks.
+ *
+ * Copyright (C) 2013, Intel Corporation
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *         Heikki Krogerus <heikki.krogerus@linux.intel.com>
+ *
+ * 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.
+ */
+
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "clk-lpss.h"
+
+#define PRV_CLOCK_PARAMS 0x800
+
+static int lpt_clk_probe(struct platform_device *pdev)
+{
+       struct clk *clk;
+
+       /* LPSS free running clock */
+       clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT,
+                                     100000000);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       /* Shared DMA clock */
+       clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto");
+
+       /* SPI clocks */
+       clk = clk_register_lpss_gate("spi0_clk", "lpss_clk", "INT33C0", NULL,
+                                    PRV_CLOCK_PARAMS);
+       if (!IS_ERR(clk))
+               clk_register_clkdev(clk, NULL, "INT33C0:00");
+
+       clk = clk_register_lpss_gate("spi1_clk", "lpss_clk", "INT33C1", NULL,
+                                    PRV_CLOCK_PARAMS);
+       if (!IS_ERR(clk))
+               clk_register_clkdev(clk, NULL, "INT33C1:00");
+
+       /* I2C clocks */
+       clk = clk_register_lpss_gate("i2c0_clk", "lpss_clk", "INT33C2", NULL,
+                                    PRV_CLOCK_PARAMS);
+       if (!IS_ERR(clk))
+               clk_register_clkdev(clk, NULL, "INT33C2:00");
+
+       clk = clk_register_lpss_gate("i2c1_clk", "lpss_clk", "INT33C3", NULL,
+                                    PRV_CLOCK_PARAMS);
+       if (!IS_ERR(clk))
+               clk_register_clkdev(clk, NULL, "INT33C3:00");
+
+       /* UART clocks */
+       clk = clk_register_lpss_gate("uart0_clk", "lpss_clk", "INT33C4", NULL,
+                                    PRV_CLOCK_PARAMS);
+       if (!IS_ERR(clk))
+               clk_register_clkdev(clk, NULL, "INT33C4:00");
+
+       clk = clk_register_lpss_gate("uart1_clk", "lpss_clk", "INT33C5", NULL,
+                                    PRV_CLOCK_PARAMS);
+       if (!IS_ERR(clk))
+               clk_register_clkdev(clk, NULL, "INT33C5:00");
+
+       return 0;
+}
+
+static struct platform_driver lpt_clk_driver = {
+       .driver = {
+               .name = "clk-lpt",
+               .owner = THIS_MODULE,
+       },
+       .probe = lpt_clk_probe,
+};
+
+static int __init lpt_clk_init(void)
+{
+       return platform_driver_register(&lpt_clk_driver);
+}
+arch_initcall(lpt_clk_init);
index e0a899f..cbcb21e 100644 (file)
@@ -185,7 +185,7 @@ config CPU_FREQ_GOV_CONSERVATIVE
          If in doubt, say N.
 
 config GENERIC_CPUFREQ_CPU0
-       bool "Generic CPU0 cpufreq driver"
+       tristate "Generic CPU0 cpufreq driver"
        depends on HAVE_CLK && REGULATOR && PM_OPP && OF
        select CPU_FREQ_TABLE
        help
index a0b3661..7f333af 100644 (file)
@@ -77,9 +77,39 @@ config ARM_EXYNOS5250_CPUFREQ
          This adds the CPUFreq driver for Samsung EXYNOS5250
          SoC.
 
+config ARM_KIRKWOOD_CPUFREQ
+       def_bool ARCH_KIRKWOOD && OF
+       help
+         This adds the CPUFreq driver for Marvell Kirkwood
+         SoCs.
+
+config ARM_IMX6Q_CPUFREQ
+       tristate "Freescale i.MX6Q cpufreq support"
+       depends on SOC_IMX6Q
+       depends on REGULATOR_ANATOP
+       help
+         This adds cpufreq driver support for Freescale i.MX6Q SOC.
+
+         If in doubt, say N.
+
 config ARM_SPEAR_CPUFREQ
        bool "SPEAr CPUFreq support"
        depends on PLAT_SPEAR
        default y
        help
          This adds the CPUFreq driver support for SPEAr SOCs.
+
+config ARM_HIGHBANK_CPUFREQ
+       tristate "Calxeda Highbank-based"
+       depends on ARCH_HIGHBANK
+       select CPU_FREQ_TABLE
+       select GENERIC_CPUFREQ_CPU0
+       select PM_OPP
+       select REGULATOR
+
+       default m
+       help
+         This adds the CPUFreq driver for Calxeda Highbank SoC
+         based boards.
+
+         If in doubt, say N.
index 7227cd7..98e5abb 100644 (file)
@@ -2,6 +2,19 @@
 # x86 CPU Frequency scaling drivers
 #
 
+config X86_INTEL_PSTATE
+       bool "Intel P state control"
+       depends on X86
+       help
+          This driver provides a P state for Intel core processors.
+         The driver implements an internal governor and will become
+          the scaling driver and governor for Sandy bridge processors.
+
+         When this driver is enabled it will become the perferred
+          scaling driver for Sandy bridge processors.
+
+         If in doubt, say N.
+
 config X86_PCC_CPUFREQ
        tristate "Processor Clocking Control interface driver"
        depends on ACPI && ACPI_PROCESSOR
index fadc4d4..5399c45 100644 (file)
@@ -19,11 +19,12 @@ obj-$(CONFIG_GENERIC_CPUFREQ_CPU0)  += cpufreq-cpu0.o
 ##################################################################################
 # x86 drivers.
 # Link order matters. K8 is preferred to ACPI because of firmware bugs in early
-# K8 systems. ACPI is preferred to all other hardware-specific drivers.
+# K8 systems. This is still the case but acpi-cpufreq errors out so that
+# powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers.
 # speedstep-* is preferred over p4-clockmod.
 
-obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o
 obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o mperf.o
+obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o
 obj-$(CONFIG_X86_PCC_CPUFREQ)          += pcc-cpufreq.o
 obj-$(CONFIG_X86_POWERNOW_K6)          += powernow-k6.o
 obj-$(CONFIG_X86_POWERNOW_K7)          += powernow-k7.o
@@ -39,6 +40,7 @@ obj-$(CONFIG_X86_SPEEDSTEP_SMI)               += speedstep-smi.o
 obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)   += speedstep-centrino.o
 obj-$(CONFIG_X86_P4_CLOCKMOD)          += p4-clockmod.o
 obj-$(CONFIG_X86_CPUFREQ_NFORCE2)      += cpufreq-nforce2.o
+obj-$(CONFIG_X86_INTEL_PSTATE)         += intel_pstate.o
 
 ##################################################################################
 # ARM SoC drivers
@@ -50,8 +52,11 @@ obj-$(CONFIG_ARM_EXYNOS_CPUFREQ)     += exynos-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ)   += exynos4210-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ)   += exynos4x12-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ)   += exynos5250-cpufreq.o
-obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)     += omap-cpufreq.o
+obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)     += kirkwood-cpufreq.o
+obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)    += omap-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)                += spear-cpufreq.o
+obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)     += highbank-cpufreq.o
+obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)                += imx6q-cpufreq.o
 
 ##################################################################################
 # PowerPC platform drivers
index 7b0d49d..937bc28 100644 (file)
@@ -734,7 +734,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
 #ifdef CONFIG_SMP
        dmi_check_system(sw_any_bug_dmi_table);
-       if (bios_with_sw_any_bug && cpumask_weight(policy->cpus) == 1) {
+       if (bios_with_sw_any_bug && !policy_is_shared(policy)) {
                policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
                cpumask_copy(policy->cpus, cpu_core_mask(cpu));
        }
@@ -762,6 +762,12 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
        switch (perf->control_register.space_id) {
        case ACPI_ADR_SPACE_SYSTEM_IO:
+               if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+                   boot_cpu_data.x86 == 0xf) {
+                       pr_debug("AMD K8 systems must use native drivers.\n");
+                       result = -ENODEV;
+                       goto err_unreg;
+               }
                pr_debug("SYSTEM IO addr space\n");
                data->cpu_feature = SYSTEM_IO_CAPABLE;
                break;
index debc5a7..4e5b7fb 100644 (file)
 #define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
 
 #include <linux/clk.h>
-#include <linux/cpu.h>
 #include <linux/cpufreq.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/opp.h>
+#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
@@ -146,7 +146,6 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
         * share the clock and voltage and clock.  Use cpufreq affected_cpus
         * interface to have all CPUs scaled together.
         */
-       policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
        cpumask_setall(policy->cpus);
 
        cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
@@ -177,34 +176,32 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
        .attr = cpu0_cpufreq_attr,
 };
 
-static int cpu0_cpufreq_driver_init(void)
+static int cpu0_cpufreq_probe(struct platform_device *pdev)
 {
        struct device_node *np;
        int ret;
 
-       np = of_find_node_by_path("/cpus/cpu@0");
+       for_each_child_of_node(of_find_node_by_path("/cpus"), np) {
+               if (of_get_property(np, "operating-points", NULL))
+                       break;
+       }
+
        if (!np) {
                pr_err("failed to find cpu0 node\n");
                return -ENOENT;
        }
 
-       cpu_dev = get_cpu_device(0);
-       if (!cpu_dev) {
-               pr_err("failed to get cpu0 device\n");
-               ret = -ENODEV;
-               goto out_put_node;
-       }
-
+       cpu_dev = &pdev->dev;
        cpu_dev->of_node = np;
 
-       cpu_clk = clk_get(cpu_dev, NULL);
+       cpu_clk = devm_clk_get(cpu_dev, NULL);
        if (IS_ERR(cpu_clk)) {
                ret = PTR_ERR(cpu_clk);
                pr_err("failed to get cpu0 clock: %d\n", ret);
                goto out_put_node;
        }
 
-       cpu_reg = regulator_get(cpu_dev, "cpu0");
+       cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
        if (IS_ERR(cpu_reg)) {
                pr_warn("failed to get cpu0 regulator\n");
                cpu_reg = NULL;
@@ -267,7 +264,24 @@ out_put_node:
        of_node_put(np);
        return ret;
 }
-late_initcall(cpu0_cpufreq_driver_init);
+
+static int cpu0_cpufreq_remove(struct platform_device *pdev)
+{
+       cpufreq_unregister_driver(&cpu0_cpufreq_driver);
+       opp_free_cpufreq_table(cpu_dev, &freq_table);
+
+       return 0;
+}
+
+static struct platform_driver cpu0_cpufreq_platdrv = {
+       .driver = {
+               .name   = "cpufreq-cpu0",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = cpu0_cpufreq_probe,
+       .remove         = cpu0_cpufreq_remove,
+};
+module_platform_driver(cpu0_cpufreq_platdrv);
 
 MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
 MODULE_DESCRIPTION("Generic CPU0 cpufreq driver");
index 1f93dbd..b02824d 100644 (file)
@@ -59,8 +59,6 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock);
  *   mode before doing so.
  *
  * Additional rules:
- * - All holders of the lock should check to make sure that the CPU they
- *   are concerned with are online after they get the lock.
  * - Governor routines that can be called in cpufreq hotplug path should not
  *   take this sem as top level hotplug notifier handler takes this.
  * - Lock should not be held across
@@ -70,38 +68,28 @@ static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
 static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
 
 #define lock_policy_rwsem(mode, cpu)                                   \
-static int lock_policy_rwsem_##mode                                    \
-(int cpu)                                                              \
+static int lock_policy_rwsem_##mode(int cpu)                           \
 {                                                                      \
        int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);              \
        BUG_ON(policy_cpu == -1);                                       \
        down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu));            \
-       if (unlikely(!cpu_online(cpu))) {                               \
-               up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu));      \
-               return -1;                                              \
-       }                                                               \
                                                                        \
        return 0;                                                       \
 }
 
 lock_policy_rwsem(read, cpu);
-
 lock_policy_rwsem(write, cpu);
 
-static void unlock_policy_rwsem_read(int cpu)
-{
-       int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
-       BUG_ON(policy_cpu == -1);
-       up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
-}
-
-static void unlock_policy_rwsem_write(int cpu)
-{
-       int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
-       BUG_ON(policy_cpu == -1);
-       up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
+#define unlock_policy_rwsem(mode, cpu)                                 \
+static void unlock_policy_rwsem_##mode(int cpu)                                \
+{                                                                      \
+       int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);              \
+       BUG_ON(policy_cpu == -1);                                       \
+       up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu));              \
 }
 
+unlock_policy_rwsem(read, cpu);
+unlock_policy_rwsem(write, cpu);
 
 /* internal prototypes */
 static int __cpufreq_governor(struct cpufreq_policy *policy,
@@ -180,6 +168,9 @@ err_out:
 
 struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
 {
+       if (cpufreq_disabled())
+               return NULL;
+
        return __cpufreq_cpu_get(cpu, false);
 }
 EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
@@ -198,6 +189,9 @@ static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
 
 void cpufreq_cpu_put(struct cpufreq_policy *data)
 {
+       if (cpufreq_disabled())
+               return;
+
        __cpufreq_cpu_put(data, false);
 }
 EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
@@ -261,14 +255,21 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
 void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
 {
        struct cpufreq_policy *policy;
+       unsigned long flags;
 
        BUG_ON(irqs_disabled());
 
+       if (cpufreq_disabled())
+               return;
+
        freqs->flags = cpufreq_driver->flags;
        pr_debug("notification %u of frequency transition to %u kHz\n",
                state, freqs->new);
 
+       spin_lock_irqsave(&cpufreq_driver_lock, flags);
        policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
+       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
        switch (state) {
 
        case CPUFREQ_PRECHANGE:
@@ -294,7 +295,6 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
                adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
                pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
                        (unsigned long)freqs->cpu);
-               trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
                trace_cpu_frequency(freqs->new, freqs->cpu);
                srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
                                CPUFREQ_POSTCHANGE, freqs);
@@ -543,8 +543,6 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf)
  */
 static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
 {
-       if (cpumask_empty(policy->related_cpus))
-               return show_cpus(policy->cpus, buf);
        return show_cpus(policy->related_cpus, buf);
 }
 
@@ -700,87 +698,6 @@ static struct kobj_type ktype_cpufreq = {
        .release        = cpufreq_sysfs_release,
 };
 
-/*
- * Returns:
- *   Negative: Failure
- *   0:        Success
- *   Positive: When we have a managed CPU and the sysfs got symlinked
- */
-static int cpufreq_add_dev_policy(unsigned int cpu,
-                                 struct cpufreq_policy *policy,
-                                 struct device *dev)
-{
-       int ret = 0;
-#ifdef CONFIG_SMP
-       unsigned long flags;
-       unsigned int j;
-#ifdef CONFIG_HOTPLUG_CPU
-       struct cpufreq_governor *gov;
-
-       gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
-       if (gov) {
-               policy->governor = gov;
-               pr_debug("Restoring governor %s for cpu %d\n",
-                      policy->governor->name, cpu);
-       }
-#endif
-
-       for_each_cpu(j, policy->cpus) {
-               struct cpufreq_policy *managed_policy;
-
-               if (cpu == j)
-                       continue;
-
-               /* Check for existing affected CPUs.
-                * They may not be aware of it due to CPU Hotplug.
-                * cpufreq_cpu_put is called when the device is removed
-                * in __cpufreq_remove_dev()
-                */
-               managed_policy = cpufreq_cpu_get(j);
-               if (unlikely(managed_policy)) {
-
-                       /* Set proper policy_cpu */
-                       unlock_policy_rwsem_write(cpu);
-                       per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
-
-                       if (lock_policy_rwsem_write(cpu) < 0) {
-                               /* Should not go through policy unlock path */
-                               if (cpufreq_driver->exit)
-                                       cpufreq_driver->exit(policy);
-                               cpufreq_cpu_put(managed_policy);
-                               return -EBUSY;
-                       }
-
-                       spin_lock_irqsave(&cpufreq_driver_lock, flags);
-                       cpumask_copy(managed_policy->cpus, policy->cpus);
-                       per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
-                       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
-                       pr_debug("CPU already managed, adding link\n");
-                       ret = sysfs_create_link(&dev->kobj,
-                                               &managed_policy->kobj,
-                                               "cpufreq");
-                       if (ret)
-                               cpufreq_cpu_put(managed_policy);
-                       /*
-                        * Success. We only needed to be added to the mask.
-                        * Call driver->exit() because only the cpu parent of
-                        * the kobj needed to call init().
-                        */
-                       if (cpufreq_driver->exit)
-                               cpufreq_driver->exit(policy);
-
-                       if (!ret)
-                               return 1;
-                       else
-                               return ret;
-               }
-       }
-#endif
-       return ret;
-}
-
-
 /* symlink affected CPUs */
 static int cpufreq_add_dev_symlink(unsigned int cpu,
                                   struct cpufreq_policy *policy)
@@ -794,8 +711,6 @@ static int cpufreq_add_dev_symlink(unsigned int cpu,
 
                if (j == cpu)
                        continue;
-               if (!cpu_online(j))
-                       continue;
 
                pr_debug("CPU %u already managed, adding link\n", j);
                managed_policy = cpufreq_cpu_get(cpu);
@@ -852,8 +767,6 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
 
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
        for_each_cpu(j, policy->cpus) {
-               if (!cpu_online(j))
-                       continue;
                per_cpu(cpufreq_cpu_data, j) = policy;
                per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
        }
@@ -885,6 +798,42 @@ err_out_kobj_put:
        return ret;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
+                                 struct device *dev)
+{
+       struct cpufreq_policy *policy;
+       int ret = 0;
+       unsigned long flags;
+
+       policy = cpufreq_cpu_get(sibling);
+       WARN_ON(!policy);
+
+       __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+
+       lock_policy_rwsem_write(sibling);
+
+       spin_lock_irqsave(&cpufreq_driver_lock, flags);
+
+       cpumask_set_cpu(cpu, policy->cpus);
+       per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
+       per_cpu(cpufreq_cpu_data, cpu) = policy;
+       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+       unlock_policy_rwsem_write(sibling);
+
+       __cpufreq_governor(policy, CPUFREQ_GOV_START);
+       __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
+
+       ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
+       if (ret) {
+               cpufreq_cpu_put(policy);
+               return ret;
+       }
+
+       return 0;
+}
+#endif
 
 /**
  * cpufreq_add_dev - add a CPU device
@@ -897,12 +846,12 @@ err_out_kobj_put:
  */
 static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
 {
-       unsigned int cpu = dev->id;
-       int ret = 0, found = 0;
+       unsigned int j, cpu = dev->id;
+       int ret = -ENOMEM;
        struct cpufreq_policy *policy;
        unsigned long flags;
-       unsigned int j;
 #ifdef CONFIG_HOTPLUG_CPU
+       struct cpufreq_governor *gov;
        int sibling;
 #endif
 
@@ -919,6 +868,19 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
                cpufreq_cpu_put(policy);
                return 0;
        }
+
+#ifdef CONFIG_HOTPLUG_CPU
+       /* Check if this cpu was hot-unplugged earlier and has siblings */
+       spin_lock_irqsave(&cpufreq_driver_lock, flags);
+       for_each_online_cpu(sibling) {
+               struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
+               if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
+                       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+                       return cpufreq_add_policy_cpu(cpu, sibling, dev);
+               }
+       }
+       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+#endif
 #endif
 
        if (!try_module_get(cpufreq_driver->owner)) {
@@ -926,7 +888,6 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
                goto module_out;
        }
 
-       ret = -ENOMEM;
        policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
        if (!policy)
                goto nomem_out;
@@ -938,66 +899,58 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
                goto err_free_cpumask;
 
        policy->cpu = cpu;
+       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        cpumask_copy(policy->cpus, cpumask_of(cpu));
 
        /* Initially set CPU itself as the policy_cpu */
        per_cpu(cpufreq_policy_cpu, cpu) = cpu;
-       ret = (lock_policy_rwsem_write(cpu) < 0);
-       WARN_ON(ret);
 
        init_completion(&policy->kobj_unregister);
        INIT_WORK(&policy->update, handle_update);
 
-       /* Set governor before ->init, so that driver could check it */
-#ifdef CONFIG_HOTPLUG_CPU
-       for_each_online_cpu(sibling) {
-               struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
-               if (cp && cp->governor &&
-                   (cpumask_test_cpu(cpu, cp->related_cpus))) {
-                       policy->governor = cp->governor;
-                       found = 1;
-                       break;
-               }
-       }
-#endif
-       if (!found)
-               policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        /* call driver. From then on the cpufreq must be able
         * to accept all calls to ->verify and ->setpolicy for this CPU
         */
        ret = cpufreq_driver->init(policy);
        if (ret) {
                pr_debug("initialization failed\n");
-               goto err_unlock_policy;
+               goto err_set_policy_cpu;
        }
+
+       /* related cpus should atleast have policy->cpus */
+       cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
+
+       /*
+        * affected cpus must always be the one, which are online. We aren't
+        * managing offline cpus here.
+        */
+       cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
+
        policy->user_policy.min = policy->min;
        policy->user_policy.max = policy->max;
 
        blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
                                     CPUFREQ_START, policy);
 
-       ret = cpufreq_add_dev_policy(cpu, policy, dev);
-       if (ret) {
-               if (ret > 0)
-                       /* This is a managed cpu, symlink created,
-                          exit with 0 */
-                       ret = 0;
-               goto err_unlock_policy;
+#ifdef CONFIG_HOTPLUG_CPU
+       gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
+       if (gov) {
+               policy->governor = gov;
+               pr_debug("Restoring governor %s for cpu %d\n",
+                      policy->governor->name, cpu);
        }
+#endif
 
        ret = cpufreq_add_dev_interface(cpu, policy, dev);
        if (ret)
                goto err_out_unregister;
 
-       unlock_policy_rwsem_write(cpu);
-
        kobject_uevent(&policy->kobj, KOBJ_ADD);
        module_put(cpufreq_driver->owner);
        pr_debug("initialization complete\n");
 
        return 0;
 
-
 err_out_unregister:
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
        for_each_cpu(j, policy->cpus)
@@ -1007,8 +960,8 @@ err_out_unregister:
        kobject_put(&policy->kobj);
        wait_for_completion(&policy->kobj_unregister);
 
-err_unlock_policy:
-       unlock_policy_rwsem_write(cpu);
+err_set_policy_cpu:
+       per_cpu(cpufreq_policy_cpu, cpu) = -1;
        free_cpumask_var(policy->related_cpus);
 err_free_cpumask:
        free_cpumask_var(policy->cpus);
@@ -1020,6 +973,22 @@ module_out:
        return ret;
 }
 
+static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
+{
+       int j;
+
+       policy->last_cpu = policy->cpu;
+       policy->cpu = cpu;
+
+       for_each_cpu(j, policy->cpus)
+               per_cpu(cpufreq_policy_cpu, j) = cpu;
+
+#ifdef CONFIG_CPU_FREQ_TABLE
+       cpufreq_frequency_table_update_policy_cpu(policy);
+#endif
+       blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
+                       CPUFREQ_UPDATE_POLICY_CPU, policy);
+}
 
 /**
  * __cpufreq_remove_dev - remove a CPU device
@@ -1030,129 +999,103 @@ module_out:
  */
 static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
 {
-       unsigned int cpu = dev->id;
+       unsigned int cpu = dev->id, ret, cpus;
        unsigned long flags;
        struct cpufreq_policy *data;
        struct kobject *kobj;
        struct completion *cmp;
-#ifdef CONFIG_SMP
        struct device *cpu_dev;
-       unsigned int j;
-#endif
 
-       pr_debug("unregistering CPU %u\n", cpu);
+       pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
 
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
+
        data = per_cpu(cpufreq_cpu_data, cpu);
+       per_cpu(cpufreq_cpu_data, cpu) = NULL;
+
+       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
        if (!data) {
-               spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-               unlock_policy_rwsem_write(cpu);
+               pr_debug("%s: No cpu_data found\n", __func__);
                return -EINVAL;
        }
-       per_cpu(cpufreq_cpu_data, cpu) = NULL;
 
+       if (cpufreq_driver->target)
+               __cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
-#ifdef CONFIG_SMP
-       /* if this isn't the CPU which is the parent of the kobj, we
-        * only need to unlink, put and exit
-        */
-       if (unlikely(cpu != data->cpu)) {
-               pr_debug("removing link\n");
-               cpumask_clear_cpu(cpu, data->cpus);
-               spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-               kobj = &dev->kobj;
-               cpufreq_cpu_put(data);
-               unlock_policy_rwsem_write(cpu);
-               sysfs_remove_link(kobj, "cpufreq");
-               return 0;
-       }
+#ifdef CONFIG_HOTPLUG_CPU
+       if (!cpufreq_driver->setpolicy)
+               strncpy(per_cpu(cpufreq_cpu_governor, cpu),
+                       data->governor->name, CPUFREQ_NAME_LEN);
 #endif
 
-#ifdef CONFIG_SMP
+       WARN_ON(lock_policy_rwsem_write(cpu));
+       cpus = cpumask_weight(data->cpus);
+       cpumask_clear_cpu(cpu, data->cpus);
+       unlock_policy_rwsem_write(cpu);
 
-#ifdef CONFIG_HOTPLUG_CPU
-       strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
-                       CPUFREQ_NAME_LEN);
-#endif
+       if (cpu != data->cpu) {
+               sysfs_remove_link(&dev->kobj, "cpufreq");
+       } else if (cpus > 1) {
+               /* first sibling now owns the new sysfs dir */
+               cpu_dev = get_cpu_device(cpumask_first(data->cpus));
+               sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
+               ret = kobject_move(&data->kobj, &cpu_dev->kobj);
+               if (ret) {
+                       pr_err("%s: Failed to move kobj: %d", __func__, ret);
 
-       /* if we have other CPUs still registered, we need to unlink them,
-        * or else wait_for_completion below will lock up. Clean the
-        * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
-        * the sysfs links afterwards.
-        */
-       if (unlikely(cpumask_weight(data->cpus) > 1)) {
-               for_each_cpu(j, data->cpus) {
-                       if (j == cpu)
-                               continue;
-                       per_cpu(cpufreq_cpu_data, j) = NULL;
-               }
-       }
+                       WARN_ON(lock_policy_rwsem_write(cpu));
+                       cpumask_set_cpu(cpu, data->cpus);
 
-       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+                       spin_lock_irqsave(&cpufreq_driver_lock, flags);
+                       per_cpu(cpufreq_cpu_data, cpu) = data;
+                       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       if (unlikely(cpumask_weight(data->cpus) > 1)) {
-               for_each_cpu(j, data->cpus) {
-                       if (j == cpu)
-                               continue;
-                       pr_debug("removing link for cpu %u\n", j);
-#ifdef CONFIG_HOTPLUG_CPU
-                       strncpy(per_cpu(cpufreq_cpu_governor, j),
-                               data->governor->name, CPUFREQ_NAME_LEN);
-#endif
-                       cpu_dev = get_cpu_device(j);
-                       kobj = &cpu_dev->kobj;
                        unlock_policy_rwsem_write(cpu);
-                       sysfs_remove_link(kobj, "cpufreq");
-                       lock_policy_rwsem_write(cpu);
-                       cpufreq_cpu_put(data);
-               }
-       }
-#else
-       spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-#endif
 
-       if (cpufreq_driver->target)
-               __cpufreq_governor(data, CPUFREQ_GOV_STOP);
+                       ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
+                                       "cpufreq");
+                       return -EINVAL;
+               }
 
-       kobj = &data->kobj;
-       cmp = &data->kobj_unregister;
-       unlock_policy_rwsem_write(cpu);
-       kobject_put(kobj);
+               WARN_ON(lock_policy_rwsem_write(cpu));
+               update_policy_cpu(data, cpu_dev->id);
+               unlock_policy_rwsem_write(cpu);
+               pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
+                               __func__, cpu_dev->id, cpu);
+       }
 
-       /* we need to make sure that the underlying kobj is actually
-        * not referenced anymore by anybody before we proceed with
-        * unloading.
-        */
-       pr_debug("waiting for dropping of refcount\n");
-       wait_for_completion(cmp);
-       pr_debug("wait complete\n");
+       pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
+       cpufreq_cpu_put(data);
 
-       lock_policy_rwsem_write(cpu);
-       if (cpufreq_driver->exit)
-               cpufreq_driver->exit(data);
-       unlock_policy_rwsem_write(cpu);
+       /* If cpu is last user of policy, free policy */
+       if (cpus == 1) {
+               lock_policy_rwsem_read(cpu);
+               kobj = &data->kobj;
+               cmp = &data->kobj_unregister;
+               unlock_policy_rwsem_read(cpu);
+               kobject_put(kobj);
+
+               /* we need to make sure that the underlying kobj is actually
+                * not referenced anymore by anybody before we proceed with
+                * unloading.
+                */
+               pr_debug("waiting for dropping of refcount\n");
+               wait_for_completion(cmp);
+               pr_debug("wait complete\n");
 
-#ifdef CONFIG_HOTPLUG_CPU
-       /* when the CPU which is the parent of the kobj is hotplugged
-        * offline, check for siblings, and create cpufreq sysfs interface
-        * and symlinks
-        */
-       if (unlikely(cpumask_weight(data->cpus) > 1)) {
-               /* first sibling now owns the new sysfs dir */
-               cpumask_clear_cpu(cpu, data->cpus);
-               cpufreq_add_dev(get_cpu_device(cpumask_first(data->cpus)), NULL);
+               if (cpufreq_driver->exit)
+                       cpufreq_driver->exit(data);
 
-               /* finally remove our own symlink */
-               lock_policy_rwsem_write(cpu);
-               __cpufreq_remove_dev(dev, sif);
+               free_cpumask_var(data->related_cpus);
+               free_cpumask_var(data->cpus);
+               kfree(data);
+       } else if (cpufreq_driver->target) {
+               __cpufreq_governor(data, CPUFREQ_GOV_START);
+               __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
        }
-#endif
-
-       free_cpumask_var(data->related_cpus);
-       free_cpumask_var(data->cpus);
-       kfree(data);
 
+       per_cpu(cpufreq_policy_cpu, cpu) = -1;
        return 0;
 }
 
@@ -1165,9 +1108,6 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
        if (cpu_is_offline(cpu))
                return 0;
 
-       if (unlikely(lock_policy_rwsem_write(cpu)))
-               BUG();
-
        retval = __cpufreq_remove_dev(dev, sif);
        return retval;
 }
@@ -1216,9 +1156,13 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
  */
 unsigned int cpufreq_quick_get(unsigned int cpu)
 {
-       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+       struct cpufreq_policy *policy;
        unsigned int ret_freq = 0;
 
+       if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
+               return cpufreq_driver->get(cpu);
+
+       policy = cpufreq_cpu_get(cpu);
        if (policy) {
                ret_freq = policy->cur;
                cpufreq_cpu_put(policy);
@@ -1386,6 +1330,20 @@ static struct syscore_ops cpufreq_syscore_ops = {
        .resume         = cpufreq_bp_resume,
 };
 
+/**
+ *     cpufreq_get_current_driver - return current driver's name
+ *
+ *     Return the name string of the currently loaded cpufreq driver
+ *     or NULL, if none.
+ */
+const char *cpufreq_get_current_driver(void)
+{
+       if (cpufreq_driver)
+               return cpufreq_driver->name;
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
 
 /*********************************************************************
  *                     NOTIFIER LISTS INTERFACE                      *
@@ -1408,6 +1366,9 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
 {
        int ret;
 
+       if (cpufreq_disabled())
+               return -EINVAL;
+
        WARN_ON(!init_cpufreq_transition_notifier_list_called);
 
        switch (list) {
@@ -1442,6 +1403,9 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
 {
        int ret;
 
+       if (cpufreq_disabled())
+               return -EINVAL;
+
        switch (list) {
        case CPUFREQ_TRANSITION_NOTIFIER:
                ret = srcu_notifier_chain_unregister(
@@ -1487,7 +1451,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
        if (target_freq == policy->cur)
                return 0;
 
-       if (cpu_online(policy->cpu) && cpufreq_driver->target)
+       if (cpufreq_driver->target)
                retval = cpufreq_driver->target(policy, target_freq, relation);
 
        return retval;
@@ -1522,7 +1486,10 @@ int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
 {
        int ret = 0;
 
-       if (!(cpu_online(cpu) && cpufreq_driver->getavg))
+       if (cpufreq_disabled())
+               return ret;
+
+       if (!cpufreq_driver->getavg)
                return 0;
 
        policy = cpufreq_cpu_get(policy->cpu);
@@ -1577,6 +1544,11 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
                                                policy->cpu, event);
        ret = policy->governor->governor(policy, event);
 
+       if (event == CPUFREQ_GOV_START)
+               policy->governor->initialized++;
+       else if (event == CPUFREQ_GOV_STOP)
+               policy->governor->initialized--;
+
        /* we keep one module reference alive for
                        each CPU governed by this CPU */
        if ((event != CPUFREQ_GOV_START) || ret)
@@ -1600,6 +1572,7 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
 
        mutex_lock(&cpufreq_governor_mutex);
 
+       governor->initialized = 0;
        err = -EBUSY;
        if (__find_governor(governor->name) == NULL) {
                err = 0;
@@ -1797,7 +1770,7 @@ int cpufreq_update_policy(unsigned int cpu)
                        pr_debug("Driver did not initialize current freq");
                        data->cur = policy.cur;
                } else {
-                       if (data->cur != policy.cur)
+                       if (data->cur != policy.cur && cpufreq_driver->target)
                                cpufreq_out_of_sync(cpu, data->cur,
                                                                policy.cur);
                }
@@ -1829,9 +1802,6 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
                        break;
                case CPU_DOWN_PREPARE:
                case CPU_DOWN_PREPARE_FROZEN:
-                       if (unlikely(lock_policy_rwsem_write(cpu)))
-                               BUG();
-
                        __cpufreq_remove_dev(dev, NULL);
                        break;
                case CPU_DOWN_FAILED:
index 64ef737..4fd0006 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "cpufreq_governor.h"
 
-/* Conservative governor macors */
+/* Conservative governor macros */
 #define DEF_FREQUENCY_UP_THRESHOLD             (80)
 #define DEF_FREQUENCY_DOWN_THRESHOLD           (20)
 #define DEF_SAMPLING_DOWN_FACTOR               (1)
@@ -113,17 +113,20 @@ static void cs_check_cpu(int cpu, unsigned int load)
 
 static void cs_dbs_timer(struct work_struct *work)
 {
+       struct delayed_work *dw = to_delayed_work(work);
        struct cs_cpu_dbs_info_s *dbs_info = container_of(work,
                        struct cs_cpu_dbs_info_s, cdbs.work.work);
-       unsigned int cpu = dbs_info->cdbs.cpu;
+       unsigned int cpu = dbs_info->cdbs.cur_policy->cpu;
+       struct cs_cpu_dbs_info_s *core_dbs_info = &per_cpu(cs_cpu_dbs_info,
+                       cpu);
        int delay = delay_for_sampling_rate(cs_tuners.sampling_rate);
 
-       mutex_lock(&dbs_info->cdbs.timer_mutex);
+       mutex_lock(&core_dbs_info->cdbs.timer_mutex);
+       if (need_load_eval(&core_dbs_info->cdbs, cs_tuners.sampling_rate))
+               dbs_check_cpu(&cs_dbs_data, cpu);
 
-       dbs_check_cpu(&cs_dbs_data, cpu);
-
-       schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay);
-       mutex_unlock(&dbs_info->cdbs.timer_mutex);
+       schedule_delayed_work_on(smp_processor_id(), dw, delay);
+       mutex_unlock(&core_dbs_info->cdbs.timer_mutex);
 }
 
 static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
@@ -141,7 +144,7 @@ static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 
        /*
         * we only care if our internally tracked freq moves outside the 'valid'
-        * ranges of freqency available to us otherwise we do not change it
+        * ranges of frequency available to us otherwise we do not change it
        */
        if (dbs_info->requested_freq > policy->max
                        || dbs_info->requested_freq < policy->min)
index 6c5f1d3..5a76086 100644 (file)
@@ -161,25 +161,48 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
 }
 EXPORT_SYMBOL_GPL(dbs_check_cpu);
 
-static inline void dbs_timer_init(struct dbs_data *dbs_data,
-               struct cpu_dbs_common_info *cdbs, unsigned int sampling_rate)
+static inline void dbs_timer_init(struct dbs_data *dbs_data, int cpu,
+                                 unsigned int sampling_rate)
 {
        int delay = delay_for_sampling_rate(sampling_rate);
+       struct cpu_dbs_common_info *cdbs = dbs_data->get_cpu_cdbs(cpu);
 
-       INIT_DEFERRABLE_WORK(&cdbs->work, dbs_data->gov_dbs_timer);
-       schedule_delayed_work_on(cdbs->cpu, &cdbs->work, delay);
+       schedule_delayed_work_on(cpu, &cdbs->work, delay);
 }
 
-static inline void dbs_timer_exit(struct cpu_dbs_common_info *cdbs)
+static inline void dbs_timer_exit(struct dbs_data *dbs_data, int cpu)
 {
+       struct cpu_dbs_common_info *cdbs = dbs_data->get_cpu_cdbs(cpu);
+
        cancel_delayed_work_sync(&cdbs->work);
 }
 
+/* Will return if we need to evaluate cpu load again or not */
+bool need_load_eval(struct cpu_dbs_common_info *cdbs,
+               unsigned int sampling_rate)
+{
+       if (policy_is_shared(cdbs->cur_policy)) {
+               ktime_t time_now = ktime_get();
+               s64 delta_us = ktime_us_delta(time_now, cdbs->time_stamp);
+
+               /* Do nothing if we recently have sampled */
+               if (delta_us < (s64)(sampling_rate / 2))
+                       return false;
+               else
+                       cdbs->time_stamp = time_now;
+       }
+
+       return true;
+}
+EXPORT_SYMBOL_GPL(need_load_eval);
+
 int cpufreq_governor_dbs(struct dbs_data *dbs_data,
                struct cpufreq_policy *policy, unsigned int event)
 {
        struct od_cpu_dbs_info_s *od_dbs_info = NULL;
        struct cs_cpu_dbs_info_s *cs_dbs_info = NULL;
+       struct cs_ops *cs_ops = NULL;
+       struct od_ops *od_ops = NULL;
        struct od_dbs_tuners *od_tuners = dbs_data->tuners;
        struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
        struct cpu_dbs_common_info *cpu_cdbs;
@@ -192,109 +215,111 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data,
                cs_dbs_info = dbs_data->get_cpu_dbs_info_s(cpu);
                sampling_rate = &cs_tuners->sampling_rate;
                ignore_nice = cs_tuners->ignore_nice;
+               cs_ops = dbs_data->gov_ops;
        } else {
                od_dbs_info = dbs_data->get_cpu_dbs_info_s(cpu);
                sampling_rate = &od_tuners->sampling_rate;
                ignore_nice = od_tuners->ignore_nice;
+               od_ops = dbs_data->gov_ops;
        }
 
        switch (event) {
        case CPUFREQ_GOV_START:
-               if ((!cpu_online(cpu)) || (!policy->cur))
+               if (!policy->cur)
                        return -EINVAL;
 
                mutex_lock(&dbs_data->mutex);
 
-               dbs_data->enable++;
-               cpu_cdbs->cpu = cpu;
                for_each_cpu(j, policy->cpus) {
-                       struct cpu_dbs_common_info *j_cdbs;
-                       j_cdbs = dbs_data->get_cpu_cdbs(j);
+                       struct cpu_dbs_common_info *j_cdbs =
+                               dbs_data->get_cpu_cdbs(j);
 
+                       j_cdbs->cpu = j;
                        j_cdbs->cur_policy = policy;
                        j_cdbs->prev_cpu_idle = get_cpu_idle_time(j,
                                        &j_cdbs->prev_cpu_wall);
                        if (ignore_nice)
                                j_cdbs->prev_cpu_nice =
                                        kcpustat_cpu(j).cpustat[CPUTIME_NICE];
-               }
 
-               /*
-                * Start the timerschedule work, when this governor is used for
-                * first time
-                */
-               if (dbs_data->enable != 1)
-                       goto second_time;
-
-               rc = sysfs_create_group(cpufreq_global_kobject,
-                               dbs_data->attr_group);
-               if (rc) {
-                       mutex_unlock(&dbs_data->mutex);
-                       return rc;
+                       mutex_init(&j_cdbs->timer_mutex);
+                       INIT_DEFERRABLE_WORK(&j_cdbs->work,
+                                            dbs_data->gov_dbs_timer);
                }
 
-               /* policy latency is in nS. Convert it to uS first */
-               latency = policy->cpuinfo.transition_latency / 1000;
-               if (latency == 0)
-                       latency = 1;
+               if (!policy->governor->initialized) {
+                       rc = sysfs_create_group(cpufreq_global_kobject,
+                                       dbs_data->attr_group);
+                       if (rc) {
+                               mutex_unlock(&dbs_data->mutex);
+                               return rc;
+                       }
+               }
 
                /*
                 * conservative does not implement micro like ondemand
                 * governor, thus we are bound to jiffes/HZ
                 */
                if (dbs_data->governor == GOV_CONSERVATIVE) {
-                       struct cs_ops *ops = dbs_data->gov_ops;
+                       cs_dbs_info->down_skip = 0;
+                       cs_dbs_info->enable = 1;
+                       cs_dbs_info->requested_freq = policy->cur;
 
-                       cpufreq_register_notifier(ops->notifier_block,
-                                       CPUFREQ_TRANSITION_NOTIFIER);
+                       if (!policy->governor->initialized) {
+                               cpufreq_register_notifier(cs_ops->notifier_block,
+                                               CPUFREQ_TRANSITION_NOTIFIER);
 
-                       dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
-                               jiffies_to_usecs(10);
+                               dbs_data->min_sampling_rate =
+                                       MIN_SAMPLING_RATE_RATIO *
+                                       jiffies_to_usecs(10);
+                       }
                } else {
-                       struct od_ops *ops = dbs_data->gov_ops;
+                       od_dbs_info->rate_mult = 1;
+                       od_dbs_info->sample_type = OD_NORMAL_SAMPLE;
+                       od_ops->powersave_bias_init_cpu(cpu);
 
-                       od_tuners->io_is_busy = ops->io_busy();
+                       if (!policy->governor->initialized)
+                               od_tuners->io_is_busy = od_ops->io_busy();
                }
 
+               if (policy->governor->initialized)
+                       goto unlock;
+
+               /* policy latency is in nS. Convert it to uS first */
+               latency = policy->cpuinfo.transition_latency / 1000;
+               if (latency == 0)
+                       latency = 1;
+
                /* Bring kernel and HW constraints together */
                dbs_data->min_sampling_rate = max(dbs_data->min_sampling_rate,
                                MIN_LATENCY_MULTIPLIER * latency);
                *sampling_rate = max(dbs_data->min_sampling_rate, latency *
                                LATENCY_MULTIPLIER);
-
-second_time:
-               if (dbs_data->governor == GOV_CONSERVATIVE) {
-                       cs_dbs_info->down_skip = 0;
-                       cs_dbs_info->enable = 1;
-                       cs_dbs_info->requested_freq = policy->cur;
-               } else {
-                       struct od_ops *ops = dbs_data->gov_ops;
-                       od_dbs_info->rate_mult = 1;
-                       od_dbs_info->sample_type = OD_NORMAL_SAMPLE;
-                       ops->powersave_bias_init_cpu(cpu);
-               }
+unlock:
                mutex_unlock(&dbs_data->mutex);
 
-               mutex_init(&cpu_cdbs->timer_mutex);
-               dbs_timer_init(dbs_data, cpu_cdbs, *sampling_rate);
+               /* Initiate timer time stamp */
+               cpu_cdbs->time_stamp = ktime_get();
+
+               for_each_cpu(j, policy->cpus)
+                       dbs_timer_init(dbs_data, j, *sampling_rate);
                break;
 
        case CPUFREQ_GOV_STOP:
                if (dbs_data->governor == GOV_CONSERVATIVE)
                        cs_dbs_info->enable = 0;
 
-               dbs_timer_exit(cpu_cdbs);
+               for_each_cpu(j, policy->cpus)
+                       dbs_timer_exit(dbs_data, j);
 
                mutex_lock(&dbs_data->mutex);
                mutex_destroy(&cpu_cdbs->timer_mutex);
-               dbs_data->enable--;
-               if (!dbs_data->enable) {
-                       struct cs_ops *ops = dbs_data->gov_ops;
 
+               if (policy->governor->initialized == 1) {
                        sysfs_remove_group(cpufreq_global_kobject,
                                        dbs_data->attr_group);
                        if (dbs_data->governor == GOV_CONSERVATIVE)
-                               cpufreq_unregister_notifier(ops->notifier_block,
+                               cpufreq_unregister_notifier(cs_ops->notifier_block,
                                                CPUFREQ_TRANSITION_NOTIFIER);
                }
                mutex_unlock(&dbs_data->mutex);
index f661654..d2ac911 100644 (file)
@@ -82,6 +82,7 @@ struct cpu_dbs_common_info {
         * the governor or limits.
         */
        struct mutex timer_mutex;
+       ktime_t time_stamp;
 };
 
 struct od_cpu_dbs_info_s {
@@ -108,7 +109,7 @@ struct od_dbs_tuners {
        unsigned int sampling_rate;
        unsigned int sampling_down_factor;
        unsigned int up_threshold;
-       unsigned int down_differential;
+       unsigned int adj_up_threshold;
        unsigned int powersave_bias;
        unsigned int io_is_busy;
 };
@@ -129,7 +130,6 @@ struct dbs_data {
        #define GOV_CONSERVATIVE        1
        int governor;
        unsigned int min_sampling_rate;
-       unsigned int enable; /* number of CPUs using this policy */
        struct attribute_group *attr_group;
        void *tuners;
 
@@ -171,6 +171,8 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate)
 
 u64 get_cpu_idle_time(unsigned int cpu, u64 *wall);
 void dbs_check_cpu(struct dbs_data *dbs_data, int cpu);
+bool need_load_eval(struct cpu_dbs_common_info *cdbs,
+               unsigned int sampling_rate);
 int cpufreq_governor_dbs(struct dbs_data *dbs_data,
                struct cpufreq_policy *policy, unsigned int event);
 #endif /* _CPUFREQ_GOVERNER_H */
index 7731f7c..f3eb26c 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "cpufreq_governor.h"
 
-/* On-demand governor macors */
+/* On-demand governor macros */
 #define DEF_FREQUENCY_DOWN_DIFFERENTIAL                (10)
 #define DEF_FREQUENCY_UP_THRESHOLD             (80)
 #define DEF_SAMPLING_DOWN_FACTOR               (1)
@@ -47,7 +47,8 @@ static struct cpufreq_governor cpufreq_gov_ondemand;
 static struct od_dbs_tuners od_tuners = {
        .up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
        .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
-       .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL,
+       .adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD -
+                           DEF_FREQUENCY_DOWN_DIFFERENTIAL,
        .ignore_nice = 0,
        .powersave_bias = 0,
 };
@@ -65,7 +66,7 @@ static void ondemand_powersave_bias_init_cpu(int cpu)
  * efficient idling at a higher frequency/voltage is.
  * Pavel Machek says this is not so for various generations of AMD and old
  * Intel systems.
- * Mike Chan (androidlcom) calis this is also not true for ARM.
+ * Mike Chan (android.com) claims this is also not true for ARM.
  * Because of this, whitelist specific known (series) of CPUs by default, and
  * leave all others up to the user.
  */
@@ -73,7 +74,7 @@ static int should_io_be_busy(void)
 {
 #if defined(CONFIG_X86)
        /*
-        * For Intel, Core 2 (model 15) andl later have an efficient idle.
+        * For Intel, Core 2 (model 15) and later have an efficient idle.
         */
        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
                        boot_cpu_data.x86 == 6 &&
@@ -158,8 +159,8 @@ static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
 
 /*
  * Every sampling_rate, we check, if current idle time is less than 20%
- * (default), then we try to increase frequency Every sampling_rate, we look for
- * a the lowest frequency which can sustain the load while keeping idle time
+ * (default), then we try to increase frequency. Every sampling_rate, we look
+ * for the lowest frequency which can sustain the load while keeping idle time
  * over 30%. If such a frequency exist, we try to decrease to this frequency.
  *
  * Any frequency increase takes it to the maximum frequency. Frequency reduction
@@ -192,11 +193,9 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
         * support the current CPU usage without triggering the up policy. To be
         * safe, we focus 10 points under the threshold.
         */
-       if (load_freq < (od_tuners.up_threshold - od_tuners.down_differential) *
-                       policy->cur) {
+       if (load_freq < od_tuners.adj_up_threshold * policy->cur) {
                unsigned int freq_next;
-               freq_next = load_freq / (od_tuners.up_threshold -
-                               od_tuners.down_differential);
+               freq_next = load_freq / od_tuners.adj_up_threshold;
 
                /* No longer fully busy, reset rate_mult */
                dbs_info->rate_mult = 1;
@@ -218,33 +217,42 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
 
 static void od_dbs_timer(struct work_struct *work)
 {
+       struct delayed_work *dw = to_delayed_work(work);
        struct od_cpu_dbs_info_s *dbs_info =
                container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work);
-       unsigned int cpu = dbs_info->cdbs.cpu;
-       int delay, sample_type = dbs_info->sample_type;
+       unsigned int cpu = dbs_info->cdbs.cur_policy->cpu;
+       struct od_cpu_dbs_info_s *core_dbs_info = &per_cpu(od_cpu_dbs_info,
+                       cpu);
+       int delay, sample_type = core_dbs_info->sample_type;
+       bool eval_load;
 
-       mutex_lock(&dbs_info->cdbs.timer_mutex);
+       mutex_lock(&core_dbs_info->cdbs.timer_mutex);
+       eval_load = need_load_eval(&core_dbs_info->cdbs,
+                       od_tuners.sampling_rate);
 
        /* Common NORMAL_SAMPLE setup */
-       dbs_info->sample_type = OD_NORMAL_SAMPLE;
+       core_dbs_info->sample_type = OD_NORMAL_SAMPLE;
        if (sample_type == OD_SUB_SAMPLE) {
-               delay = dbs_info->freq_lo_jiffies;
-               __cpufreq_driver_target(dbs_info->cdbs.cur_policy,
-                       dbs_info->freq_lo, CPUFREQ_RELATION_H);
+               delay = core_dbs_info->freq_lo_jiffies;
+               if (eval_load)
+                       __cpufreq_driver_target(core_dbs_info->cdbs.cur_policy,
+                                               core_dbs_info->freq_lo,
+                                               CPUFREQ_RELATION_H);
        } else {
-               dbs_check_cpu(&od_dbs_data, cpu);
-               if (dbs_info->freq_lo) {
+               if (eval_load)
+                       dbs_check_cpu(&od_dbs_data, cpu);
+               if (core_dbs_info->freq_lo) {
                        /* Setup timer for SUB_SAMPLE */
-                       dbs_info->sample_type = OD_SUB_SAMPLE;
-                       delay = dbs_info->freq_hi_jiffies;
+                       core_dbs_info->sample_type = OD_SUB_SAMPLE;
+                       delay = core_dbs_info->freq_hi_jiffies;
                } else {
                        delay = delay_for_sampling_rate(od_tuners.sampling_rate
-                                               * dbs_info->rate_mult);
+                                               * core_dbs_info->rate_mult);
                }
        }
 
-       schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay);
-       mutex_unlock(&dbs_info->cdbs.timer_mutex);
+       schedule_delayed_work_on(smp_processor_id(), dw, delay);
+       mutex_unlock(&core_dbs_info->cdbs.timer_mutex);
 }
 
 /************************** sysfs interface ************************/
@@ -259,7 +267,7 @@ static ssize_t show_sampling_rate_min(struct kobject *kobj,
  * update_sampling_rate - update sampling rate effective immediately if needed.
  * @new_rate: new sampling rate
  *
- * If new rate is smaller than the old, simply updaing
+ * If new rate is smaller than the old, simply updating
  * dbs_tuners_int.sampling_rate might not be appropriate. For example, if the
  * original sampling_rate was 1 second and the requested new sampling rate is 10
  * ms because the user needs immediate reaction from ondemand governor, but not
@@ -287,7 +295,7 @@ static void update_sampling_rate(unsigned int new_rate)
                        cpufreq_cpu_put(policy);
                        continue;
                }
-               dbs_info = &per_cpu(od_cpu_dbs_info, policy->cpu);
+               dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
                cpufreq_cpu_put(policy);
 
                mutex_lock(&dbs_info->cdbs.timer_mutex);
@@ -306,8 +314,7 @@ static void update_sampling_rate(unsigned int new_rate)
                        cancel_delayed_work_sync(&dbs_info->cdbs.work);
                        mutex_lock(&dbs_info->cdbs.timer_mutex);
 
-                       schedule_delayed_work_on(dbs_info->cdbs.cpu,
-                                       &dbs_info->cdbs.work,
+                       schedule_delayed_work_on(cpu, &dbs_info->cdbs.work,
                                        usecs_to_jiffies(new_rate));
 
                }
@@ -351,6 +358,10 @@ static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
                        input < MIN_FREQUENCY_UP_THRESHOLD) {
                return -EINVAL;
        }
+       /* Calculate the new adj_up_threshold */
+       od_tuners.adj_up_threshold += input;
+       od_tuners.adj_up_threshold -= od_tuners.up_threshold;
+
        od_tuners.up_threshold = input;
        return count;
 }
@@ -507,7 +518,8 @@ static int __init cpufreq_gov_dbs_init(void)
        if (idle_time != -1ULL) {
                /* Idle micro accounting is supported. Use finer thresholds */
                od_tuners.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
-               od_tuners.down_differential = MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
+               od_tuners.adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD -
+                                            MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
                /*
                 * In nohz/micro accounting case we set the minimum frequency
                 * not depending on HZ, but fixed (very low). The deferred
index 9d7732b..2fd779e 100644 (file)
 
 static spinlock_t cpufreq_stats_lock;
 
-#define CPUFREQ_STATDEVICE_ATTR(_name, _mode, _show) \
-static struct freq_attr _attr_##_name = {\
-       .attr = {.name = __stringify(_name), .mode = _mode, }, \
-       .show = _show,\
-};
-
 struct cpufreq_stats {
        unsigned int cpu;
        unsigned int total_trans;
@@ -136,17 +130,17 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
                return PAGE_SIZE;
        return len;
 }
-CPUFREQ_STATDEVICE_ATTR(trans_table, 0444, show_trans_table);
+cpufreq_freq_attr_ro(trans_table);
 #endif
 
-CPUFREQ_STATDEVICE_ATTR(total_trans, 0444, show_total_trans);
-CPUFREQ_STATDEVICE_ATTR(time_in_state, 0444, show_time_in_state);
+cpufreq_freq_attr_ro(total_trans);
+cpufreq_freq_attr_ro(time_in_state);
 
 static struct attribute *default_attrs[] = {
-       &_attr_total_trans.attr,
-       &_attr_time_in_state.attr,
+       &total_trans.attr,
+       &time_in_state.attr,
 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
-       &_attr_trans_table.attr,
+       &trans_table.attr,
 #endif
        NULL
 };
@@ -170,11 +164,13 @@ static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
 static void cpufreq_stats_free_table(unsigned int cpu)
 {
        struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu);
+
        if (stat) {
+               pr_debug("%s: Free stat table\n", __func__);
                kfree(stat->time_in_state);
                kfree(stat);
+               per_cpu(cpufreq_stats_table, cpu) = NULL;
        }
-       per_cpu(cpufreq_stats_table, cpu) = NULL;
 }
 
 /* must be called early in the CPU removal sequence (before
@@ -183,8 +179,14 @@ static void cpufreq_stats_free_table(unsigned int cpu)
 static void cpufreq_stats_free_sysfs(unsigned int cpu)
 {
        struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-       if (policy && policy->cpu == cpu)
+
+       if (!cpufreq_frequency_get_table(cpu))
+               return;
+
+       if (policy && !policy_is_shared(policy)) {
+               pr_debug("%s: Free sysfs stat\n", __func__);
                sysfs_remove_group(&policy->kobj, &stats_attr_group);
+       }
        if (policy)
                cpufreq_cpu_put(policy);
 }
@@ -262,6 +264,19 @@ error_get_fail:
        return ret;
 }
 
+static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy)
+{
+       struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table,
+                       policy->last_cpu);
+
+       pr_debug("Updating stats_table for new_cpu %u from last_cpu %u\n",
+                       policy->cpu, policy->last_cpu);
+       per_cpu(cpufreq_stats_table, policy->cpu) = per_cpu(cpufreq_stats_table,
+                       policy->last_cpu);
+       per_cpu(cpufreq_stats_table, policy->last_cpu) = NULL;
+       stat->cpu = policy->cpu;
+}
+
 static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
                unsigned long val, void *data)
 {
@@ -269,6 +284,12 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
        struct cpufreq_policy *policy = data;
        struct cpufreq_frequency_table *table;
        unsigned int cpu = policy->cpu;
+
+       if (val == CPUFREQ_UPDATE_POLICY_CPU) {
+               cpufreq_stats_update_policy_cpu(policy);
+               return 0;
+       }
+
        if (val != CPUFREQ_NOTIFY)
                return 0;
        table = cpufreq_frequency_get_table(cpu);
index c8c3d29..bbeb9c0 100644 (file)
@@ -118,8 +118,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
 
        switch (event) {
        case CPUFREQ_GOV_START:
-               if (!cpu_online(cpu))
-                       return -EINVAL;
                BUG_ON(!policy->cur);
                mutex_lock(&userspace_mutex);
 
index 4f154bc..79a8486 100644 (file)
@@ -128,9 +128,7 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
        policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */
 
        /* policy sharing between dual CPUs */
-       cpumask_copy(policy->cpus, cpu_present_mask);
-
-       policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+       cpumask_setall(policy->cpus);
 
        return 0;
 }
index 7012ea8..69b676d 100644 (file)
@@ -42,51 +42,56 @@ static unsigned int exynos_getspeed(unsigned int cpu)
        return clk_get_rate(exynos_info->cpu_clk) / 1000;
 }
 
-static int exynos_target(struct cpufreq_policy *policy,
-                         unsigned int target_freq,
-                         unsigned int relation)
+static int exynos_cpufreq_get_index(unsigned int freq)
+{
+       struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
+       int index;
+
+       for (index = 0;
+               freq_table[index].frequency != CPUFREQ_TABLE_END; index++)
+               if (freq_table[index].frequency == freq)
+                       break;
+
+       if (freq_table[index].frequency == CPUFREQ_TABLE_END)
+               return -EINVAL;
+
+       return index;
+}
+
+static int exynos_cpufreq_scale(unsigned int target_freq)
 {
-       unsigned int index, old_index;
-       unsigned int arm_volt, safe_arm_volt = 0;
-       int ret = 0;
        struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
        unsigned int *volt_table = exynos_info->volt_table;
+       struct cpufreq_policy *policy = cpufreq_cpu_get(0);
+       unsigned int arm_volt, safe_arm_volt = 0;
        unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz;
-
-       mutex_lock(&cpufreq_lock);
+       int index, old_index;
+       int ret = 0;
 
        freqs.old = policy->cur;
+       freqs.new = target_freq;
+       freqs.cpu = policy->cpu;
 
-       if (frequency_locked && target_freq != locking_frequency) {
-               ret = -EAGAIN;
+       if (freqs.new == freqs.old)
                goto out;
-       }
 
        /*
         * The policy max have been changed so that we cannot get proper
         * old_index with cpufreq_frequency_table_target(). Thus, ignore
         * policy and get the index from the raw freqeuncy table.
         */
-       for (old_index = 0;
-               freq_table[old_index].frequency != CPUFREQ_TABLE_END;
-               old_index++)
-               if (freq_table[old_index].frequency == freqs.old)
-                       break;
-
-       if (freq_table[old_index].frequency == CPUFREQ_TABLE_END) {
-               ret = -EINVAL;
+       old_index = exynos_cpufreq_get_index(freqs.old);
+       if (old_index < 0) {
+               ret = old_index;
                goto out;
        }
 
-       if (cpufreq_frequency_table_target(policy, freq_table,
-                                          target_freq, relation, &index)) {
-               ret = -EINVAL;
+       index = exynos_cpufreq_get_index(target_freq);
+       if (index < 0) {
+               ret = index;
                goto out;
        }
 
-       freqs.new = freq_table[index].frequency;
-       freqs.cpu = policy->cpu;
-
        /*
         * ARM clock source will be changed APLL to MPLL temporary
         * To support this level, need to control regulator for
@@ -106,15 +111,25 @@ static int exynos_target(struct cpufreq_policy *policy,
        /* When the new frequency is higher than current frequency */
        if ((freqs.new > freqs.old) && !safe_arm_volt) {
                /* Firstly, voltage up to increase frequency */
-               regulator_set_voltage(arm_regulator, arm_volt,
-                               arm_volt);
+               ret = regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
+               if (ret) {
+                       pr_err("%s: failed to set cpu voltage to %d\n",
+                               __func__, arm_volt);
+                       goto out;
+               }
        }
 
-       if (safe_arm_volt)
-               regulator_set_voltage(arm_regulator, safe_arm_volt,
+       if (safe_arm_volt) {
+               ret = regulator_set_voltage(arm_regulator, safe_arm_volt,
                                      safe_arm_volt);
-       if (freqs.new != freqs.old)
-               exynos_info->set_freq(old_index, index);
+               if (ret) {
+                       pr_err("%s: failed to set cpu voltage to %d\n",
+                               __func__, safe_arm_volt);
+                       goto out;
+               }
+       }
+
+       exynos_info->set_freq(old_index, index);
 
        for_each_cpu(freqs.cpu, policy->cpus)
                cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
@@ -125,8 +140,44 @@ static int exynos_target(struct cpufreq_policy *policy,
                /* down the voltage after frequency change */
                regulator_set_voltage(arm_regulator, arm_volt,
                                arm_volt);
+               if (ret) {
+                       pr_err("%s: failed to set cpu voltage to %d\n",
+                               __func__, arm_volt);
+                       goto out;
+               }
+       }
+
+out:
+
+       cpufreq_cpu_put(policy);
+
+       return ret;
+}
+
+static int exynos_target(struct cpufreq_policy *policy,
+                         unsigned int target_freq,
+                         unsigned int relation)
+{
+       struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
+       unsigned int index;
+       unsigned int new_freq;
+       int ret = 0;
+
+       mutex_lock(&cpufreq_lock);
+
+       if (frequency_locked)
+               goto out;
+
+       if (cpufreq_frequency_table_target(policy, freq_table,
+                                          target_freq, relation, &index)) {
+               ret = -EINVAL;
+               goto out;
        }
 
+       new_freq = freq_table[index].frequency;
+
+       ret = exynos_cpufreq_scale(new_freq);
+
 out:
        mutex_unlock(&cpufreq_lock);
 
@@ -163,51 +214,26 @@ static int exynos_cpufreq_resume(struct cpufreq_policy *policy)
 static int exynos_cpufreq_pm_notifier(struct notifier_block *notifier,
                                       unsigned long pm_event, void *v)
 {
-       struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */
-       static unsigned int saved_frequency;
-       unsigned int temp;
+       int ret;
 
-       mutex_lock(&cpufreq_lock);
        switch (pm_event) {
        case PM_SUSPEND_PREPARE:
-               if (frequency_locked)
-                       goto out;
-
+               mutex_lock(&cpufreq_lock);
                frequency_locked = true;
+               mutex_unlock(&cpufreq_lock);
 
-               if (locking_frequency) {
-                       saved_frequency = exynos_getspeed(0);
+               ret = exynos_cpufreq_scale(locking_frequency);
+               if (ret < 0)
+                       return NOTIFY_BAD;
 
-                       mutex_unlock(&cpufreq_lock);
-                       exynos_target(policy, locking_frequency,
-                                     CPUFREQ_RELATION_H);
-                       mutex_lock(&cpufreq_lock);
-               }
                break;
 
        case PM_POST_SUSPEND:
-               if (saved_frequency) {
-                       /*
-                        * While frequency_locked, only locking_frequency
-                        * is valid for target(). In order to use
-                        * saved_frequency while keeping frequency_locked,
-                        * we temporarly overwrite locking_frequency.
-                        */
-                       temp = locking_frequency;
-                       locking_frequency = saved_frequency;
-
-                       mutex_unlock(&cpufreq_lock);
-                       exynos_target(policy, locking_frequency,
-                                     CPUFREQ_RELATION_H);
-                       mutex_lock(&cpufreq_lock);
-
-                       locking_frequency = temp;
-               }
+               mutex_lock(&cpufreq_lock);
                frequency_locked = false;
+               mutex_unlock(&cpufreq_lock);
                break;
        }
-out:
-       mutex_unlock(&cpufreq_lock);
 
        return NOTIFY_OK;
 }
@@ -222,35 +248,34 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
        cpufreq_frequency_table_get_attr(exynos_info->freq_table, policy->cpu);
 
-       locking_frequency = exynos_getspeed(0);
-
        /* set the transition latency value */
        policy->cpuinfo.transition_latency = 100000;
 
-       /*
-        * EXYNOS4 multi-core processors has 2 cores
-        * that the frequency cannot be set independently.
-        * Each cpu is bound to the same speed.
-        * So the affected cpu is all of the cpus.
-        */
-       if (num_online_cpus() == 1) {
-               cpumask_copy(policy->related_cpus, cpu_possible_mask);
-               cpumask_copy(policy->cpus, cpu_online_mask);
-       } else {
-               policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
-               cpumask_setall(policy->cpus);
-       }
+       cpumask_setall(policy->cpus);
 
        return cpufreq_frequency_table_cpuinfo(policy, exynos_info->freq_table);
 }
 
+static int exynos_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+       cpufreq_frequency_table_put_attr(policy->cpu);
+       return 0;
+}
+
+static struct freq_attr *exynos_cpufreq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
 static struct cpufreq_driver exynos_driver = {
        .flags          = CPUFREQ_STICKY,
        .verify         = exynos_verify_speed,
        .target         = exynos_target,
        .get            = exynos_getspeed,
        .init           = exynos_cpufreq_cpu_init,
+       .exit           = exynos_cpufreq_cpu_exit,
        .name           = "exynos_cpufreq",
+       .attr           = exynos_cpufreq_attr,
 #ifdef CONFIG_PM
        .suspend        = exynos_cpufreq_suspend,
        .resume         = exynos_cpufreq_resume,
@@ -288,6 +313,8 @@ static int __init exynos_cpufreq_init(void)
                goto err_vdd_arm;
        }
 
+       locking_frequency = exynos_getspeed(0);
+
        register_pm_notifier(&exynos_cpufreq_nb);
 
        if (cpufreq_register_driver(&exynos_driver)) {
@@ -299,8 +326,7 @@ static int __init exynos_cpufreq_init(void)
 err_cpufreq:
        unregister_pm_notifier(&exynos_cpufreq_nb);
 
-       if (!IS_ERR(arm_regulator))
-               regulator_put(arm_regulator);
+       regulator_put(arm_regulator);
 err_vdd_arm:
        kfree(exynos_info);
        pr_debug("%s: failed initialization\n", __func__);
index fb148fa..de91755 100644 (file)
 #include <mach/regs-clock.h>
 #include <mach/cpufreq.h>
 
-#define CPUFREQ_LEVEL_END      L5
-
-static int max_support_idx = L0;
-static int min_support_idx = (CPUFREQ_LEVEL_END - 1);
-
 static struct clk *cpu_clk;
 static struct clk *moutcore;
 static struct clk *mout_mpll;
 static struct clk *mout_apll;
 
-struct cpufreq_clkdiv {
-       unsigned int index;
-       unsigned int clkdiv;
-};
-
-static unsigned int exynos4210_volt_table[CPUFREQ_LEVEL_END] = {
+static unsigned int exynos4210_volt_table[] = {
        1250000, 1150000, 1050000, 975000, 950000,
 };
 
-
-static struct cpufreq_clkdiv exynos4210_clkdiv_table[CPUFREQ_LEVEL_END];
-
 static struct cpufreq_frequency_table exynos4210_freq_table[] = {
-       {L0, 1200*1000},
-       {L1, 1000*1000},
-       {L2, 800*1000},
-       {L3, 500*1000},
-       {L4, 200*1000},
+       {L0, 1200 * 1000},
+       {L1, 1000 * 1000},
+       {L2,  800 * 1000},
+       {L3,  500 * 1000},
+       {L4,  200 * 1000},
        {0, CPUFREQ_TABLE_END},
 };
 
-static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
+static struct apll_freq apll_freq_4210[] = {
        /*
-        * Clock divider value for following
-        * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
-        *              DIVATB, DIVPCLK_DBG, DIVAPLL }
+        * values:
+        * freq
+        * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, RESERVED
+        * clock divider for COPY, HPM, RESERVED
+        * PLL M, P, S
         */
-
-       /* ARM L0: 1200MHz */
-       { 0, 3, 7, 3, 4, 1, 7 },
-
-       /* ARM L1: 1000MHz */
-       { 0, 3, 7, 3, 4, 1, 7 },
-
-       /* ARM L2: 800MHz */
-       { 0, 3, 7, 3, 3, 1, 7 },
-
-       /* ARM L3: 500MHz */
-       { 0, 3, 7, 3, 3, 1, 7 },
-
-       /* ARM L4: 200MHz */
-       { 0, 1, 3, 1, 3, 1, 0 },
-};
-
-static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
-       /*
-        * Clock divider value for following
-        * { DIVCOPY, DIVHPM }
-        */
-
-       /* ARM L0: 1200MHz */
-       { 5, 0 },
-
-       /* ARM L1: 1000MHz */
-       { 4, 0 },
-
-       /* ARM L2: 800MHz */
-       { 3, 0 },
-
-       /* ARM L3: 500MHz */
-       { 3, 0 },
-
-       /* ARM L4: 200MHz */
-       { 3, 0 },
-};
-
-static unsigned int exynos4210_apll_pms_table[CPUFREQ_LEVEL_END] = {
-       /* APLL FOUT L0: 1200MHz */
-       ((150 << 16) | (3 << 8) | 1),
-
-       /* APLL FOUT L1: 1000MHz */
-       ((250 << 16) | (6 << 8) | 1),
-
-       /* APLL FOUT L2: 800MHz */
-       ((200 << 16) | (6 << 8) | 1),
-
-       /* APLL FOUT L3: 500MHz */
-       ((250 << 16) | (6 << 8) | 2),
-
-       /* APLL FOUT L4: 200MHz */
-       ((200 << 16) | (6 << 8) | 3),
+       APLL_FREQ(1200, 0, 3, 7, 3, 4, 1, 7, 0, 5, 0, 0, 150, 3, 1),
+       APLL_FREQ(1000, 0, 3, 7, 3, 4, 1, 7, 0, 4, 0, 0, 250, 6, 1),
+       APLL_FREQ(800,  0, 3, 7, 3, 3, 1, 7, 0, 3, 0, 0, 200, 6, 1),
+       APLL_FREQ(500,  0, 3, 7, 3, 3, 1, 7, 0, 3, 0, 0, 250, 6, 2),
+       APLL_FREQ(200,  0, 1, 3, 1, 3, 1, 0, 0, 3, 0, 0, 200, 6, 3),
 };
 
 static void exynos4210_set_clkdiv(unsigned int div_index)
@@ -119,7 +59,7 @@ static void exynos4210_set_clkdiv(unsigned int div_index)
 
        /* Change Divider - CPU0 */
 
-       tmp = exynos4210_clkdiv_table[div_index].clkdiv;
+       tmp = apll_freq_4210[div_index].clk_div_cpu0;
 
        __raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
 
@@ -129,12 +69,7 @@ static void exynos4210_set_clkdiv(unsigned int div_index)
 
        /* Change Divider - CPU1 */
 
-       tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1);
-
-       tmp &= ~((0x7 << 4) | 0x7);
-
-       tmp |= ((clkdiv_cpu1[div_index][0] << 4) |
-               (clkdiv_cpu1[div_index][1] << 0));
+       tmp = apll_freq_4210[div_index].clk_div_cpu1;
 
        __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
 
@@ -162,7 +97,7 @@ static void exynos4210_set_apll(unsigned int index)
        /* 3. Change PLL PMS values */
        tmp = __raw_readl(EXYNOS4_APLL_CON0);
        tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
-       tmp |= exynos4210_apll_pms_table[index];
+       tmp |= apll_freq_4210[index].mps;
        __raw_writel(tmp, EXYNOS4_APLL_CON0);
 
        /* 4. wait_lock_time */
@@ -179,10 +114,10 @@ static void exynos4210_set_apll(unsigned int index)
        } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
 }
 
-bool exynos4210_pms_change(unsigned int old_index, unsigned int new_index)
+static bool exynos4210_pms_change(unsigned int old_index, unsigned int new_index)
 {
-       unsigned int old_pm = (exynos4210_apll_pms_table[old_index] >> 8);
-       unsigned int new_pm = (exynos4210_apll_pms_table[new_index] >> 8);
+       unsigned int old_pm = apll_freq_4210[old_index].mps >> 8;
+       unsigned int new_pm = apll_freq_4210[new_index].mps >> 8;
 
        return (old_pm == new_pm) ? 0 : 1;
 }
@@ -200,7 +135,7 @@ static void exynos4210_set_frequency(unsigned int old_index,
                        /* 2. Change just s value in apll m,p,s value */
                        tmp = __raw_readl(EXYNOS4_APLL_CON0);
                        tmp &= ~(0x7 << 0);
-                       tmp |= (exynos4210_apll_pms_table[new_index] & 0x7);
+                       tmp |= apll_freq_4210[new_index].mps & 0x7;
                        __raw_writel(tmp, EXYNOS4_APLL_CON0);
                } else {
                        /* Clock Configuration Procedure */
@@ -214,7 +149,7 @@ static void exynos4210_set_frequency(unsigned int old_index,
                        /* 1. Change just s value in apll m,p,s value */
                        tmp = __raw_readl(EXYNOS4_APLL_CON0);
                        tmp &= ~(0x7 << 0);
-                       tmp |= (exynos4210_apll_pms_table[new_index] & 0x7);
+                       tmp |= apll_freq_4210[new_index].mps & 0x7;
                        __raw_writel(tmp, EXYNOS4_APLL_CON0);
 
                        /* 2. Change the system clock divider values */
@@ -231,8 +166,6 @@ static void exynos4210_set_frequency(unsigned int old_index,
 
 int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
 {
-       int i;
-       unsigned int tmp;
        unsigned long rate;
 
        cpu_clk = clk_get(NULL, "armclk");
@@ -253,33 +186,9 @@ int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
        if (IS_ERR(mout_apll))
                goto err_mout_apll;
 
-       tmp = __raw_readl(EXYNOS4_CLKDIV_CPU);
-
-       for (i = L0; i <  CPUFREQ_LEVEL_END; i++) {
-               tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK |
-                       EXYNOS4_CLKDIV_CPU0_COREM0_MASK |
-                       EXYNOS4_CLKDIV_CPU0_COREM1_MASK |
-                       EXYNOS4_CLKDIV_CPU0_PERIPH_MASK |
-                       EXYNOS4_CLKDIV_CPU0_ATB_MASK |
-                       EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK |
-                       EXYNOS4_CLKDIV_CPU0_APLL_MASK);
-
-               tmp |= ((clkdiv_cpu0[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) |
-                       (clkdiv_cpu0[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) |
-                       (clkdiv_cpu0[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) |
-                       (clkdiv_cpu0[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) |
-                       (clkdiv_cpu0[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) |
-                       (clkdiv_cpu0[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) |
-                       (clkdiv_cpu0[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT));
-
-               exynos4210_clkdiv_table[i].clkdiv = tmp;
-       }
-
        info->mpll_freq_khz = rate;
-       info->pm_lock_idx = L2;
+       /* 800Mhz */
        info->pll_safe_idx = L2;
-       info->max_support_idx = max_support_idx;
-       info->min_support_idx = min_support_idx;
        info->cpu_clk = cpu_clk;
        info->volt_table = exynos4210_volt_table;
        info->freq_table = exynos4210_freq_table;
@@ -289,14 +198,11 @@ int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
        return 0;
 
 err_mout_apll:
-       if (!IS_ERR(mout_mpll))
-               clk_put(mout_mpll);
+       clk_put(mout_mpll);
 err_mout_mpll:
-       if (!IS_ERR(moutcore))
-               clk_put(moutcore);
+       clk_put(moutcore);
 err_moutcore:
-       if (!IS_ERR(cpu_clk))
-               clk_put(cpu_clk);
+       clk_put(cpu_clk);
 
        pr_debug("%s: failed initialization\n", __func__);
        return -EINVAL;
index 8c5a7af..0661039 100644 (file)
 #include <mach/regs-clock.h>
 #include <mach/cpufreq.h>
 
-#define CPUFREQ_LEVEL_END      (L13 + 1)
-
-static int max_support_idx;
-static int min_support_idx = (CPUFREQ_LEVEL_END - 1);
-
 static struct clk *cpu_clk;
 static struct clk *moutcore;
 static struct clk *mout_mpll;
 static struct clk *mout_apll;
 
-struct cpufreq_clkdiv {
-       unsigned int    index;
-       unsigned int    clkdiv;
-       unsigned int    clkdiv1;
+static unsigned int exynos4x12_volt_table[] = {
+       1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500,
+       1000000,  987500,  975000,  950000,  925000,  900000,  900000
 };
 
-static unsigned int exynos4x12_volt_table[CPUFREQ_LEVEL_END];
-
 static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
-       {L0, 1500 * 1000},
+       {L0, CPUFREQ_ENTRY_INVALID},
        {L1, 1400 * 1000},
        {L2, 1300 * 1000},
        {L3, 1200 * 1000},
@@ -56,247 +48,54 @@ static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
        {0, CPUFREQ_TABLE_END},
 };
 
-static struct cpufreq_clkdiv exynos4x12_clkdiv_table[CPUFREQ_LEVEL_END];
+static struct apll_freq *apll_freq_4x12;
 
-static unsigned int clkdiv_cpu0_4212[CPUFREQ_LEVEL_END][8] = {
+static struct apll_freq apll_freq_4212[] = {
        /*
-        * Clock divider value for following
-        * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
-        *              DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 }
+        * values:
+        * freq
+        * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2
+        * clock divider for COPY, HPM, RESERVED
+        * PLL M, P, S
         */
-       /* ARM L0: 1500 MHz */
-       { 0, 3, 7, 0, 6, 1, 2, 0 },
-
-       /* ARM L1: 1400 MHz */
-       { 0, 3, 7, 0, 6, 1, 2, 0 },
-
-       /* ARM L2: 1300 MHz */
-       { 0, 3, 7, 0, 5, 1, 2, 0 },
-
-       /* ARM L3: 1200 MHz */
-       { 0, 3, 7, 0, 5, 1, 2, 0 },
-
-       /* ARM L4: 1100 MHz */
-       { 0, 3, 6, 0, 4, 1, 2, 0 },
-
-       /* ARM L5: 1000 MHz */
-       { 0, 2, 5, 0, 4, 1, 1, 0 },
-
-       /* ARM L6: 900 MHz */
-       { 0, 2, 5, 0, 3, 1, 1, 0 },
-
-       /* ARM L7: 800 MHz */
-       { 0, 2, 5, 0, 3, 1, 1, 0 },
-
-       /* ARM L8: 700 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L9: 600 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L10: 500 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L11: 400 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L12: 300 MHz */
-       { 0, 2, 4, 0, 2, 1, 1, 0 },
-
-       /* ARM L13: 200 MHz */
-       { 0, 1, 3, 0, 1, 1, 1, 0 },
+       APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 250, 4, 0),
+       APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 175, 3, 0),
+       APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 325, 6, 0),
+       APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 200, 4, 0),
+       APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 2, 0, 275, 6, 0),
+       APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 2, 0, 125, 3, 0),
+       APLL_FREQ(900,  0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 150, 4, 0),
+       APLL_FREQ(800,  0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 0),
+       APLL_FREQ(700,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 175, 3, 1),
+       APLL_FREQ(600,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 200, 4, 1),
+       APLL_FREQ(500,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 125, 3, 1),
+       APLL_FREQ(400,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 1),
+       APLL_FREQ(300,  0, 2, 4, 0, 2, 1, 1, 0, 3, 2, 0, 200, 4, 2),
+       APLL_FREQ(200,  0, 1, 3, 0, 1, 1, 1, 0, 3, 2, 0, 100, 3, 2),
 };
 
-static unsigned int clkdiv_cpu0_4412[CPUFREQ_LEVEL_END][8] = {
+static struct apll_freq apll_freq_4412[] = {
        /*
-        * Clock divider value for following
-        * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
-        *              DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 }
-        */
-       /* ARM L0: 1500 MHz */
-       { 0, 3, 7, 0, 6, 1, 2, 0 },
-
-       /* ARM L1: 1400 MHz */
-       { 0, 3, 7, 0, 6, 1, 2, 0 },
-
-       /* ARM L2: 1300 MHz */
-       { 0, 3, 7, 0, 5, 1, 2, 0 },
-
-       /* ARM L3: 1200 MHz */
-       { 0, 3, 7, 0, 5, 1, 2, 0 },
-
-       /* ARM L4: 1100 MHz */
-       { 0, 3, 6, 0, 4, 1, 2, 0 },
-
-       /* ARM L5: 1000 MHz */
-       { 0, 2, 5, 0, 4, 1, 1, 0 },
-
-       /* ARM L6: 900 MHz */
-       { 0, 2, 5, 0, 3, 1, 1, 0 },
-
-       /* ARM L7: 800 MHz */
-       { 0, 2, 5, 0, 3, 1, 1, 0 },
-
-       /* ARM L8: 700 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L9: 600 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L10: 500 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L11: 400 MHz */
-       { 0, 2, 4, 0, 3, 1, 1, 0 },
-
-       /* ARM L12: 300 MHz */
-       { 0, 2, 4, 0, 2, 1, 1, 0 },
-
-       /* ARM L13: 200 MHz */
-       { 0, 1, 3, 0, 1, 1, 1, 0 },
-};
-
-static unsigned int clkdiv_cpu1_4212[CPUFREQ_LEVEL_END][2] = {
-       /* Clock divider value for following
-        * { DIVCOPY, DIVHPM }
-        */
-       /* ARM L0: 1500 MHz */
-       { 6, 0 },
-
-       /* ARM L1: 1400 MHz */
-       { 6, 0 },
-
-       /* ARM L2: 1300 MHz */
-       { 5, 0 },
-
-       /* ARM L3: 1200 MHz */
-       { 5, 0 },
-
-       /* ARM L4: 1100 MHz */
-       { 4, 0 },
-
-       /* ARM L5: 1000 MHz */
-       { 4, 0 },
-
-       /* ARM L6: 900 MHz */
-       { 3, 0 },
-
-       /* ARM L7: 800 MHz */
-       { 3, 0 },
-
-       /* ARM L8: 700 MHz */
-       { 3, 0 },
-
-       /* ARM L9: 600 MHz */
-       { 3, 0 },
-
-       /* ARM L10: 500 MHz */
-       { 3, 0 },
-
-       /* ARM L11: 400 MHz */
-       { 3, 0 },
-
-       /* ARM L12: 300 MHz */
-       { 3, 0 },
-
-       /* ARM L13: 200 MHz */
-       { 3, 0 },
-};
-
-static unsigned int clkdiv_cpu1_4412[CPUFREQ_LEVEL_END][3] = {
-       /* Clock divider value for following
-        * { DIVCOPY, DIVHPM, DIVCORES }
+        * values:
+        * freq
+        * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2
+        * clock divider for COPY, HPM, CORES
+        * PLL M, P, S
         */
-       /* ARM L0: 1500 MHz */
-       { 6, 0, 7 },
-
-       /* ARM L1: 1400 MHz */
-       { 6, 0, 6 },
-
-       /* ARM L2: 1300 MHz */
-       { 5, 0, 6 },
-
-       /* ARM L3: 1200 MHz */
-       { 5, 0, 5 },
-
-       /* ARM L4: 1100 MHz */
-       { 4, 0, 5 },
-
-       /* ARM L5: 1000 MHz */
-       { 4, 0, 4 },
-
-       /* ARM L6: 900 MHz */
-       { 3, 0, 4 },
-
-       /* ARM L7: 800 MHz */
-       { 3, 0, 3 },
-
-       /* ARM L8: 700 MHz */
-       { 3, 0, 3 },
-
-       /* ARM L9: 600 MHz */
-       { 3, 0, 2 },
-
-       /* ARM L10: 500 MHz */
-       { 3, 0, 2 },
-
-       /* ARM L11: 400 MHz */
-       { 3, 0, 1 },
-
-       /* ARM L12: 300 MHz */
-       { 3, 0, 1 },
-
-       /* ARM L13: 200 MHz */
-       { 3, 0, 0 },
-};
-
-static unsigned int exynos4x12_apll_pms_table[CPUFREQ_LEVEL_END] = {
-       /* APLL FOUT L0: 1500 MHz */
-       ((250 << 16) | (4 << 8) | (0x0)),
-
-       /* APLL FOUT L1: 1400 MHz */
-       ((175 << 16) | (3 << 8) | (0x0)),
-
-       /* APLL FOUT L2: 1300 MHz */
-       ((325 << 16) | (6 << 8) | (0x0)),
-
-       /* APLL FOUT L3: 1200 MHz */
-       ((200 << 16) | (4 << 8) | (0x0)),
-
-       /* APLL FOUT L4: 1100 MHz */
-       ((275 << 16) | (6 << 8) | (0x0)),
-
-       /* APLL FOUT L5: 1000 MHz */
-       ((125 << 16) | (3 << 8) | (0x0)),
-
-       /* APLL FOUT L6: 900 MHz */
-       ((150 << 16) | (4 << 8) | (0x0)),
-
-       /* APLL FOUT L7: 800 MHz */
-       ((100 << 16) | (3 << 8) | (0x0)),
-
-       /* APLL FOUT L8: 700 MHz */
-       ((175 << 16) | (3 << 8) | (0x1)),
-
-       /* APLL FOUT L9: 600 MHz */
-       ((200 << 16) | (4 << 8) | (0x1)),
-
-       /* APLL FOUT L10: 500 MHz */
-       ((125 << 16) | (3 << 8) | (0x1)),
-
-       /* APLL FOUT L11 400 MHz */
-       ((100 << 16) | (3 << 8) | (0x1)),
-
-       /* APLL FOUT L12: 300 MHz */
-       ((200 << 16) | (4 << 8) | (0x2)),
-
-       /* APLL FOUT L13: 200 MHz */
-       ((100 << 16) | (3 << 8) | (0x2)),
-};
-
-static const unsigned int asv_voltage_4x12[CPUFREQ_LEVEL_END] = {
-       1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500,
-       1000000,  987500,  975000,  950000,  925000,  900000,  900000
+       APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 7, 250, 4, 0),
+       APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 6, 175, 3, 0),
+       APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 6, 325, 6, 0),
+       APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 5, 200, 4, 0),
+       APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 0, 5, 275, 6, 0),
+       APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 0, 4, 125, 3, 0),
+       APLL_FREQ(900,  0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 4, 150, 4, 0),
+       APLL_FREQ(800,  0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 3, 100, 3, 0),
+       APLL_FREQ(700,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 3, 175, 3, 1),
+       APLL_FREQ(600,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 200, 4, 1),
+       APLL_FREQ(500,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 125, 3, 1),
+       APLL_FREQ(400,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 1, 100, 3, 1),
+       APLL_FREQ(300,  0, 2, 4, 0, 2, 1, 1, 0, 3, 0, 1, 200, 4, 2),
+       APLL_FREQ(200,  0, 1, 3, 0, 1, 1, 1, 0, 3, 0, 0, 100, 3, 2),
 };
 
 static void exynos4x12_set_clkdiv(unsigned int div_index)
@@ -306,7 +105,7 @@ static void exynos4x12_set_clkdiv(unsigned int div_index)
 
        /* Change Divider - CPU0 */
 
-       tmp = exynos4x12_clkdiv_table[div_index].clkdiv;
+       tmp = apll_freq_4x12[div_index].clk_div_cpu0;
 
        __raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
 
@@ -314,7 +113,7 @@ static void exynos4x12_set_clkdiv(unsigned int div_index)
                cpu_relax();
 
        /* Change Divider - CPU1 */
-       tmp = exynos4x12_clkdiv_table[div_index].clkdiv1;
+       tmp = apll_freq_4x12[div_index].clk_div_cpu1;
 
        __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
        if (soc_is_exynos4212())
@@ -341,14 +140,14 @@ static void exynos4x12_set_apll(unsigned int index)
        } while (tmp != 0x2);
 
        /* 2. Set APLL Lock time */
-       pdiv = ((exynos4x12_apll_pms_table[index] >> 8) & 0x3f);
+       pdiv = ((apll_freq_4x12[index].mps >> 8) & 0x3f);
 
        __raw_writel((pdiv * 250), EXYNOS4_APLL_LOCK);
 
        /* 3. Change PLL PMS values */
        tmp = __raw_readl(EXYNOS4_APLL_CON0);
        tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
-       tmp |= exynos4x12_apll_pms_table[index];
+       tmp |= apll_freq_4x12[index].mps;
        __raw_writel(tmp, EXYNOS4_APLL_CON0);
 
        /* 4. wait_lock_time */
@@ -367,10 +166,10 @@ static void exynos4x12_set_apll(unsigned int index)
        } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
 }
 
-bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index)
+static bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index)
 {
-       unsigned int old_pm = exynos4x12_apll_pms_table[old_index] >> 8;
-       unsigned int new_pm = exynos4x12_apll_pms_table[new_index] >> 8;
+       unsigned int old_pm = apll_freq_4x12[old_index].mps >> 8;
+       unsigned int new_pm = apll_freq_4x12[new_index].mps >> 8;
 
        return (old_pm == new_pm) ? 0 : 1;
 }
@@ -387,7 +186,7 @@ static void exynos4x12_set_frequency(unsigned int old_index,
                        /* 2. Change just s value in apll m,p,s value */
                        tmp = __raw_readl(EXYNOS4_APLL_CON0);
                        tmp &= ~(0x7 << 0);
-                       tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7);
+                       tmp |= apll_freq_4x12[new_index].mps & 0x7;
                        __raw_writel(tmp, EXYNOS4_APLL_CON0);
 
                } else {
@@ -402,7 +201,7 @@ static void exynos4x12_set_frequency(unsigned int old_index,
                        /* 1. Change just s value in apll m,p,s value */
                        tmp = __raw_readl(EXYNOS4_APLL_CON0);
                        tmp &= ~(0x7 << 0);
-                       tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7);
+                       tmp |= apll_freq_4x12[new_index].mps & 0x7;
                        __raw_writel(tmp, EXYNOS4_APLL_CON0);
                        /* 2. Change the system clock divider values */
                        exynos4x12_set_clkdiv(new_index);
@@ -416,27 +215,10 @@ static void exynos4x12_set_frequency(unsigned int old_index,
        }
 }
 
-static void __init set_volt_table(void)
-{
-       unsigned int i;
-
-       max_support_idx = L1;
-
-       /* Not supported */
-       exynos4x12_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID;
-
-       for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++)
-               exynos4x12_volt_table[i] = asv_voltage_4x12[i];
-}
-
 int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
 {
-       int i;
-       unsigned int tmp;
        unsigned long rate;
 
-       set_volt_table();
-
        cpu_clk = clk_get(NULL, "armclk");
        if (IS_ERR(cpu_clk))
                return PTR_ERR(cpu_clk);
@@ -455,66 +237,14 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
        if (IS_ERR(mout_apll))
                goto err_mout_apll;
 
-       for (i = L0; i <  CPUFREQ_LEVEL_END; i++) {
-
-               exynos4x12_clkdiv_table[i].index = i;
-
-               tmp = __raw_readl(EXYNOS4_CLKDIV_CPU);
-
-               tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK |
-                       EXYNOS4_CLKDIV_CPU0_COREM0_MASK |
-                       EXYNOS4_CLKDIV_CPU0_COREM1_MASK |
-                       EXYNOS4_CLKDIV_CPU0_PERIPH_MASK |
-                       EXYNOS4_CLKDIV_CPU0_ATB_MASK |
-                       EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK |
-                       EXYNOS4_CLKDIV_CPU0_APLL_MASK);
-
-               if (soc_is_exynos4212()) {
-                       tmp |= ((clkdiv_cpu0_4212[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) |
-                               (clkdiv_cpu0_4212[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) |
-                               (clkdiv_cpu0_4212[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) |
-                               (clkdiv_cpu0_4212[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) |
-                               (clkdiv_cpu0_4212[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) |
-                               (clkdiv_cpu0_4212[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) |
-                               (clkdiv_cpu0_4212[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT));
-               } else {
-                       tmp &= ~EXYNOS4_CLKDIV_CPU0_CORE2_MASK;
-
-                       tmp |= ((clkdiv_cpu0_4412[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) |
-                               (clkdiv_cpu0_4412[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) |
-                               (clkdiv_cpu0_4412[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) |
-                               (clkdiv_cpu0_4412[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) |
-                               (clkdiv_cpu0_4412[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) |
-                               (clkdiv_cpu0_4412[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) |
-                               (clkdiv_cpu0_4412[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT) |
-                               (clkdiv_cpu0_4412[i][7] << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT));
-               }
-
-               exynos4x12_clkdiv_table[i].clkdiv = tmp;
-
-               tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1);
-
-               if (soc_is_exynos4212()) {
-                       tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK |
-                               EXYNOS4_CLKDIV_CPU1_HPM_MASK);
-                       tmp |= ((clkdiv_cpu1_4212[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) |
-                               (clkdiv_cpu1_4212[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT));
-               } else {
-                       tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK |
-                               EXYNOS4_CLKDIV_CPU1_HPM_MASK |
-                               EXYNOS4_CLKDIV_CPU1_CORES_MASK);
-                       tmp |= ((clkdiv_cpu1_4412[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) |
-                               (clkdiv_cpu1_4412[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) |
-                               (clkdiv_cpu1_4412[i][2] << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT));
-               }
-               exynos4x12_clkdiv_table[i].clkdiv1 = tmp;
-       }
+       if (soc_is_exynos4212())
+               apll_freq_4x12 = apll_freq_4212;
+       else
+               apll_freq_4x12 = apll_freq_4412;
 
        info->mpll_freq_khz = rate;
-       info->pm_lock_idx = L5;
+       /* 800Mhz */
        info->pll_safe_idx = L7;
-       info->max_support_idx = max_support_idx;
-       info->min_support_idx = min_support_idx;
        info->cpu_clk = cpu_clk;
        info->volt_table = exynos4x12_volt_table;
        info->freq_table = exynos4x12_freq_table;
index e64c253..b934486 100644 (file)
 #include <mach/regs-clock.h>
 #include <mach/cpufreq.h>
 
-#define CPUFREQ_LEVEL_END      (L15 + 1)
-
-static int max_support_idx;
-static int min_support_idx = (CPUFREQ_LEVEL_END - 1);
 static struct clk *cpu_clk;
 static struct clk *moutcore;
 static struct clk *mout_mpll;
 static struct clk *mout_apll;
 
-struct cpufreq_clkdiv {
-       unsigned int    index;
-       unsigned int    clkdiv;
-       unsigned int    clkdiv1;
+static unsigned int exynos5250_volt_table[] = {
+       1300000, 1250000, 1225000, 1200000, 1150000,
+       1125000, 1100000, 1075000, 1050000, 1025000,
+       1012500, 1000000,  975000,  950000,  937500,
+       925000
 };
 
-static unsigned int exynos5250_volt_table[CPUFREQ_LEVEL_END];
-
 static struct cpufreq_frequency_table exynos5250_freq_table[] = {
        {L0, 1700 * 1000},
        {L1, 1600 * 1000},
@@ -47,8 +42,8 @@ static struct cpufreq_frequency_table exynos5250_freq_table[] = {
        {L5, 1200 * 1000},
        {L6, 1100 * 1000},
        {L7, 1000 * 1000},
-       {L8, 900 * 1000},
-       {L9, 800 * 1000},
+       {L8,  900 * 1000},
+       {L9,  800 * 1000},
        {L10, 700 * 1000},
        {L11, 600 * 1000},
        {L12, 500 * 1000},
@@ -58,78 +53,30 @@ static struct cpufreq_frequency_table exynos5250_freq_table[] = {
        {0, CPUFREQ_TABLE_END},
 };
 
-static struct cpufreq_clkdiv exynos5250_clkdiv_table[CPUFREQ_LEVEL_END];
-
-static unsigned int clkdiv_cpu0_5250[CPUFREQ_LEVEL_END][8] = {
+static struct apll_freq apll_freq_5250[] = {
        /*
-        * Clock divider value for following
-        * { ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG, APLL, ARM2 }
-        */
-       { 0, 3, 7, 7, 7, 3, 5, 0 },     /* 1700 MHz */
-       { 0, 3, 7, 7, 7, 1, 4, 0 },     /* 1600 MHz */
-       { 0, 2, 7, 7, 7, 1, 4, 0 },     /* 1500 MHz */
-       { 0, 2, 7, 7, 6, 1, 4, 0 },     /* 1400 MHz */
-       { 0, 2, 7, 7, 6, 1, 3, 0 },     /* 1300 MHz */
-       { 0, 2, 7, 7, 5, 1, 3, 0 },     /* 1200 MHz */
-       { 0, 3, 7, 7, 5, 1, 3, 0 },     /* 1100 MHz */
-       { 0, 1, 7, 7, 4, 1, 2, 0 },     /* 1000 MHz */
-       { 0, 1, 7, 7, 4, 1, 2, 0 },     /* 900 MHz */
-       { 0, 1, 7, 7, 4, 1, 2, 0 },     /* 800 MHz */
-       { 0, 1, 7, 7, 3, 1, 1, 0 },     /* 700 MHz */
-       { 0, 1, 7, 7, 3, 1, 1, 0 },     /* 600 MHz */
-       { 0, 1, 7, 7, 2, 1, 1, 0 },     /* 500 MHz */
-       { 0, 1, 7, 7, 2, 1, 1, 0 },     /* 400 MHz */
-       { 0, 1, 7, 7, 1, 1, 1, 0 },     /* 300 MHz */
-       { 0, 1, 7, 7, 1, 1, 1, 0 },     /* 200 MHz */
-};
-
-static unsigned int clkdiv_cpu1_5250[CPUFREQ_LEVEL_END][2] = {
-       /* Clock divider value for following
-        * { COPY, HPM }
+        * values:
+        * freq
+        * clock divider for ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG, APLL, ARM2
+        * clock divider for COPY, HPM, RESERVED
+        * PLL M, P, S
         */
-       { 0, 2 },       /* 1700 MHz */
-       { 0, 2 },       /* 1600 MHz */
-       { 0, 2 },       /* 1500 MHz */
-       { 0, 2 },       /* 1400 MHz */
-       { 0, 2 },       /* 1300 MHz */
-       { 0, 2 },       /* 1200 MHz */
-       { 0, 2 },       /* 1100 MHz */
-       { 0, 2 },       /* 1000 MHz */
-       { 0, 2 },       /* 900 MHz */
-       { 0, 2 },       /* 800 MHz */
-       { 0, 2 },       /* 700 MHz */
-       { 0, 2 },       /* 600 MHz */
-       { 0, 2 },       /* 500 MHz */
-       { 0, 2 },       /* 400 MHz */
-       { 0, 2 },       /* 300 MHz */
-       { 0, 2 },       /* 200 MHz */
-};
-
-static unsigned int exynos5_apll_pms_table[CPUFREQ_LEVEL_END] = {
-       ((425 << 16) | (6 << 8) | 0),   /* 1700 MHz */
-       ((200 << 16) | (3 << 8) | 0),   /* 1600 MHz */
-       ((250 << 16) | (4 << 8) | 0),   /* 1500 MHz */
-       ((175 << 16) | (3 << 8) | 0),   /* 1400 MHz */
-       ((325 << 16) | (6 << 8) | 0),   /* 1300 MHz */
-       ((200 << 16) | (4 << 8) | 0),   /* 1200 MHz */
-       ((275 << 16) | (6 << 8) | 0),   /* 1100 MHz */
-       ((125 << 16) | (3 << 8) | 0),   /* 1000 MHz */
-       ((150 << 16) | (4 << 8) | 0),   /* 900 MHz */
-       ((100 << 16) | (3 << 8) | 0),   /* 800 MHz */
-       ((175 << 16) | (3 << 8) | 1),   /* 700 MHz */
-       ((200 << 16) | (4 << 8) | 1),   /* 600 MHz */
-       ((125 << 16) | (3 << 8) | 1),   /* 500 MHz */
-       ((100 << 16) | (3 << 8) | 1),   /* 400 MHz */
-       ((200 << 16) | (4 << 8) | 2),   /* 300 MHz */
-       ((100 << 16) | (3 << 8) | 2),   /* 200 MHz */
-};
-
-/* ASV group voltage table */
-static const unsigned int asv_voltage_5250[CPUFREQ_LEVEL_END] = {
-       1300000, 1250000, 1225000, 1200000, 1150000,
-       1125000, 1100000, 1075000, 1050000, 1025000,
-       1012500, 1000000,  975000,  950000,  937500,
-       925000
+       APLL_FREQ(1700, 0, 3, 7, 7, 7, 3, 5, 0, 0, 2, 0, 425, 6, 0),
+       APLL_FREQ(1600, 0, 3, 7, 7, 7, 1, 4, 0, 0, 2, 0, 200, 3, 0),
+       APLL_FREQ(1500, 0, 2, 7, 7, 7, 1, 4, 0, 0, 2, 0, 250, 4, 0),
+       APLL_FREQ(1400, 0, 2, 7, 7, 6, 1, 4, 0, 0, 2, 0, 175, 3, 0),
+       APLL_FREQ(1300, 0, 2, 7, 7, 6, 1, 3, 0, 0, 2, 0, 325, 6, 0),
+       APLL_FREQ(1200, 0, 2, 7, 7, 5, 1, 3, 0, 0, 2, 0, 200, 4, 0),
+       APLL_FREQ(1100, 0, 3, 7, 7, 5, 1, 3, 0, 0, 2, 0, 275, 6, 0),
+       APLL_FREQ(1000, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 125, 3, 0),
+       APLL_FREQ(900,  0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 150, 4, 0),
+       APLL_FREQ(800,  0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 100, 3, 0),
+       APLL_FREQ(700,  0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 175, 3, 1),
+       APLL_FREQ(600,  0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 200, 4, 1),
+       APLL_FREQ(500,  0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 125, 3, 1),
+       APLL_FREQ(400,  0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 100, 3, 1),
+       APLL_FREQ(300,  0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 200, 4, 2),
+       APLL_FREQ(200,  0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 100, 3, 2),
 };
 
 static void set_clkdiv(unsigned int div_index)
@@ -138,7 +85,7 @@ static void set_clkdiv(unsigned int div_index)
 
        /* Change Divider - CPU0 */
 
-       tmp = exynos5250_clkdiv_table[div_index].clkdiv;
+       tmp = apll_freq_5250[div_index].clk_div_cpu0;
 
        __raw_writel(tmp, EXYNOS5_CLKDIV_CPU0);
 
@@ -146,7 +93,7 @@ static void set_clkdiv(unsigned int div_index)
                cpu_relax();
 
        /* Change Divider - CPU1 */
-       tmp = exynos5250_clkdiv_table[div_index].clkdiv1;
+       tmp = apll_freq_5250[div_index].clk_div_cpu1;
 
        __raw_writel(tmp, EXYNOS5_CLKDIV_CPU1);
 
@@ -169,14 +116,14 @@ static void set_apll(unsigned int new_index,
        } while (tmp != 0x2);
 
        /* 2. Set APLL Lock time */
-       pdiv = ((exynos5_apll_pms_table[new_index] >> 8) & 0x3f);
+       pdiv = ((apll_freq_5250[new_index].mps >> 8) & 0x3f);
 
        __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK);
 
        /* 3. Change PLL PMS values */
        tmp = __raw_readl(EXYNOS5_APLL_CON0);
        tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
-       tmp |= exynos5_apll_pms_table[new_index];
+       tmp |= apll_freq_5250[new_index].mps;
        __raw_writel(tmp, EXYNOS5_APLL_CON0);
 
        /* 4. wait_lock_time */
@@ -196,10 +143,10 @@ static void set_apll(unsigned int new_index,
 
 }
 
-bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index)
+static bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index)
 {
-       unsigned int old_pm = (exynos5_apll_pms_table[old_index] >> 8);
-       unsigned int new_pm = (exynos5_apll_pms_table[new_index] >> 8);
+       unsigned int old_pm = apll_freq_5250[old_index].mps >> 8;
+       unsigned int new_pm = apll_freq_5250[new_index].mps >> 8;
 
        return (old_pm == new_pm) ? 0 : 1;
 }
@@ -216,7 +163,7 @@ static void exynos5250_set_frequency(unsigned int old_index,
                        /* 2. Change just s value in apll m,p,s value */
                        tmp = __raw_readl(EXYNOS5_APLL_CON0);
                        tmp &= ~(0x7 << 0);
-                       tmp |= (exynos5_apll_pms_table[new_index] & 0x7);
+                       tmp |= apll_freq_5250[new_index].mps & 0x7;
                        __raw_writel(tmp, EXYNOS5_APLL_CON0);
 
                } else {
@@ -231,7 +178,7 @@ static void exynos5250_set_frequency(unsigned int old_index,
                        /* 1. Change just s value in apll m,p,s value */
                        tmp = __raw_readl(EXYNOS5_APLL_CON0);
                        tmp &= ~(0x7 << 0);
-                       tmp |= (exynos5_apll_pms_table[new_index] & 0x7);
+                       tmp |= apll_freq_5250[new_index].mps & 0x7;
                        __raw_writel(tmp, EXYNOS5_APLL_CON0);
                        /* 2. Change the system clock divider values */
                        set_clkdiv(new_index);
@@ -245,24 +192,10 @@ static void exynos5250_set_frequency(unsigned int old_index,
        }
 }
 
-static void __init set_volt_table(void)
-{
-       unsigned int i;
-
-       max_support_idx = L0;
-
-       for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++)
-               exynos5250_volt_table[i] = asv_voltage_5250[i];
-}
-
 int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
 {
-       int i;
-       unsigned int tmp;
        unsigned long rate;
 
-       set_volt_table();
-
        cpu_clk = clk_get(NULL, "armclk");
        if (IS_ERR(cpu_clk))
                return PTR_ERR(cpu_clk);
@@ -281,44 +214,9 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
        if (IS_ERR(mout_apll))
                goto err_mout_apll;
 
-       for (i = L0; i < CPUFREQ_LEVEL_END; i++) {
-
-               exynos5250_clkdiv_table[i].index = i;
-
-               tmp = __raw_readl(EXYNOS5_CLKDIV_CPU0);
-
-               tmp &= ~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) |
-                       (0x7 << 12) | (0x7 << 16) | (0x7 << 20) |
-                       (0x7 << 24) | (0x7 << 28));
-
-               tmp |= ((clkdiv_cpu0_5250[i][0] << 0) |
-                       (clkdiv_cpu0_5250[i][1] << 4) |
-                       (clkdiv_cpu0_5250[i][2] << 8) |
-                       (clkdiv_cpu0_5250[i][3] << 12) |
-                       (clkdiv_cpu0_5250[i][4] << 16) |
-                       (clkdiv_cpu0_5250[i][5] << 20) |
-                       (clkdiv_cpu0_5250[i][6] << 24) |
-                       (clkdiv_cpu0_5250[i][7] << 28));
-
-               exynos5250_clkdiv_table[i].clkdiv = tmp;
-
-               tmp = __raw_readl(EXYNOS5_CLKDIV_CPU1);
-
-               tmp &= ~((0x7 << 0) | (0x7 << 4));
-
-               tmp |= ((clkdiv_cpu1_5250[i][0] << 0) |
-                       (clkdiv_cpu1_5250[i][1] << 4));
-
-               exynos5250_clkdiv_table[i].clkdiv1 = tmp;
-       }
-
        info->mpll_freq_khz = rate;
-       /* 1000Mhz */
-       info->pm_lock_idx = L7;
        /* 800Mhz */
        info->pll_safe_idx = L9;
-       info->max_support_idx = max_support_idx;
-       info->min_support_idx = min_support_idx;
        info->cpu_clk = cpu_clk;
        info->volt_table = exynos5250_volt_table;
        info->freq_table = exynos5250_freq_table;
index 49cda25..d7a7966 100644 (file)
@@ -63,9 +63,6 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
        pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n",
                                        policy->min, policy->max, policy->cpu);
 
-       if (!cpu_online(policy->cpu))
-               return -EINVAL;
-
        cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
                                     policy->cpuinfo.max_freq);
 
@@ -121,9 +118,6 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
                break;
        }
 
-       if (!cpu_online(policy->cpu))
-               return -EINVAL;
-
        for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
                unsigned int freq = table[i].frequency;
                if (freq == CPUFREQ_ENTRY_INVALID)
@@ -227,6 +221,15 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu)
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
 
+void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy)
+{
+       pr_debug("Updating show_table for new_cpu %u from last_cpu %u\n",
+                       policy->cpu, policy->last_cpu);
+       per_cpu(cpufreq_show_table, policy->cpu) = per_cpu(cpufreq_show_table,
+                       policy->last_cpu);
+       per_cpu(cpufreq_show_table, policy->last_cpu) = NULL;
+}
+
 struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
 {
        return per_cpu(cpufreq_show_table, cpu);
diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c
new file mode 100644 (file)
index 0000000..66e3a71
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 Calxeda, Inc.
+ *
+ * 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.
+ *
+ * This driver provides the clk notifier callbacks that are used when
+ * the cpufreq-cpu0 driver changes to frequency to alert the highbank
+ * EnergyCore Management Engine (ECME) about the need to change
+ * voltage. The ECME interfaces with the actual voltage regulators.
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/mailbox.h>
+#include <linux/platform_device.h>
+
+#define HB_CPUFREQ_CHANGE_NOTE 0x80000001
+#define HB_CPUFREQ_IPC_LEN     7
+#define HB_CPUFREQ_VOLT_RETRIES        15
+
+static int hb_voltage_change(unsigned int freq)
+{
+       int i;
+       u32 msg[HB_CPUFREQ_IPC_LEN];
+
+       msg[0] = HB_CPUFREQ_CHANGE_NOTE;
+       msg[1] = freq / 1000000;
+       for (i = 2; i < HB_CPUFREQ_IPC_LEN; i++)
+               msg[i] = 0;
+
+       return pl320_ipc_transmit(msg);
+}
+
+static int hb_cpufreq_clk_notify(struct notifier_block *nb,
+                               unsigned long action, void *hclk)
+{
+       struct clk_notifier_data *clk_data = hclk;
+       int i = 0;
+
+       if (action == PRE_RATE_CHANGE) {
+               if (clk_data->new_rate > clk_data->old_rate)
+                       while (hb_voltage_change(clk_data->new_rate))
+                               if (i++ > HB_CPUFREQ_VOLT_RETRIES)
+                                       return NOTIFY_BAD;
+       } else if (action == POST_RATE_CHANGE) {
+               if (clk_data->new_rate < clk_data->old_rate)
+                       while (hb_voltage_change(clk_data->new_rate))
+                               if (i++ > HB_CPUFREQ_VOLT_RETRIES)
+                                       return NOTIFY_BAD;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block hb_cpufreq_clk_nb = {
+       .notifier_call = hb_cpufreq_clk_notify,
+};
+
+static int hb_cpufreq_driver_init(void)
+{
+       struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
+       struct device *cpu_dev;
+       struct clk *cpu_clk;
+       struct device_node *np;
+       int ret;
+
+       if (!of_machine_is_compatible("calxeda,highbank"))
+               return -ENODEV;
+
+       for_each_child_of_node(of_find_node_by_path("/cpus"), np)
+               if (of_get_property(np, "operating-points", NULL))
+                       break;
+
+       if (!np) {
+               pr_err("failed to find highbank cpufreq node\n");
+               return -ENOENT;
+       }
+
+       cpu_dev = get_cpu_device(0);
+       if (!cpu_dev) {
+               pr_err("failed to get highbank cpufreq device\n");
+               ret = -ENODEV;
+               goto out_put_node;
+       }
+
+       cpu_dev->of_node = np;
+
+       cpu_clk = clk_get(cpu_dev, NULL);
+       if (IS_ERR(cpu_clk)) {
+               ret = PTR_ERR(cpu_clk);
+               pr_err("failed to get cpu0 clock: %d\n", ret);
+               goto out_put_node;
+       }
+
+       ret = clk_notifier_register(cpu_clk, &hb_cpufreq_clk_nb);
+       if (ret) {
+               pr_err("failed to register clk notifier: %d\n", ret);
+               goto out_put_node;
+       }
+
+       /* Instantiate cpufreq-cpu0 */
+       platform_device_register_full(&devinfo);
+
+out_put_node:
+       of_node_put(np);
+       return ret;
+}
+module_init(hb_cpufreq_driver_init);
+
+MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@calxeda.com>");
+MODULE_DESCRIPTION("Calxeda Highbank cpufreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
new file mode 100644 (file)
index 0000000..d6b6ef3
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/opp.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#define PU_SOC_VOLTAGE_NORMAL  1250000
+#define PU_SOC_VOLTAGE_HIGH    1275000
+#define FREQ_1P2_GHZ           1200000000
+
+static struct regulator *arm_reg;
+static struct regulator *pu_reg;
+static struct regulator *soc_reg;
+
+static struct clk *arm_clk;
+static struct clk *pll1_sys_clk;
+static struct clk *pll1_sw_clk;
+static struct clk *step_clk;
+static struct clk *pll2_pfd2_396m_clk;
+
+static struct device *cpu_dev;
+static struct cpufreq_frequency_table *freq_table;
+static unsigned int transition_latency;
+
+static int imx6q_verify_speed(struct cpufreq_policy *policy)
+{
+       return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int imx6q_get_speed(unsigned int cpu)
+{
+       return clk_get_rate(arm_clk) / 1000;
+}
+
+static int imx6q_set_target(struct cpufreq_policy *policy,
+                           unsigned int target_freq, unsigned int relation)
+{
+       struct cpufreq_freqs freqs;
+       struct opp *opp;
+       unsigned long freq_hz, volt, volt_old;
+       unsigned int index, cpu;
+       int ret;
+
+       ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+                                            relation, &index);
+       if (ret) {
+               dev_err(cpu_dev, "failed to match target frequency %d: %d\n",
+                       target_freq, ret);
+               return ret;
+       }
+
+       freqs.new = freq_table[index].frequency;
+       freq_hz = freqs.new * 1000;
+       freqs.old = clk_get_rate(arm_clk) / 1000;
+
+       if (freqs.old == freqs.new)
+               return 0;
+
+       for_each_online_cpu(cpu) {
+               freqs.cpu = cpu;
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       }
+
+       rcu_read_lock();
+       opp = opp_find_freq_ceil(cpu_dev, &freq_hz);
+       if (IS_ERR(opp)) {
+               rcu_read_unlock();
+               dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
+               return PTR_ERR(opp);
+       }
+
+       volt = opp_get_voltage(opp);
+       rcu_read_unlock();
+       volt_old = regulator_get_voltage(arm_reg);
+
+       dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
+               freqs.old / 1000, volt_old / 1000,
+               freqs.new / 1000, volt / 1000);
+
+       /* scaling up?  scale voltage before frequency */
+       if (freqs.new > freqs.old) {
+               ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+               if (ret) {
+                       dev_err(cpu_dev,
+                               "failed to scale vddarm up: %d\n", ret);
+                       return ret;
+               }
+
+               /*
+                * Need to increase vddpu and vddsoc for safety
+                * if we are about to run at 1.2 GHz.
+                */
+               if (freqs.new == FREQ_1P2_GHZ / 1000) {
+                       regulator_set_voltage_tol(pu_reg,
+                                       PU_SOC_VOLTAGE_HIGH, 0);
+                       regulator_set_voltage_tol(soc_reg,
+                                       PU_SOC_VOLTAGE_HIGH, 0);
+               }
+       }
+
+       /*
+        * The setpoints are selected per PLL/PDF frequencies, so we need to
+        * reprogram PLL for frequency scaling.  The procedure of reprogramming
+        * PLL1 is as below.
+        *
+        *  - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
+        *  - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
+        *  - Disable pll2_pfd2_396m_clk
+        */
+       clk_prepare_enable(pll2_pfd2_396m_clk);
+       clk_set_parent(step_clk, pll2_pfd2_396m_clk);
+       clk_set_parent(pll1_sw_clk, step_clk);
+       if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
+               clk_set_rate(pll1_sys_clk, freqs.new * 1000);
+               /*
+                * If we are leaving 396 MHz set-point, we need to enable
+                * pll1_sys_clk and disable pll2_pfd2_396m_clk to keep
+                * their use count correct.
+                */
+               if (freqs.old * 1000 <= clk_get_rate(pll2_pfd2_396m_clk)) {
+                       clk_prepare_enable(pll1_sys_clk);
+                       clk_disable_unprepare(pll2_pfd2_396m_clk);
+               }
+               clk_set_parent(pll1_sw_clk, pll1_sys_clk);
+               clk_disable_unprepare(pll2_pfd2_396m_clk);
+       } else {
+               /*
+                * Disable pll1_sys_clk if pll2_pfd2_396m_clk is sufficient
+                * to provide the frequency.
+                */
+               clk_disable_unprepare(pll1_sys_clk);
+       }
+
+       /* Ensure the arm clock divider is what we expect */
+       ret = clk_set_rate(arm_clk, freqs.new * 1000);
+       if (ret) {
+               dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
+               regulator_set_voltage_tol(arm_reg, volt_old, 0);
+               return ret;
+       }
+
+       /* scaling down?  scale voltage after frequency */
+       if (freqs.new < freqs.old) {
+               ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+               if (ret)
+                       dev_warn(cpu_dev,
+                                "failed to scale vddarm down: %d\n", ret);
+
+               if (freqs.old == FREQ_1P2_GHZ / 1000) {
+                       regulator_set_voltage_tol(pu_reg,
+                                       PU_SOC_VOLTAGE_NORMAL, 0);
+                       regulator_set_voltage_tol(soc_reg,
+                                       PU_SOC_VOLTAGE_NORMAL, 0);
+               }
+       }
+
+       for_each_online_cpu(cpu) {
+               freqs.cpu = cpu;
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       }
+
+       return 0;
+}
+
+static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
+{
+       int ret;
+
+       ret = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+       if (ret) {
+               dev_err(cpu_dev, "invalid frequency table: %d\n", ret);
+               return ret;
+       }
+
+       policy->cpuinfo.transition_latency = transition_latency;
+       policy->cur = clk_get_rate(arm_clk) / 1000;
+       cpumask_setall(policy->cpus);
+       cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
+       return 0;
+}
+
+static int imx6q_cpufreq_exit(struct cpufreq_policy *policy)
+{
+       cpufreq_frequency_table_put_attr(policy->cpu);
+       return 0;
+}
+
+static struct freq_attr *imx6q_cpufreq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
+static struct cpufreq_driver imx6q_cpufreq_driver = {
+       .verify = imx6q_verify_speed,
+       .target = imx6q_set_target,
+       .get = imx6q_get_speed,
+       .init = imx6q_cpufreq_init,
+       .exit = imx6q_cpufreq_exit,
+       .name = "imx6q-cpufreq",
+       .attr = imx6q_cpufreq_attr,
+};
+
+static int imx6q_cpufreq_probe(struct platform_device *pdev)
+{
+       struct device_node *np;
+       struct opp *opp;
+       unsigned long min_volt, max_volt;
+       int num, ret;
+
+       cpu_dev = &pdev->dev;
+
+       np = of_find_node_by_path("/cpus/cpu@0");
+       if (!np) {
+               dev_err(cpu_dev, "failed to find cpu0 node\n");
+               return -ENOENT;
+       }
+
+       cpu_dev->of_node = np;
+
+       arm_clk = devm_clk_get(cpu_dev, "arm");
+       pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
+       pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
+       step_clk = devm_clk_get(cpu_dev, "step");
+       pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
+       if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
+           IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
+               dev_err(cpu_dev, "failed to get clocks\n");
+               ret = -ENOENT;
+               goto put_node;
+       }
+
+       arm_reg = devm_regulator_get(cpu_dev, "arm");
+       pu_reg = devm_regulator_get(cpu_dev, "pu");
+       soc_reg = devm_regulator_get(cpu_dev, "soc");
+       if (!arm_reg || !pu_reg || !soc_reg) {
+               dev_err(cpu_dev, "failed to get regulators\n");
+               ret = -ENOENT;
+               goto put_node;
+       }
+
+       /* We expect an OPP table supplied by platform */
+       num = opp_get_opp_count(cpu_dev);
+       if (num < 0) {
+               ret = num;
+               dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
+               goto put_node;
+       }
+
+       ret = opp_init_cpufreq_table(cpu_dev, &freq_table);
+       if (ret) {
+               dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+               goto put_node;
+       }
+
+       if (of_property_read_u32(np, "clock-latency", &transition_latency))
+               transition_latency = CPUFREQ_ETERNAL;
+
+       /*
+        * OPP is maintained in order of increasing frequency, and
+        * freq_table initialised from OPP is therefore sorted in the
+        * same order.
+        */
+       rcu_read_lock();
+       opp = opp_find_freq_exact(cpu_dev,
+                                 freq_table[0].frequency * 1000, true);
+       min_volt = opp_get_voltage(opp);
+       opp = opp_find_freq_exact(cpu_dev,
+                                 freq_table[--num].frequency * 1000, true);
+       max_volt = opp_get_voltage(opp);
+       rcu_read_unlock();
+       ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
+       if (ret > 0)
+               transition_latency += ret * 1000;
+
+       /* Count vddpu and vddsoc latency in for 1.2 GHz support */
+       if (freq_table[num].frequency == FREQ_1P2_GHZ / 1000) {
+               ret = regulator_set_voltage_time(pu_reg, PU_SOC_VOLTAGE_NORMAL,
+                                                PU_SOC_VOLTAGE_HIGH);
+               if (ret > 0)
+                       transition_latency += ret * 1000;
+               ret = regulator_set_voltage_time(soc_reg, PU_SOC_VOLTAGE_NORMAL,
+                                                PU_SOC_VOLTAGE_HIGH);
+               if (ret > 0)
+                       transition_latency += ret * 1000;
+       }
+
+       ret = cpufreq_register_driver(&imx6q_cpufreq_driver);
+       if (ret) {
+               dev_err(cpu_dev, "failed register driver: %d\n", ret);
+               goto free_freq_table;
+       }
+
+       of_node_put(np);
+       return 0;
+
+free_freq_table:
+       opp_free_cpufreq_table(cpu_dev, &freq_table);
+put_node:
+       of_node_put(np);
+       return ret;
+}
+
+static int imx6q_cpufreq_remove(struct platform_device *pdev)
+{
+       cpufreq_unregister_driver(&imx6q_cpufreq_driver);
+       opp_free_cpufreq_table(cpu_dev, &freq_table);
+
+       return 0;
+}
+
+static struct platform_driver imx6q_cpufreq_platdrv = {
+       .driver = {
+               .name   = "imx6q-cpufreq",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = imx6q_cpufreq_probe,
+       .remove         = imx6q_cpufreq_remove,
+};
+module_platform_driver(imx6q_cpufreq_platdrv);
+
+MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
+MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
new file mode 100644 (file)
index 0000000..096fde0
--- /dev/null
@@ -0,0 +1,823 @@
+/*
+ * cpufreq_snb.c: Native P state management for Intel processors
+ *
+ * (C) Copyright 2012 Intel Corporation
+ * Author: Dirk Brandewie <dirk.j.brandewie@intel.com>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <trace/events/power.h>
+
+#include <asm/div64.h>
+#include <asm/msr.h>
+#include <asm/cpu_device_id.h>
+
+#define SAMPLE_COUNT           3
+
+#define FRAC_BITS 8
+#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
+#define fp_toint(X) ((X) >> FRAC_BITS)
+
+static inline int32_t mul_fp(int32_t x, int32_t y)
+{
+       return ((int64_t)x * (int64_t)y) >> FRAC_BITS;
+}
+
+static inline int32_t div_fp(int32_t x, int32_t y)
+{
+       return div_s64((int64_t)x << FRAC_BITS, (int64_t)y);
+}
+
+struct sample {
+       ktime_t start_time;
+       ktime_t end_time;
+       int core_pct_busy;
+       int pstate_pct_busy;
+       u64 duration_us;
+       u64 idletime_us;
+       u64 aperf;
+       u64 mperf;
+       int freq;
+};
+
+struct pstate_data {
+       int     current_pstate;
+       int     min_pstate;
+       int     max_pstate;
+       int     turbo_pstate;
+};
+
+struct _pid {
+       int setpoint;
+       int32_t integral;
+       int32_t p_gain;
+       int32_t i_gain;
+       int32_t d_gain;
+       int deadband;
+       int last_err;
+};
+
+struct cpudata {
+       int cpu;
+
+       char name[64];
+
+       struct timer_list timer;
+
+       struct pstate_adjust_policy *pstate_policy;
+       struct pstate_data pstate;
+       struct _pid pid;
+       struct _pid idle_pid;
+
+       int min_pstate_count;
+       int idle_mode;
+
+       ktime_t prev_sample;
+       u64     prev_idle_time_us;
+       u64     prev_aperf;
+       u64     prev_mperf;
+       int     sample_ptr;
+       struct sample samples[SAMPLE_COUNT];
+};
+
+static struct cpudata **all_cpu_data;
+struct pstate_adjust_policy {
+       int sample_rate_ms;
+       int deadband;
+       int setpoint;
+       int p_gain_pct;
+       int d_gain_pct;
+       int i_gain_pct;
+};
+
+static struct pstate_adjust_policy default_policy = {
+       .sample_rate_ms = 10,
+       .deadband = 0,
+       .setpoint = 109,
+       .p_gain_pct = 17,
+       .d_gain_pct = 0,
+       .i_gain_pct = 4,
+};
+
+struct perf_limits {
+       int no_turbo;
+       int max_perf_pct;
+       int min_perf_pct;
+       int32_t max_perf;
+       int32_t min_perf;
+};
+
+static struct perf_limits limits = {
+       .no_turbo = 0,
+       .max_perf_pct = 100,
+       .max_perf = int_tofp(1),
+       .min_perf_pct = 0,
+       .min_perf = 0,
+};
+
+static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
+                       int deadband, int integral) {
+       pid->setpoint = setpoint;
+       pid->deadband  = deadband;
+       pid->integral  = int_tofp(integral);
+       pid->last_err  = setpoint - busy;
+}
+
+static inline void pid_p_gain_set(struct _pid *pid, int percent)
+{
+       pid->p_gain = div_fp(int_tofp(percent), int_tofp(100));
+}
+
+static inline void pid_i_gain_set(struct _pid *pid, int percent)
+{
+       pid->i_gain = div_fp(int_tofp(percent), int_tofp(100));
+}
+
+static inline void pid_d_gain_set(struct _pid *pid, int percent)
+{
+
+       pid->d_gain = div_fp(int_tofp(percent), int_tofp(100));
+}
+
+static signed int pid_calc(struct _pid *pid, int busy)
+{
+       signed int err, result;
+       int32_t pterm, dterm, fp_error;
+       int32_t integral_limit;
+
+       err = pid->setpoint - busy;
+       fp_error = int_tofp(err);
+
+       if (abs(err) <= pid->deadband)
+               return 0;
+
+       pterm = mul_fp(pid->p_gain, fp_error);
+
+       pid->integral += fp_error;
+
+       /* limit the integral term */
+       integral_limit = int_tofp(30);
+       if (pid->integral > integral_limit)
+               pid->integral = integral_limit;
+       if (pid->integral < -integral_limit)
+               pid->integral = -integral_limit;
+
+       dterm = mul_fp(pid->d_gain, (err - pid->last_err));
+       pid->last_err = err;
+
+       result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm;
+
+       return (signed int)fp_toint(result);
+}
+
+static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu)
+{
+       pid_p_gain_set(&cpu->pid, cpu->pstate_policy->p_gain_pct);
+       pid_d_gain_set(&cpu->pid, cpu->pstate_policy->d_gain_pct);
+       pid_i_gain_set(&cpu->pid, cpu->pstate_policy->i_gain_pct);
+
+       pid_reset(&cpu->pid,
+               cpu->pstate_policy->setpoint,
+               100,
+               cpu->pstate_policy->deadband,
+               0);
+}
+
+static inline void intel_pstate_idle_pid_reset(struct cpudata *cpu)
+{
+       pid_p_gain_set(&cpu->idle_pid, cpu->pstate_policy->p_gain_pct);
+       pid_d_gain_set(&cpu->idle_pid, cpu->pstate_policy->d_gain_pct);
+       pid_i_gain_set(&cpu->idle_pid, cpu->pstate_policy->i_gain_pct);
+
+       pid_reset(&cpu->idle_pid,
+               75,
+               50,
+               cpu->pstate_policy->deadband,
+               0);
+}
+
+static inline void intel_pstate_reset_all_pid(void)
+{
+       unsigned int cpu;
+       for_each_online_cpu(cpu) {
+               if (all_cpu_data[cpu])
+                       intel_pstate_busy_pid_reset(all_cpu_data[cpu]);
+       }
+}
+
+/************************** debugfs begin ************************/
+static int pid_param_set(void *data, u64 val)
+{
+       *(u32 *)data = val;
+       intel_pstate_reset_all_pid();
+       return 0;
+}
+static int pid_param_get(void *data, u64 *val)
+{
+       *val = *(u32 *)data;
+       return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_pid_param, pid_param_get,
+                       pid_param_set, "%llu\n");
+
+struct pid_param {
+       char *name;
+       void *value;
+};
+
+static struct pid_param pid_files[] = {
+       {"sample_rate_ms", &default_policy.sample_rate_ms},
+       {"d_gain_pct", &default_policy.d_gain_pct},
+       {"i_gain_pct", &default_policy.i_gain_pct},
+       {"deadband", &default_policy.deadband},
+       {"setpoint", &default_policy.setpoint},
+       {"p_gain_pct", &default_policy.p_gain_pct},
+       {NULL, NULL}
+};
+
+static struct dentry *debugfs_parent;
+static void intel_pstate_debug_expose_params(void)
+{
+       int i = 0;
+
+       debugfs_parent = debugfs_create_dir("pstate_snb", NULL);
+       if (IS_ERR_OR_NULL(debugfs_parent))
+               return;
+       while (pid_files[i].name) {
+               debugfs_create_file(pid_files[i].name, 0660,
+                               debugfs_parent, pid_files[i].value,
+                               &fops_pid_param);
+               i++;
+       }
+}
+
+/************************** debugfs end ************************/
+
+/************************** sysfs begin ************************/
+#define show_one(file_name, object)                                    \
+       static ssize_t show_##file_name                                 \
+       (struct kobject *kobj, struct attribute *attr, char *buf)       \
+       {                                                               \
+               return sprintf(buf, "%u\n", limits.object);             \
+       }
+
+static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
+                               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+       ret = sscanf(buf, "%u", &input);
+       if (ret != 1)
+               return -EINVAL;
+       limits.no_turbo = clamp_t(int, input, 0 , 1);
+
+       return count;
+}
+
+static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
+                               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+       ret = sscanf(buf, "%u", &input);
+       if (ret != 1)
+               return -EINVAL;
+
+       limits.max_perf_pct = clamp_t(int, input, 0 , 100);
+       limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
+       return count;
+}
+
+static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
+                               const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+       ret = sscanf(buf, "%u", &input);
+       if (ret != 1)
+               return -EINVAL;
+       limits.min_perf_pct = clamp_t(int, input, 0 , 100);
+       limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
+
+       return count;
+}
+
+show_one(no_turbo, no_turbo);
+show_one(max_perf_pct, max_perf_pct);
+show_one(min_perf_pct, min_perf_pct);
+
+define_one_global_rw(no_turbo);
+define_one_global_rw(max_perf_pct);
+define_one_global_rw(min_perf_pct);
+
+static struct attribute *intel_pstate_attributes[] = {
+       &no_turbo.attr,
+       &max_perf_pct.attr,
+       &min_perf_pct.attr,
+       NULL
+};
+
+static struct attribute_group intel_pstate_attr_group = {
+       .attrs = intel_pstate_attributes,
+};
+static struct kobject *intel_pstate_kobject;
+
+static void intel_pstate_sysfs_expose_params(void)
+{
+       int rc;
+
+       intel_pstate_kobject = kobject_create_and_add("intel_pstate",
+                                               &cpu_subsys.dev_root->kobj);
+       BUG_ON(!intel_pstate_kobject);
+       rc = sysfs_create_group(intel_pstate_kobject,
+                               &intel_pstate_attr_group);
+       BUG_ON(rc);
+}
+
+/************************** sysfs end ************************/
+
+static int intel_pstate_min_pstate(void)
+{
+       u64 value;
+       rdmsrl(0xCE, value);
+       return (value >> 40) & 0xFF;
+}
+
+static int intel_pstate_max_pstate(void)
+{
+       u64 value;
+       rdmsrl(0xCE, value);
+       return (value >> 8) & 0xFF;
+}
+
+static int intel_pstate_turbo_pstate(void)
+{
+       u64 value;
+       int nont, ret;
+       rdmsrl(0x1AD, value);
+       nont = intel_pstate_max_pstate();
+       ret = ((value) & 255);
+       if (ret <= nont)
+               ret = nont;
+       return ret;
+}
+
+static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
+{
+       int max_perf = cpu->pstate.turbo_pstate;
+       int min_perf;
+       if (limits.no_turbo)
+               max_perf = cpu->pstate.max_pstate;
+
+       max_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf));
+       *max = clamp_t(int, max_perf,
+                       cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
+
+       min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
+       *min = clamp_t(int, min_perf,
+                       cpu->pstate.min_pstate, max_perf);
+}
+
+static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
+{
+       int max_perf, min_perf;
+
+       intel_pstate_get_min_max(cpu, &min_perf, &max_perf);
+
+       pstate = clamp_t(int, pstate, min_perf, max_perf);
+
+       if (pstate == cpu->pstate.current_pstate)
+               return;
+
+#ifndef MODULE
+       trace_cpu_frequency(pstate * 100000, cpu->cpu);
+#endif
+       cpu->pstate.current_pstate = pstate;
+       wrmsrl(MSR_IA32_PERF_CTL, pstate << 8);
+
+}
+
+static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
+{
+       int target;
+       target = cpu->pstate.current_pstate + steps;
+
+       intel_pstate_set_pstate(cpu, target);
+}
+
+static inline void intel_pstate_pstate_decrease(struct cpudata *cpu, int steps)
+{
+       int target;
+       target = cpu->pstate.current_pstate - steps;
+       intel_pstate_set_pstate(cpu, target);
+}
+
+static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+{
+       sprintf(cpu->name, "Intel 2nd generation core");
+
+       cpu->pstate.min_pstate = intel_pstate_min_pstate();
+       cpu->pstate.max_pstate = intel_pstate_max_pstate();
+       cpu->pstate.turbo_pstate = intel_pstate_turbo_pstate();
+
+       /*
+        * goto max pstate so we don't slow up boot if we are built-in if we are
+        * a module we will take care of it during normal operation
+        */
+       intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
+}
+
+static inline void intel_pstate_calc_busy(struct cpudata *cpu,
+                                       struct sample *sample)
+{
+       u64 core_pct;
+       sample->pstate_pct_busy = 100 - div64_u64(
+                                       sample->idletime_us * 100,
+                                       sample->duration_us);
+       core_pct = div64_u64(sample->aperf * 100, sample->mperf);
+       sample->freq = cpu->pstate.turbo_pstate * core_pct * 1000;
+
+       sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct),
+                                       100);
+}
+
+static inline void intel_pstate_sample(struct cpudata *cpu)
+{
+       ktime_t now;
+       u64 idle_time_us;
+       u64 aperf, mperf;
+
+       now = ktime_get();
+       idle_time_us = get_cpu_idle_time_us(cpu->cpu, NULL);
+
+       rdmsrl(MSR_IA32_APERF, aperf);
+       rdmsrl(MSR_IA32_MPERF, mperf);
+       /* for the first sample, don't actually record a sample, just
+        * set the baseline */
+       if (cpu->prev_idle_time_us > 0) {
+               cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
+               cpu->samples[cpu->sample_ptr].start_time = cpu->prev_sample;
+               cpu->samples[cpu->sample_ptr].end_time = now;
+               cpu->samples[cpu->sample_ptr].duration_us =
+                       ktime_us_delta(now, cpu->prev_sample);
+               cpu->samples[cpu->sample_ptr].idletime_us =
+                       idle_time_us - cpu->prev_idle_time_us;
+
+               cpu->samples[cpu->sample_ptr].aperf = aperf;
+               cpu->samples[cpu->sample_ptr].mperf = mperf;
+               cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
+               cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
+
+               intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);
+       }
+
+       cpu->prev_sample = now;
+       cpu->prev_idle_time_us = idle_time_us;
+       cpu->prev_aperf = aperf;
+       cpu->prev_mperf = mperf;
+}
+
+static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
+{
+       int sample_time, delay;
+
+       sample_time = cpu->pstate_policy->sample_rate_ms;
+       delay = msecs_to_jiffies(sample_time);
+       delay -= jiffies % delay;
+       mod_timer_pinned(&cpu->timer, jiffies + delay);
+}
+
+static inline void intel_pstate_idle_mode(struct cpudata *cpu)
+{
+       cpu->idle_mode = 1;
+}
+
+static inline void intel_pstate_normal_mode(struct cpudata *cpu)
+{
+       cpu->idle_mode = 0;
+}
+
+static inline int intel_pstate_get_scaled_busy(struct cpudata *cpu)
+{
+       int32_t busy_scaled;
+       int32_t core_busy, turbo_pstate, current_pstate;
+
+       core_busy = int_tofp(cpu->samples[cpu->sample_ptr].core_pct_busy);
+       turbo_pstate = int_tofp(cpu->pstate.turbo_pstate);
+       current_pstate = int_tofp(cpu->pstate.current_pstate);
+       busy_scaled = mul_fp(core_busy, div_fp(turbo_pstate, current_pstate));
+
+       return fp_toint(busy_scaled);
+}
+
+static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
+{
+       int busy_scaled;
+       struct _pid *pid;
+       signed int ctl = 0;
+       int steps;
+
+       pid = &cpu->pid;
+       busy_scaled = intel_pstate_get_scaled_busy(cpu);
+
+       ctl = pid_calc(pid, busy_scaled);
+
+       steps = abs(ctl);
+       if (ctl < 0)
+               intel_pstate_pstate_increase(cpu, steps);
+       else
+               intel_pstate_pstate_decrease(cpu, steps);
+}
+
+static inline void intel_pstate_adjust_idle_pstate(struct cpudata *cpu)
+{
+       int busy_scaled;
+       struct _pid *pid;
+       int ctl = 0;
+       int steps;
+
+       pid = &cpu->idle_pid;
+
+       busy_scaled = intel_pstate_get_scaled_busy(cpu);
+
+       ctl = pid_calc(pid, 100 - busy_scaled);
+
+       steps = abs(ctl);
+       if (ctl < 0)
+               intel_pstate_pstate_decrease(cpu, steps);
+       else
+               intel_pstate_pstate_increase(cpu, steps);
+
+       if (cpu->pstate.current_pstate == cpu->pstate.min_pstate)
+               intel_pstate_normal_mode(cpu);
+}
+
+static void intel_pstate_timer_func(unsigned long __data)
+{
+       struct cpudata *cpu = (struct cpudata *) __data;
+
+       intel_pstate_sample(cpu);
+
+       if (!cpu->idle_mode)
+               intel_pstate_adjust_busy_pstate(cpu);
+       else
+               intel_pstate_adjust_idle_pstate(cpu);
+
+#if defined(XPERF_FIX)
+       if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) {
+               cpu->min_pstate_count++;
+               if (!(cpu->min_pstate_count % 5)) {
+                       intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
+                       intel_pstate_idle_mode(cpu);
+               }
+       } else
+               cpu->min_pstate_count = 0;
+#endif
+       intel_pstate_set_sample_time(cpu);
+}
+
+#define ICPU(model, policy) \
+       { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy }
+
+static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
+       ICPU(0x2a, default_policy),
+       ICPU(0x2d, default_policy),
+       {}
+};
+MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
+
+static int intel_pstate_init_cpu(unsigned int cpunum)
+{
+
+       const struct x86_cpu_id *id;
+       struct cpudata *cpu;
+
+       id = x86_match_cpu(intel_pstate_cpu_ids);
+       if (!id)
+               return -ENODEV;
+
+       all_cpu_data[cpunum] = kzalloc(sizeof(struct cpudata), GFP_KERNEL);
+       if (!all_cpu_data[cpunum])
+               return -ENOMEM;
+
+       cpu = all_cpu_data[cpunum];
+
+       intel_pstate_get_cpu_pstates(cpu);
+
+       cpu->cpu = cpunum;
+       cpu->pstate_policy =
+               (struct pstate_adjust_policy *)id->driver_data;
+       init_timer_deferrable(&cpu->timer);
+       cpu->timer.function = intel_pstate_timer_func;
+       cpu->timer.data =
+               (unsigned long)cpu;
+       cpu->timer.expires = jiffies + HZ/100;
+       intel_pstate_busy_pid_reset(cpu);
+       intel_pstate_idle_pid_reset(cpu);
+       intel_pstate_sample(cpu);
+       intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
+
+       add_timer_on(&cpu->timer, cpunum);
+
+       pr_info("Intel pstate controlling: cpu %d\n", cpunum);
+
+       return 0;
+}
+
+static unsigned int intel_pstate_get(unsigned int cpu_num)
+{
+       struct sample *sample;
+       struct cpudata *cpu;
+
+       cpu = all_cpu_data[cpu_num];
+       if (!cpu)
+               return 0;
+       sample = &cpu->samples[cpu->sample_ptr];
+       return sample->freq;
+}
+
+static int intel_pstate_set_policy(struct cpufreq_policy *policy)
+{
+       struct cpudata *cpu;
+       int min, max;
+
+       cpu = all_cpu_data[policy->cpu];
+
+       intel_pstate_get_min_max(cpu, &min, &max);
+
+       limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
+       limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100);
+       limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
+
+       limits.max_perf_pct = policy->max * 100 / policy->cpuinfo.max_freq;
+       limits.max_perf_pct = clamp_t(int, limits.max_perf_pct, 0 , 100);
+       limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
+
+       if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+               limits.min_perf_pct = 100;
+               limits.min_perf = int_tofp(1);
+               limits.max_perf_pct = 100;
+               limits.max_perf = int_tofp(1);
+               limits.no_turbo = 0;
+       }
+
+       return 0;
+}
+
+static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
+{
+       cpufreq_verify_within_limits(policy,
+                               policy->cpuinfo.min_freq,
+                               policy->cpuinfo.max_freq);
+
+       if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
+               (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int __cpuinit intel_pstate_cpu_exit(struct cpufreq_policy *policy)
+{
+       int cpu = policy->cpu;
+
+       del_timer(&all_cpu_data[cpu]->timer);
+       kfree(all_cpu_data[cpu]);
+       all_cpu_data[cpu] = NULL;
+       return 0;
+}
+
+static int __cpuinit intel_pstate_cpu_init(struct cpufreq_policy *policy)
+{
+       int rc, min_pstate, max_pstate;
+       struct cpudata *cpu;
+
+       rc = intel_pstate_init_cpu(policy->cpu);
+       if (rc)
+               return rc;
+
+       cpu = all_cpu_data[policy->cpu];
+
+       if (!limits.no_turbo &&
+               limits.min_perf_pct == 100 && limits.max_perf_pct == 100)
+               policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+       else
+               policy->policy = CPUFREQ_POLICY_POWERSAVE;
+
+       intel_pstate_get_min_max(cpu, &min_pstate, &max_pstate);
+       policy->min = min_pstate * 100000;
+       policy->max = max_pstate * 100000;
+
+       /* cpuinfo and default policy values */
+       policy->cpuinfo.min_freq = cpu->pstate.min_pstate * 100000;
+       policy->cpuinfo.max_freq = cpu->pstate.turbo_pstate * 100000;
+       policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+       cpumask_set_cpu(policy->cpu, policy->cpus);
+
+       return 0;
+}
+
+static struct cpufreq_driver intel_pstate_driver = {
+       .flags          = CPUFREQ_CONST_LOOPS,
+       .verify         = intel_pstate_verify_policy,
+       .setpolicy      = intel_pstate_set_policy,
+       .get            = intel_pstate_get,
+       .init           = intel_pstate_cpu_init,
+       .exit           = intel_pstate_cpu_exit,
+       .name           = "intel_pstate",
+       .owner          = THIS_MODULE,
+};
+
+static void intel_pstate_exit(void)
+{
+       int cpu;
+
+       sysfs_remove_group(intel_pstate_kobject,
+                               &intel_pstate_attr_group);
+       debugfs_remove_recursive(debugfs_parent);
+
+       cpufreq_unregister_driver(&intel_pstate_driver);
+
+       if (!all_cpu_data)
+               return;
+
+       get_online_cpus();
+       for_each_online_cpu(cpu) {
+               if (all_cpu_data[cpu]) {
+                       del_timer_sync(&all_cpu_data[cpu]->timer);
+                       kfree(all_cpu_data[cpu]);
+               }
+       }
+
+       put_online_cpus();
+       vfree(all_cpu_data);
+}
+module_exit(intel_pstate_exit);
+
+static int __initdata no_load;
+
+static int __init intel_pstate_init(void)
+{
+       int rc = 0;
+       const struct x86_cpu_id *id;
+
+       if (no_load)
+               return -ENODEV;
+
+       id = x86_match_cpu(intel_pstate_cpu_ids);
+       if (!id)
+               return -ENODEV;
+
+       pr_info("Intel P-state driver initializing.\n");
+
+       all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus());
+       if (!all_cpu_data)
+               return -ENOMEM;
+       memset(all_cpu_data, 0, sizeof(void *) * num_possible_cpus());
+
+       rc = cpufreq_register_driver(&intel_pstate_driver);
+       if (rc)
+               goto out;
+
+       intel_pstate_debug_expose_params();
+       intel_pstate_sysfs_expose_params();
+       return rc;
+out:
+       intel_pstate_exit();
+       return -ENODEV;
+}
+device_initcall(intel_pstate_init);
+
+static int __init intel_pstate_setup(char *str)
+{
+       if (!str)
+               return -EINVAL;
+
+       if (!strcmp(str, "disable"))
+               no_load = 1;
+       return 0;
+}
+early_param("intel_pstate", intel_pstate_setup);
+
+MODULE_AUTHOR("Dirk Brandewie <dirk.j.brandewie@intel.com>");
+MODULE_DESCRIPTION("'intel_pstate' - P state driver Intel Core processors");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
new file mode 100644 (file)
index 0000000..0e83e3c
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ *     kirkwood_freq.c: cpufreq driver for the Marvell kirkwood
+ *
+ *     Copyright (C) 2013 Andrew Lunn <andrew@lunn.ch>
+ *
+ *     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; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/cpufreq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+
+#define CPU_SW_INT_BLK BIT(28)
+
+static struct priv
+{
+       struct clk *cpu_clk;
+       struct clk *ddr_clk;
+       struct clk *powersave_clk;
+       struct device *dev;
+       void __iomem *base;
+} priv;
+
+#define STATE_CPU_FREQ 0x01
+#define STATE_DDR_FREQ 0x02
+
+/*
+ * Kirkwood can swap the clock to the CPU between two clocks:
+ *
+ * - cpu clk
+ * - ddr clk
+ *
+ * The frequencies are set at runtime before registering this *
+ * table.
+ */
+static struct cpufreq_frequency_table kirkwood_freq_table[] = {
+       {STATE_CPU_FREQ,        0}, /* CPU uses cpuclk */
+       {STATE_DDR_FREQ,        0}, /* CPU uses ddrclk */
+       {0,                     CPUFREQ_TABLE_END},
+};
+
+static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu)
+{
+       if (__clk_is_enabled(priv.powersave_clk))
+               return kirkwood_freq_table[1].frequency;
+       return kirkwood_freq_table[0].frequency;
+}
+
+static void kirkwood_cpufreq_set_cpu_state(unsigned int index)
+{
+       struct cpufreq_freqs freqs;
+       unsigned int state = kirkwood_freq_table[index].index;
+       unsigned long reg;
+
+       freqs.old = kirkwood_cpufreq_get_cpu_frequency(0);
+       freqs.new = kirkwood_freq_table[index].frequency;
+       freqs.cpu = 0; /* Kirkwood is UP */
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+       dev_dbg(priv.dev, "Attempting to set frequency to %i KHz\n",
+               kirkwood_freq_table[index].frequency);
+       dev_dbg(priv.dev, "old frequency was %i KHz\n",
+               kirkwood_cpufreq_get_cpu_frequency(0));
+
+       if (freqs.old != freqs.new) {
+               local_irq_disable();
+
+               /* Disable interrupts to the CPU */
+               reg = readl_relaxed(priv.base);
+               reg |= CPU_SW_INT_BLK;
+               writel_relaxed(reg, priv.base);
+
+               switch (state) {
+               case STATE_CPU_FREQ:
+                       clk_disable(priv.powersave_clk);
+                       break;
+               case STATE_DDR_FREQ:
+                       clk_enable(priv.powersave_clk);
+                       break;
+               }
+
+               /* Wait-for-Interrupt, while the hardware changes frequency */
+               cpu_do_idle();
+
+               /* Enable interrupts to the CPU */
+               reg = readl_relaxed(priv.base);
+               reg &= ~CPU_SW_INT_BLK;
+               writel_relaxed(reg, priv.base);
+
+               local_irq_enable();
+       }
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+};
+
+static int kirkwood_cpufreq_verify(struct cpufreq_policy *policy)
+{
+       return cpufreq_frequency_table_verify(policy, kirkwood_freq_table);
+}
+
+static int kirkwood_cpufreq_target(struct cpufreq_policy *policy,
+                           unsigned int target_freq,
+                           unsigned int relation)
+{
+       unsigned int index = 0;
+
+       if (cpufreq_frequency_table_target(policy, kirkwood_freq_table,
+                               target_freq, relation, &index))
+               return -EINVAL;
+
+       kirkwood_cpufreq_set_cpu_state(index);
+
+       return 0;
+}
+
+/* Module init and exit code */
+static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+       int result;
+
+       /* cpuinfo and default policy values */
+       policy->cpuinfo.transition_latency = 5000; /* 5uS */
+       policy->cur = kirkwood_cpufreq_get_cpu_frequency(0);
+
+       result = cpufreq_frequency_table_cpuinfo(policy, kirkwood_freq_table);
+       if (result)
+               return result;
+
+       cpufreq_frequency_table_get_attr(kirkwood_freq_table, policy->cpu);
+
+       return 0;
+}
+
+static int kirkwood_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+       cpufreq_frequency_table_put_attr(policy->cpu);
+       return 0;
+}
+
+static struct freq_attr *kirkwood_cpufreq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
+static struct cpufreq_driver kirkwood_cpufreq_driver = {
+       .get    = kirkwood_cpufreq_get_cpu_frequency,
+       .verify = kirkwood_cpufreq_verify,
+       .target = kirkwood_cpufreq_target,
+       .init   = kirkwood_cpufreq_cpu_init,
+       .exit   = kirkwood_cpufreq_cpu_exit,
+       .name   = "kirkwood-cpufreq",
+       .owner  = THIS_MODULE,
+       .attr   = kirkwood_cpufreq_attr,
+};
+
+static int kirkwood_cpufreq_probe(struct platform_device *pdev)
+{
+       struct device_node *np;
+       struct resource *res;
+       int err;
+
+       priv.dev = &pdev->dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "Cannot get memory resource\n");
+               return -ENODEV;
+       }
+       priv.base = devm_request_and_ioremap(&pdev->dev, res);
+       if (!priv.base) {
+               dev_err(&pdev->dev, "Cannot ioremap\n");
+               return -EADDRNOTAVAIL;
+       }
+
+       np = of_find_node_by_path("/cpus/cpu@0");
+       if (!np)
+               return -ENODEV;
+
+       priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
+       if (IS_ERR(priv.cpu_clk)) {
+               dev_err(priv.dev, "Unable to get cpuclk");
+               return PTR_ERR(priv.cpu_clk);
+       }
+
+       clk_prepare_enable(priv.cpu_clk);
+       kirkwood_freq_table[0].frequency = clk_get_rate(priv.cpu_clk) / 1000;
+
+       priv.ddr_clk = of_clk_get_by_name(np, "ddrclk");
+       if (IS_ERR(priv.ddr_clk)) {
+               dev_err(priv.dev, "Unable to get ddrclk");
+               err = PTR_ERR(priv.ddr_clk);
+               goto out_cpu;
+       }
+
+       clk_prepare_enable(priv.ddr_clk);
+       kirkwood_freq_table[1].frequency = clk_get_rate(priv.ddr_clk) / 1000;
+
+       priv.powersave_clk = of_clk_get_by_name(np, "powersave");
+       if (IS_ERR(priv.powersave_clk)) {
+               dev_err(priv.dev, "Unable to get powersave");
+               err = PTR_ERR(priv.powersave_clk);
+               goto out_ddr;
+       }
+       clk_prepare(priv.powersave_clk);
+
+       of_node_put(np);
+       np = NULL;
+
+       err = cpufreq_register_driver(&kirkwood_cpufreq_driver);
+       if (!err)
+               return 0;
+
+       dev_err(priv.dev, "Failed to register cpufreq driver");
+
+       clk_disable_unprepare(priv.powersave_clk);
+out_ddr:
+       clk_disable_unprepare(priv.ddr_clk);
+out_cpu:
+       clk_disable_unprepare(priv.cpu_clk);
+       of_node_put(np);
+
+       return err;
+}
+
+static int kirkwood_cpufreq_remove(struct platform_device *pdev)
+{
+       cpufreq_unregister_driver(&kirkwood_cpufreq_driver);
+
+       clk_disable_unprepare(priv.powersave_clk);
+       clk_disable_unprepare(priv.ddr_clk);
+       clk_disable_unprepare(priv.cpu_clk);
+
+       return 0;
+}
+
+static struct platform_driver kirkwood_cpufreq_platform_driver = {
+       .probe = kirkwood_cpufreq_probe,
+       .remove = kirkwood_cpufreq_remove,
+       .driver = {
+               .name = "kirkwood-cpufreq",
+               .owner = THIS_MODULE,
+       },
+};
+
+module_platform_driver(kirkwood_cpufreq_platform_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch");
+MODULE_DESCRIPTION("cpufreq driver for Marvell's kirkwood CPU");
+MODULE_ALIAS("platform:kirkwood-cpufreq");
index 89b178a..d4c4989 100644 (file)
@@ -181,7 +181,7 @@ static int maple_cpufreq_cpu_init(struct cpufreq_policy *policy)
        /* secondary CPUs are tied to the primary one by the
         * cpufreq core if in the secondary policy we tell it that
         * it actually must be one policy together with all others. */
-       cpumask_copy(policy->cpus, cpu_online_mask);
+       cpumask_setall(policy->cpus);
        cpufreq_frequency_table_get_attr(maple_cpu_freqs, policy->cpu);
 
        return cpufreq_frequency_table_cpuinfo(policy,
index 97102b0..9128c07 100644 (file)
@@ -214,10 +214,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
         * interface to handle this scenario. Additional is_smp() check
         * is to keep SMP_ON_UP build working.
         */
-       if (is_smp()) {
-               policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+       if (is_smp())
                cpumask_setall(policy->cpus);
-       }
 
        /* FIXME: what's the actual transition time? */
        policy->cpuinfo.transition_latency = 300 * 1000;
index 056faf6..d13a136 100644 (file)
@@ -1249,39 +1249,59 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
        .attr           = powernow_k8_attr,
 };
 
+static void __request_acpi_cpufreq(void)
+{
+       const char *cur_drv, *drv = "acpi-cpufreq";
+
+       cur_drv = cpufreq_get_current_driver();
+       if (!cur_drv)
+               goto request;
+
+       if (strncmp(cur_drv, drv, min_t(size_t, strlen(cur_drv), strlen(drv))))
+               pr_warn(PFX "WTF driver: %s\n", cur_drv);
+
+       return;
+
+ request:
+       pr_warn(PFX "This CPU is not supported anymore, using acpi-cpufreq instead.\n");
+       request_module(drv);
+}
+
 /* driver entry point for init */
 static int __cpuinit powernowk8_init(void)
 {
        unsigned int i, supported_cpus = 0;
-       int rv;
+       int ret;
 
        if (static_cpu_has(X86_FEATURE_HW_PSTATE)) {
-               pr_warn(PFX "this CPU is not supported anymore, using acpi-cpufreq instead.\n");
-               request_module("acpi-cpufreq");
+               __request_acpi_cpufreq();
                return -ENODEV;
        }
 
        if (!x86_match_cpu(powernow_k8_ids))
                return -ENODEV;
 
+       get_online_cpus();
        for_each_online_cpu(i) {
-               int rc;
-               smp_call_function_single(i, check_supported_cpu, &rc, 1);
-               if (rc == 0)
+               smp_call_function_single(i, check_supported_cpu, &ret, 1);
+               if (!ret)
                        supported_cpus++;
        }
 
-       if (supported_cpus != num_online_cpus())
+       if (supported_cpus != num_online_cpus()) {
+               put_online_cpus();
                return -ENODEV;
+       }
+       put_online_cpus();
 
-       rv = cpufreq_register_driver(&cpufreq_amd64_driver);
+       ret = cpufreq_register_driver(&cpufreq_amd64_driver);
+       if (ret)
+               return ret;
 
-       if (!rv)
-               pr_info(PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
-                       num_online_nodes(), boot_cpu_data.x86_model_id,
-                       supported_cpus);
+       pr_info(PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
+               num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
 
-       return rv;
+       return ret;
 }
 
 /* driver entry point for term */
index 4575cfe..7e4d773 100644 (file)
@@ -30,7 +30,7 @@ static struct {
        u32 cnt;
 } spear_cpufreq;
 
-int spear_cpufreq_verify(struct cpufreq_policy *policy)
+static int spear_cpufreq_verify(struct cpufreq_policy *policy)
 {
        return cpufreq_frequency_table_verify(policy, spear_cpufreq.freq_tbl);
 }
@@ -157,7 +157,9 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
 
        freqs.new = newfreq / 1000;
        freqs.new /= mult;
-       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+       for_each_cpu(freqs.cpu, policy->cpus)
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
        if (mult == 2)
                ret = spear1340_set_cpu_rate(srcclk, newfreq);
@@ -170,7 +172,8 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
                freqs.new = clk_get_rate(spear_cpufreq.clk) / 1000;
        }
 
-       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       for_each_cpu(freqs.cpu, policy->cpus)
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
        return ret;
 }
 
@@ -188,8 +191,7 @@ static int spear_cpufreq_init(struct cpufreq_policy *policy)
        policy->cpuinfo.transition_latency = spear_cpufreq.transition_latency;
        policy->cur = spear_cpufreq_get(0);
 
-       cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu));
-       cpumask_copy(policy->related_cpus, policy->cpus);
+       cpumask_setall(policy->cpus);
 
        return 0;
 }
index e1f6860..eba6929 100644 (file)
@@ -144,7 +144,6 @@ int cpuidle_idle_call(void)
                return 0;
        }
 
-       trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu);
        trace_cpu_idle_rcuidle(next_state, dev->cpu);
 
        if (cpuidle_state_is_coupled(dev, drv, next_state))
@@ -153,7 +152,6 @@ int cpuidle_idle_call(void)
        else
                entered_state = cpuidle_enter_state(dev, drv, next_state);
 
-       trace_power_end_rcuidle(dev->cpu);
        trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
 
        /* give the governor an opportunity to reflect on the outcome */
index 4d0e60a..a2d478e 100644 (file)
@@ -1313,14 +1313,18 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
                                if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
                                        radeon_wait_for_vblank(rdev, i);
                                        tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+                                       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
                                        WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+                                       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
                                }
                        } else {
                                tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
                                if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
                                        radeon_wait_for_vblank(rdev, i);
                                        tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+                                       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
                                        WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
+                                       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
                                }
                        }
                        /* wait for the next frame */
@@ -1345,6 +1349,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
                blackout &= ~BLACKOUT_MODE_MASK;
                WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
        }
+       /* wait for the MC to settle */
+       udelay(100);
 }
 
 void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1378,11 +1384,15 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
                        if (ASIC_IS_DCE6(rdev)) {
                                tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
                                tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+                               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
                                WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+                               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
                        } else {
                                tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
                                tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+                               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
                                WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
+                               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
                        }
                        /* wait for the next frame */
                        frame_count = radeon_get_vblank_counter(rdev, i);
@@ -2036,9 +2046,20 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
        WREG32(HDP_ADDR_CONFIG, gb_addr_config);
        WREG32(DMA_TILING_CONFIG, gb_addr_config);
 
-       tmp = gb_addr_config & NUM_PIPES_MASK;
-       tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends,
-                                       EVERGREEN_MAX_BACKENDS, disabled_rb_mask);
+       if ((rdev->config.evergreen.max_backends == 1) &&
+           (rdev->flags & RADEON_IS_IGP)) {
+               if ((disabled_rb_mask & 3) == 1) {
+                       /* RB0 disabled, RB1 enabled */
+                       tmp = 0x11111111;
+               } else {
+                       /* RB1 disabled, RB0 enabled */
+                       tmp = 0x00000000;
+               }
+       } else {
+               tmp = gb_addr_config & NUM_PIPES_MASK;
+               tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends,
+                                               EVERGREEN_MAX_BACKENDS, disabled_rb_mask);
+       }
        WREG32(GB_BACKEND_MAP, tmp);
 
        WREG32(CGTS_SYS_TCC_DISABLE, 0);
index bc2540b..becb03e 100644 (file)
@@ -1462,12 +1462,15 @@ u32 r6xx_remap_render_backend(struct radeon_device *rdev,
                              u32 disabled_rb_mask)
 {
        u32 rendering_pipe_num, rb_num_width, req_rb_num;
-       u32 pipe_rb_ratio, pipe_rb_remain;
+       u32 pipe_rb_ratio, pipe_rb_remain, tmp;
        u32 data = 0, mask = 1 << (max_rb_num - 1);
        unsigned i, j;
 
        /* mask out the RBs that don't exist on that asic */
-       disabled_rb_mask |= (0xff << max_rb_num) & 0xff;
+       tmp = disabled_rb_mask | ((0xff << max_rb_num) & 0xff);
+       /* make sure at least one RB is available */
+       if ((tmp & 0xff) != 0xff)
+               disabled_rb_mask = tmp;
 
        rendering_pipe_num = 1 << tiling_pipe_num;
        req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask);
index 9056faf..0b202c0 100644 (file)
@@ -1445,7 +1445,7 @@ static struct radeon_asic cayman_asic = {
        .vm = {
                .init = &cayman_vm_init,
                .fini = &cayman_vm_fini,
-               .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+               .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
                .set_page = &cayman_vm_set_page,
        },
        .ring = {
@@ -1572,7 +1572,7 @@ static struct radeon_asic trinity_asic = {
        .vm = {
                .init = &cayman_vm_init,
                .fini = &cayman_vm_fini,
-               .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+               .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
                .set_page = &cayman_vm_set_page,
        },
        .ring = {
@@ -1699,7 +1699,7 @@ static struct radeon_asic si_asic = {
        .vm = {
                .init = &si_vm_init,
                .fini = &si_vm_fini,
-               .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+               .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
                .set_page = &si_vm_set_page,
        },
        .ring = {
index 33a56a0..3e403bd 100644 (file)
@@ -2470,6 +2470,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                                                                   1),
                                                                  ATOM_DEVICE_CRT1_SUPPORT);
                                }
+                               /* RV100 board with external TDMS bit mis-set.
+                                * Actually uses internal TMDS, clear the bit.
+                                */
+                               if (dev->pdev->device == 0x5159 &&
+                                   dev->pdev->subsystem_vendor == 0x1014 &&
+                                   dev->pdev->subsystem_device == 0x029A) {
+                                       tmp &= ~(1 << 4);
+                               }
                                if ((tmp >> 4) & 0x1) {
                                        devices |= ATOM_DEVICE_DFP2_SUPPORT;
                                        radeon_add_legacy_encoder(dev,
index ff3def7..05c96fa 100644 (file)
@@ -1115,8 +1115,10 @@ radeon_user_framebuffer_create(struct drm_device *dev,
        }
 
        radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
-       if (radeon_fb == NULL)
+       if (radeon_fb == NULL) {
+               drm_gem_object_unreference_unlocked(obj);
                return ERR_PTR(-ENOMEM);
+       }
 
        ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
        if (ret) {
index 2430d80..cd72062 100644 (file)
@@ -377,6 +377,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi
 {
        int r;
 
+       /* make sure we aren't trying to allocate more space than there is on the ring */
+       if (ndw > (ring->ring_size / 4))
+               return -ENOMEM;
        /* Align requested size with padding so unlock_commit can
         * pad safely */
        ndw = (ndw + ring->align_mask) & ~ring->align_mask;
index 0f656b1..a072fa8 100644 (file)
@@ -1,5 +1,6 @@
 cayman 0x9400
 0x0000802C GRBM_GFX_INDEX
+0x00008040 WAIT_UNTIL
 0x000084FC CP_STRMOUT_CNTL
 0x000085F0 CP_COHER_CNTL
 0x000085F4 CP_COHER_SIZE
index 2bb6d0e..435ed35 100644 (file)
@@ -336,6 +336,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
                                WREG32(R600_CITF_CNTL, blackout);
                }
        }
+       /* wait for the MC to settle */
+       udelay(100);
 }
 
 void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
index 44420fc..8be35c8 100644 (file)
@@ -429,7 +429,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
        struct ttm_bo_device *bdev = bo->bdev;
        struct ttm_bo_driver *driver = bdev->driver;
 
-       fbo = kzalloc(sizeof(*fbo), GFP_KERNEL);
+       fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
        if (!fbo)
                return -ENOMEM;
 
@@ -448,7 +448,12 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
        fbo->vm_node = NULL;
        atomic_set(&fbo->cpu_writers, 0);
 
-       fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
+       spin_lock(&bdev->fence_lock);
+       if (bo->sync_obj)
+               fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
+       else
+               fbo->sync_obj = NULL;
+       spin_unlock(&bdev->fence_lock);
        kref_init(&fbo->list_kref);
        kref_init(&fbo->kref);
        fbo->destroy = &ttm_transfered_destroy;
@@ -661,13 +666,11 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
                 */
 
                set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
-
-               /* ttm_buffer_object_transfer accesses bo->sync_obj */
-               ret = ttm_buffer_object_transfer(bo, &ghost_obj);
                spin_unlock(&bdev->fence_lock);
                if (tmp_obj)
                        driver->sync_obj_unref(&tmp_obj);
 
+               ret = ttm_buffer_object_transfer(bo, &ghost_obj);
                if (ret)
                        return ret;
 
index 1672e2a..6351aba 100644 (file)
@@ -911,7 +911,7 @@ exit:
        return res;
 }
 
-static int acpi_power_meter_remove(struct acpi_device *device, int type)
+static int acpi_power_meter_remove(struct acpi_device *device)
 {
        struct acpi_power_meter_resource *resource;
 
index 56dbcfb..b25c643 100644 (file)
@@ -190,7 +190,7 @@ struct atk_acpi_input_buf {
 };
 
 static int atk_add(struct acpi_device *device);
-static int atk_remove(struct acpi_device *device, int type);
+static int atk_remove(struct acpi_device *device);
 static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
 static int atk_read_value(struct atk_sensor_data *sensor, u64 *value);
 static void atk_free_sensors(struct atk_data *data);
@@ -1416,7 +1416,7 @@ out:
        return err;
 }
 
-static int atk_remove(struct acpi_device *device, int type)
+static int atk_remove(struct acpi_device *device)
 {
        struct atk_data *data = device->driver_data;
        dev_dbg(&device->dev, "removing...\n");
index 6aafa3d..c447e8d 100644 (file)
@@ -406,7 +406,7 @@ err:
        return -EIO;
 }
 
-static int acpi_smbus_cmi_remove(struct acpi_device *device, int type)
+static int acpi_smbus_cmi_remove(struct acpi_device *device)
 {
        struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device);
 
index 4850d03..3527509 100644 (file)
@@ -263,20 +263,15 @@ static void remove_qp(struct qib_ibdev *dev, struct qib_qp *qp)
                struct qib_qp __rcu **qpp;
 
                qpp = &dev->qp_table[n];
-               q = rcu_dereference_protected(*qpp,
-                       lockdep_is_held(&dev->qpt_lock));
-               for (; q; qpp = &q->next) {
+               for (; (q = rcu_dereference_protected(*qpp,
+                               lockdep_is_held(&dev->qpt_lock))) != NULL;
+                               qpp = &q->next)
                        if (q == qp) {
                                atomic_dec(&qp->refcount);
                                *qpp = qp->next;
                                rcu_assign_pointer(qp->next, NULL);
-                               q = rcu_dereference_protected(*qpp,
-                                       lockdep_is_held(&dev->qpt_lock));
                                break;
                        }
-                       q = rcu_dereference_protected(*qpp,
-                               lockdep_is_held(&dev->qpt_lock));
-               }
        }
 
        spin_unlock_irqrestore(&dev->qpt_lock, flags);
index 03103d2..67b0c1d 100644 (file)
@@ -741,6 +741,9 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
 
        tx_req->mapping = addr;
 
+       skb_orphan(skb);
+       skb_dst_drop(skb);
+
        rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
                       addr, skb->len);
        if (unlikely(rc)) {
@@ -752,9 +755,6 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
                dev->trans_start = jiffies;
                ++tx->tx_head;
 
-               skb_orphan(skb);
-               skb_dst_drop(skb);
-
                if (++priv->tx_outstanding == ipoib_sendq_size) {
                        ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
                                  tx->qp->qp_num);
index a1bca70..2cfa76f 100644 (file)
@@ -600,6 +600,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
                netif_stop_queue(dev);
        }
 
+       skb_orphan(skb);
+       skb_dst_drop(skb);
+
        rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
                       address->ah, qpn, tx_req, phead, hlen);
        if (unlikely(rc)) {
@@ -615,9 +618,6 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
 
                address->last_send = priv->tx_head;
                ++priv->tx_head;
-
-               skb_orphan(skb);
-               skb_dst_drop(skb);
        }
 
        if (unlikely(priv->tx_outstanding > MAX_SEND_CQE))
index 26f1313..5d44023 100644 (file)
@@ -121,7 +121,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
        return err;
 }
 
-static int atlas_acpi_button_remove(struct acpi_device *device, int type)
+static int atlas_acpi_button_remove(struct acpi_device *device)
 {
        acpi_status status;
 
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
new file mode 100644 (file)
index 0000000..9545c9f
--- /dev/null
@@ -0,0 +1,19 @@
+menuconfig MAILBOX
+       bool "Mailbox Hardware Support"
+       help
+         Mailbox is a framework to control hardware communication between
+         on-chip processors through queued messages and interrupt driven
+         signals. Say Y if your platform supports hardware mailboxes.
+
+if MAILBOX
+config PL320_MBOX
+       bool "ARM PL320 Mailbox"
+       depends on ARM_AMBA
+       help
+         An implementation of the ARM PL320 Interprocessor Communication
+         Mailbox (IPCM), tailored for the Calxeda Highbank. It is used to
+         send short messages between Highbank's A9 cores and the EnergyCore
+         Management Engine, primarily for cpufreq. Say Y here if you want
+         to use the PL320 IPCM support.
+
+endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
new file mode 100644 (file)
index 0000000..543ad6a
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_PL320_MBOX)       += pl320-ipc.o
diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320-ipc.c
new file mode 100644 (file)
index 0000000..c45b3ae
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * 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/types.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+
+#include <linux/mailbox.h>
+
+#define IPCMxSOURCE(m)         ((m) * 0x40)
+#define IPCMxDSET(m)           (((m) * 0x40) + 0x004)
+#define IPCMxDCLEAR(m)         (((m) * 0x40) + 0x008)
+#define IPCMxDSTATUS(m)                (((m) * 0x40) + 0x00C)
+#define IPCMxMODE(m)           (((m) * 0x40) + 0x010)
+#define IPCMxMSET(m)           (((m) * 0x40) + 0x014)
+#define IPCMxMCLEAR(m)         (((m) * 0x40) + 0x018)
+#define IPCMxMSTATUS(m)                (((m) * 0x40) + 0x01C)
+#define IPCMxSEND(m)           (((m) * 0x40) + 0x020)
+#define IPCMxDR(m, dr)         (((m) * 0x40) + ((dr) * 4) + 0x024)
+
+#define IPCMMIS(irq)           (((irq) * 8) + 0x800)
+#define IPCMRIS(irq)           (((irq) * 8) + 0x804)
+
+#define MBOX_MASK(n)           (1 << (n))
+#define IPC_TX_MBOX            1
+#define IPC_RX_MBOX            2
+
+#define CHAN_MASK(n)           (1 << (n))
+#define A9_SOURCE              1
+#define M3_SOURCE              0
+
+static void __iomem *ipc_base;
+static int ipc_irq;
+static DEFINE_MUTEX(ipc_m1_lock);
+static DECLARE_COMPLETION(ipc_completion);
+static ATOMIC_NOTIFIER_HEAD(ipc_notifier);
+
+static inline void set_destination(int source, int mbox)
+{
+       __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDSET(mbox));
+       __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMSET(mbox));
+}
+
+static inline void clear_destination(int source, int mbox)
+{
+       __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDCLEAR(mbox));
+       __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMCLEAR(mbox));
+}
+
+static void __ipc_send(int mbox, u32 *data)
+{
+       int i;
+       for (i = 0; i < 7; i++)
+               __raw_writel(data[i], ipc_base + IPCMxDR(mbox, i));
+       __raw_writel(0x1, ipc_base + IPCMxSEND(mbox));
+}
+
+static u32 __ipc_rcv(int mbox, u32 *data)
+{
+       int i;
+       for (i = 0; i < 7; i++)
+               data[i] = __raw_readl(ipc_base + IPCMxDR(mbox, i));
+       return data[1];
+}
+
+/* blocking implmentation from the A9 side, not usuable in interrupts! */
+int pl320_ipc_transmit(u32 *data)
+{
+       int ret;
+
+       mutex_lock(&ipc_m1_lock);
+
+       init_completion(&ipc_completion);
+       __ipc_send(IPC_TX_MBOX, data);
+       ret = wait_for_completion_timeout(&ipc_completion,
+                                         msecs_to_jiffies(1000));
+       if (ret == 0) {
+               ret = -ETIMEDOUT;
+               goto out;
+       }
+
+       ret = __ipc_rcv(IPC_TX_MBOX, data);
+out:
+       mutex_unlock(&ipc_m1_lock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(pl320_ipc_transmit);
+
+static irqreturn_t ipc_handler(int irq, void *dev)
+{
+       u32 irq_stat;
+       u32 data[7];
+
+       irq_stat = __raw_readl(ipc_base + IPCMMIS(1));
+       if (irq_stat & MBOX_MASK(IPC_TX_MBOX)) {
+               __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+               complete(&ipc_completion);
+       }
+       if (irq_stat & MBOX_MASK(IPC_RX_MBOX)) {
+               __ipc_rcv(IPC_RX_MBOX, data);
+               atomic_notifier_call_chain(&ipc_notifier, data[0], data + 1);
+               __raw_writel(2, ipc_base + IPCMxSEND(IPC_RX_MBOX));
+       }
+
+       return IRQ_HANDLED;
+}
+
+int pl320_ipc_register_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&ipc_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(pl320_ipc_register_notifier);
+
+int pl320_ipc_unregister_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&ipc_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(pl320_ipc_unregister_notifier);
+
+static int __init pl320_probe(struct amba_device *adev,
+                               const struct amba_id *id)
+{
+       int ret;
+
+       ipc_base = ioremap(adev->res.start, resource_size(&adev->res));
+       if (ipc_base == NULL)
+               return -ENOMEM;
+
+       __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+
+       ipc_irq = adev->irq[0];
+       ret = request_irq(ipc_irq, ipc_handler, 0, dev_name(&adev->dev), NULL);
+       if (ret < 0)
+               goto err;
+
+       /* Init slow mailbox */
+       __raw_writel(CHAN_MASK(A9_SOURCE),
+                       ipc_base + IPCMxSOURCE(IPC_TX_MBOX));
+       __raw_writel(CHAN_MASK(M3_SOURCE),
+                       ipc_base + IPCMxDSET(IPC_TX_MBOX));
+       __raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE),
+                    ipc_base + IPCMxMSET(IPC_TX_MBOX));
+
+       /* Init receive mailbox */
+       __raw_writel(CHAN_MASK(M3_SOURCE),
+                       ipc_base + IPCMxSOURCE(IPC_RX_MBOX));
+       __raw_writel(CHAN_MASK(A9_SOURCE),
+                       ipc_base + IPCMxDSET(IPC_RX_MBOX));
+       __raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE),
+                    ipc_base + IPCMxMSET(IPC_RX_MBOX));
+
+       return 0;
+err:
+       iounmap(ipc_base);
+       return ret;
+}
+
+static struct amba_id pl320_ids[] = {
+       {
+               .id     = 0x00041320,
+               .mask   = 0x000fffff,
+       },
+       { 0, 0 },
+};
+
+static struct amba_driver pl320_driver = {
+       .drv = {
+               .name   = "pl320",
+       },
+       .id_table       = pl320_ids,
+       .probe          = pl320_probe,
+};
+
+static int __init ipc_init(void)
+{
+       return amba_driver_register(&pl320_driver);
+}
+module_init(ipc_init);
index e10e525..296941a 100644 (file)
@@ -374,6 +374,7 @@ static int usb_keene_probe(struct usb_interface *intf,
        radio->vdev.ioctl_ops = &usb_keene_ioctl_ops;
        radio->vdev.lock = &radio->lock;
        radio->vdev.release = video_device_release_empty;
+       radio->vdev.vfl_dir = VFL_DIR_TX;
 
        radio->usbdev = interface_to_usbdev(intf);
        radio->intf = intf;
index a082e40..1507c9d 100644 (file)
@@ -250,6 +250,7 @@ static struct video_device radio_si4713_vdev_template = {
        .name                   = "radio-si4713",
        .release                = video_device_release,
        .ioctl_ops              = &radio_si4713_ioctl_ops,
+       .vfl_dir                = VFL_DIR_TX,
 };
 
 /* Platform driver interface */
index c48be19..cabbe3a 100644 (file)
@@ -1971,6 +1971,7 @@ static struct video_device wl1273_viddev_template = {
        .ioctl_ops              = &wl1273_ioctl_ops,
        .name                   = WL1273_FM_DRIVER_NAME,
        .release                = wl1273_vdev_release,
+       .vfl_dir                = VFL_DIR_TX,
 };
 
 static int wl1273_fm_radio_remove(struct platform_device *pdev)
index 048de45..0a8ee8f 100644 (file)
@@ -518,6 +518,16 @@ static struct video_device fm_viddev_template = {
        .ioctl_ops = &fm_drv_ioctl_ops,
        .name = FM_DRV_NAME,
        .release = video_device_release,
+       /*
+        * To ensure both the tuner and modulator ioctls are accessible we
+        * set the vfl_dir to M2M to indicate this.
+        *
+        * It is not really a mem2mem device of course, but it can both receive
+        * and transmit using the same radio device. It's the only radio driver
+        * that does this and it should really be split in two radio devices,
+        * but that would affect applications using this driver.
+        */
+       .vfl_dir = VFL_DIR_M2M,
 };
 
 int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
index 27f80cd..46dcb54 100644 (file)
@@ -272,6 +272,7 @@ config MTD_DOCG3
        tristate "M-Systems Disk-On-Chip G3"
        select BCH
        select BCH_CONST_PARAMS
+       select BITREVERSE
        ---help---
          This provides an MTD device driver for the M-Systems DiskOnChip
          G3 devices.
index 67cc73c..7901d72 100644 (file)
@@ -170,7 +170,7 @@ static int of_flash_probe(struct platform_device *dev)
        resource_size_t res_size;
        struct mtd_part_parser_data ppdata;
        bool map_indirect;
-       const char *mtd_name;
+       const char *mtd_name = NULL;
 
        match = of_match_device(of_flash_match, &dev->dev);
        if (!match)
index 86c9a79..595de40 100644 (file)
@@ -17,8 +17,8 @@
 #include "bcm47xxnflash.h"
 
 /* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has
- * shown 164 retries as maxiumum. */
-#define NFLASH_READY_RETRIES           1000
+ * shown ~1000 retries as maxiumum. */
+#define NFLASH_READY_RETRIES           10000
 
 #define NFLASH_SECTOR_SIZE             512
 
index 3502606..feae55c 100644 (file)
@@ -523,7 +523,7 @@ static struct nand_ecclayout hwecc4_2048 __initconst = {
 static const struct of_device_id davinci_nand_of_match[] = {
        {.compatible = "ti,davinci-nand", },
        {},
-}
+};
 MODULE_DEVICE_TABLE(of, davinci_nand_of_match);
 
 static struct davinci_nand_pdata
index 8323ac9..3766682 100644 (file)
@@ -2857,8 +2857,11 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        int i;
        int val;
 
-       /* ONFI need to be probed in 8 bits mode */
-       WARN_ON(chip->options & NAND_BUSWIDTH_16);
+       /* ONFI need to be probed in 8 bits mode, and 16 bits should be selected with NAND_BUSWIDTH_AUTO */
+       if (chip->options & NAND_BUSWIDTH_16) {
+               pr_err("Trying ONFI probe in 16 bits mode, aborting !\n");
+               return 0;
+       }
        /* Try ONFI for unknown chip or LP */
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
index 1877ed7..1c9e09f 100644 (file)
@@ -1053,6 +1053,7 @@ static ssize_t bonding_store_primary(struct device *d,
                pr_info("%s: Setting primary slave to None.\n",
                        bond->dev->name);
                bond->primary_slave = NULL;
+               memset(bond->params.primary, 0, sizeof(bond->params.primary));
                bond_select_active_slave(bond);
                goto out;
        }
index 58607f1..2282b1a 100644 (file)
@@ -488,8 +488,12 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface,
 
        priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface),
                        IFX_WRITE_LOW_16BIT(mask));
+
+       /* According to C_CAN documentation, the reserved bit
+        * in IFx_MASK2 register is fixed 1
+        */
        priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface),
-                       IFX_WRITE_HIGH_16BIT(mask));
+                       IFX_WRITE_HIGH_16BIT(mask) | BIT(13));
 
        priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
                        IFX_WRITE_LOW_16BIT(id));
index 4eba17b..f1b3df1 100644 (file)
 
 #define DRV_VER                        "4.4.161.0u"
 #define DRV_NAME               "be2net"
-#define BE_NAME                        "ServerEngines BladeEngine2 10Gbps NIC"
-#define BE3_NAME               "ServerEngines BladeEngine3 10Gbps NIC"
-#define OC_NAME                        "Emulex OneConnect 10Gbps NIC"
+#define BE_NAME                        "Emulex BladeEngine2"
+#define BE3_NAME               "Emulex BladeEngine3"
+#define OC_NAME                        "Emulex OneConnect"
 #define OC_NAME_BE             OC_NAME "(be3)"
 #define OC_NAME_LANCER         OC_NAME "(Lancer)"
 #define OC_NAME_SH             OC_NAME "(Skyhawk)"
-#define DRV_DESC               "ServerEngines BladeEngine 10Gbps NIC Driver"
+#define DRV_DESC               "Emulex OneConnect 10Gbps NIC Driver"
 
 #define BE_VENDOR_ID           0x19a2
 #define EMULEX_VENDOR_ID       0x10df
index 5c99570..4d6f3c5 100644 (file)
@@ -25,7 +25,7 @@
 MODULE_VERSION(DRV_VER);
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
 MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
-MODULE_AUTHOR("ServerEngines Corporation");
+MODULE_AUTHOR("Emulex Corporation");
 MODULE_LICENSE("GPL");
 
 static unsigned int num_vfs;
index 02a12b6..4dab6fc 100644 (file)
 #define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
 #define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */
 #define E1000_CTRL_LANPHYPC_VALUE    0x00020000 /* SW value of LANPHYPC */
+#define E1000_CTRL_MEHE     0x00080000  /* Memory Error Handling Enable */
 #define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
 #define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
 #define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */
 
 #define E1000_PBS_16K E1000_PBA_16K
 
+/* Uncorrectable/correctable ECC Error counts and enable bits */
+#define E1000_PBECCSTS_CORR_ERR_CNT_MASK       0x000000FF
+#define E1000_PBECCSTS_UNCORR_ERR_CNT_MASK     0x0000FF00
+#define E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT    8
+#define E1000_PBECCSTS_ECC_ENABLE              0x00010000
+
 #define IFS_MAX       80
 #define IFS_MIN       40
 #define IFS_RATIO     4
 #define E1000_ICR_RXSEQ         0x00000008 /* Rx sequence error */
 #define E1000_ICR_RXDMT0        0x00000010 /* Rx desc min. threshold (0) */
 #define E1000_ICR_RXT0          0x00000080 /* Rx timer intr (ring 0) */
+#define E1000_ICR_ECCER         0x00400000 /* Uncorrectable ECC Error */
 #define E1000_ICR_INT_ASSERTED  0x80000000 /* If this bit asserted, the driver should claim the interrupt */
 #define E1000_ICR_RXQ0          0x00100000 /* Rx Queue 0 Interrupt */
 #define E1000_ICR_RXQ1          0x00200000 /* Rx Queue 1 Interrupt */
 #define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
 #define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
 #define E1000_IMS_RXT0      E1000_ICR_RXT0      /* Rx timer intr */
+#define E1000_IMS_ECCER     E1000_ICR_ECCER     /* Uncorrectable ECC Error */
 #define E1000_IMS_RXQ0      E1000_ICR_RXQ0      /* Rx Queue 0 Interrupt */
 #define E1000_IMS_RXQ1      E1000_ICR_RXQ1      /* Rx Queue 1 Interrupt */
 #define E1000_IMS_TXQ0      E1000_ICR_TXQ0      /* Tx Queue 0 Interrupt */
index 6782a2e..7e95f22 100644 (file)
@@ -309,6 +309,8 @@ struct e1000_adapter {
 
        struct napi_struct napi;
 
+       unsigned int uncorr_errors;     /* uncorrectable ECC errors */
+       unsigned int corr_errors;       /* correctable ECC errors */
        unsigned int restart_queue;
        u32 txd_cmd;
 
index f95bc6e..fd4772a 100644 (file)
@@ -108,6 +108,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
        E1000_STAT("dropped_smbus", stats.mgpdc),
        E1000_STAT("rx_dma_failed", rx_dma_failed),
        E1000_STAT("tx_dma_failed", tx_dma_failed),
+       E1000_STAT("uncorr_ecc_errors", uncorr_errors),
+       E1000_STAT("corr_ecc_errors", corr_errors),
 };
 
 #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
index cf21777..b88676f 100644 (file)
@@ -77,6 +77,7 @@ enum e1e_registers {
 #define E1000_POEMB    E1000_PHY_CTRL  /* PHY OEM Bits */
        E1000_PBA      = 0x01000, /* Packet Buffer Allocation - RW */
        E1000_PBS      = 0x01008, /* Packet Buffer Size */
+       E1000_PBECCSTS = 0x0100C, /* Packet Buffer ECC Status - RW */
        E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */
        E1000_EEWR     = 0x0102C, /* EEPROM Write Register - RW */
        E1000_FLOP     = 0x0103C, /* FLASH Opcode Register */
index 9763365..24d9f61 100644 (file)
@@ -3624,6 +3624,17 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
        if (hw->mac.type == e1000_ich8lan)
                reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
        ew32(RFCTL, reg);
+
+       /* Enable ECC on Lynxpoint */
+       if (hw->mac.type == e1000_pch_lpt) {
+               reg = er32(PBECCSTS);
+               reg |= E1000_PBECCSTS_ECC_ENABLE;
+               ew32(PBECCSTS, reg);
+
+               reg = er32(CTRL);
+               reg |= E1000_CTRL_MEHE;
+               ew32(CTRL, reg);
+       }
 }
 
 /**
index fbf75fd..643c883 100644 (file)
@@ -1678,6 +1678,23 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
+       /* Reset on uncorrectable ECC error */
+       if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
+               u32 pbeccsts = er32(PBECCSTS);
+
+               adapter->corr_errors +=
+                   pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
+               adapter->uncorr_errors +=
+                   (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
+                   E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
+
+               /* Do the reset outside of interrupt context */
+               schedule_work(&adapter->reset_task);
+
+               /* return immediately since reset is imminent */
+               return IRQ_HANDLED;
+       }
+
        if (napi_schedule_prep(&adapter->napi)) {
                adapter->total_tx_bytes = 0;
                adapter->total_tx_packets = 0;
@@ -1741,6 +1758,23 @@ static irqreturn_t e1000_intr(int irq, void *data)
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
+       /* Reset on uncorrectable ECC error */
+       if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
+               u32 pbeccsts = er32(PBECCSTS);
+
+               adapter->corr_errors +=
+                   pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
+               adapter->uncorr_errors +=
+                   (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
+                   E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
+
+               /* Do the reset outside of interrupt context */
+               schedule_work(&adapter->reset_task);
+
+               /* return immediately since reset is imminent */
+               return IRQ_HANDLED;
+       }
+
        if (napi_schedule_prep(&adapter->napi)) {
                adapter->total_tx_bytes = 0;
                adapter->total_tx_packets = 0;
@@ -2104,6 +2138,8 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
        if (adapter->msix_entries) {
                ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
                ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
+       } else if (hw->mac.type == e1000_pch_lpt) {
+               ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);
        } else {
                ew32(IMS, IMS_ENABLE_MASK);
        }
@@ -4251,6 +4287,16 @@ static void e1000e_update_stats(struct e1000_adapter *adapter)
        adapter->stats.mgptc += er32(MGTPTC);
        adapter->stats.mgprc += er32(MGTPRC);
        adapter->stats.mgpdc += er32(MGTPDC);
+
+       /* Correctable ECC Errors */
+       if (hw->mac.type == e1000_pch_lpt) {
+               u32 pbeccsts = er32(PBECCSTS);
+               adapter->corr_errors +=
+                   pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
+               adapter->uncorr_errors +=
+                   (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
+                   E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
+       }
 }
 
 /**
index a6542d7..5163af3 100644 (file)
@@ -380,7 +380,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                }
        }
 
-       if ((dev_cap->flags &
+       if ((dev->caps.flags &
            (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) &&
            mlx4_is_master(dev))
                dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE;
index 7992b3e..78ace59 100644 (file)
@@ -1801,7 +1801,7 @@ static void rhine_tx(struct net_device *dev)
                                         rp->tx_skbuff[entry]->len,
                                         PCI_DMA_TODEVICE);
                }
-               dev_kfree_skb_irq(rp->tx_skbuff[entry]);
+               dev_kfree_skb(rp->tx_skbuff[entry]);
                rp->tx_skbuff[entry] = NULL;
                entry = (++rp->dirty_tx) % TX_RING_SIZE;
        }
@@ -2010,11 +2010,7 @@ static void rhine_slow_event_task(struct work_struct *work)
        if (intr_status & IntrPCIErr)
                netif_warn(rp, hw, dev, "PCI error\n");
 
-       napi_disable(&rp->napi);
-       rhine_irq_disable(rp);
-       /* Slow and safe. Consider __napi_schedule as a replacement ? */
-       napi_enable(&rp->napi);
-       napi_schedule(&rp->napi);
+       iowrite16(RHINE_EVENT & 0xffff, rp->base + IntrEnable);
 
 out_unlock:
        mutex_unlock(&rp->task_lock);
index cc09b67..2917a86 100644 (file)
@@ -298,11 +298,12 @@ static void tun_flow_cleanup(unsigned long data)
 }
 
 static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
-                           u16 queue_index)
+                           struct tun_file *tfile)
 {
        struct hlist_head *head;
        struct tun_flow_entry *e;
        unsigned long delay = tun->ageing_time;
+       u16 queue_index = tfile->queue_index;
 
        if (!rxhash)
                return;
@@ -311,7 +312,9 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
 
        rcu_read_lock();
 
-       if (tun->numqueues == 1)
+       /* We may get a very small possibility of OOO during switching, not
+        * worth to optimize.*/
+       if (tun->numqueues == 1 || tfile->detached)
                goto unlock;
 
        e = tun_flow_find(head, rxhash);
@@ -411,21 +414,21 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
 
        tun = rtnl_dereference(tfile->tun);
 
-       if (tun) {
+       if (tun && !tfile->detached) {
                u16 index = tfile->queue_index;
                BUG_ON(index >= tun->numqueues);
                dev = tun->dev;
 
                rcu_assign_pointer(tun->tfiles[index],
                                   tun->tfiles[tun->numqueues - 1]);
-               rcu_assign_pointer(tfile->tun, NULL);
                ntfile = rtnl_dereference(tun->tfiles[index]);
                ntfile->queue_index = index;
 
                --tun->numqueues;
-               if (clean)
+               if (clean) {
+                       rcu_assign_pointer(tfile->tun, NULL);
                        sock_put(&tfile->sk);
-               else
+               else
                        tun_disable_queue(tun, tfile);
 
                synchronize_net();
@@ -439,10 +442,13 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
        }
 
        if (clean) {
-               if (tun && tun->numqueues == 0 && tun->numdisabled == 0 &&
-                   !(tun->flags & TUN_PERSIST))
-                       if (tun->dev->reg_state == NETREG_REGISTERED)
+               if (tun && tun->numqueues == 0 && tun->numdisabled == 0) {
+                       netif_carrier_off(tun->dev);
+
+                       if (!(tun->flags & TUN_PERSIST) &&
+                           tun->dev->reg_state == NETREG_REGISTERED)
                                unregister_netdevice(tun->dev);
+               }
 
                BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED,
                                 &tfile->socket.flags));
@@ -470,6 +476,10 @@ static void tun_detach_all(struct net_device *dev)
                rcu_assign_pointer(tfile->tun, NULL);
                --tun->numqueues;
        }
+       list_for_each_entry(tfile, &tun->disabled, next) {
+               wake_up_all(&tfile->wq.wait);
+               rcu_assign_pointer(tfile->tun, NULL);
+       }
        BUG_ON(tun->numqueues != 0);
 
        synchronize_net();
@@ -500,7 +510,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
                goto out;
 
        err = -EINVAL;
-       if (rtnl_dereference(tfile->tun))
+       if (rtnl_dereference(tfile->tun) && !tfile->detached)
                goto out;
 
        err = -EBUSY;
@@ -1199,7 +1209,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
        tun->dev->stats.rx_packets++;
        tun->dev->stats.rx_bytes += len;
 
-       tun_flow_update(tun, rxhash, tfile->queue_index);
+       tun_flow_update(tun, rxhash, tfile);
        return total_len;
 }
 
@@ -1658,10 +1668,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                    device_create_file(&tun->dev->dev, &dev_attr_owner) ||
                    device_create_file(&tun->dev->dev, &dev_attr_group))
                        pr_err("Failed to create tun sysfs files\n");
-
-               netif_carrier_on(tun->dev);
        }
 
+       netif_carrier_on(tun->dev);
+
        tun_debug(KERN_INFO, tun, "tun_set_iff\n");
 
        if (ifr->ifr_flags & IFF_NO_PI)
@@ -1813,7 +1823,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
                ret = tun_attach(tun, file);
        } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
                tun = rtnl_dereference(tfile->tun);
-               if (!tun || !(tun->flags & TUN_TAP_MQ))
+               if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached)
                        ret = -EINVAL;
                else
                        __tun_detach(tfile, false);
index 9197b2c..00d3b2d 100644 (file)
@@ -1215,6 +1215,9 @@ static const struct usb_device_id cdc_devs[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),
          .driver_info = (unsigned long)&wwan_info,
        },
+       { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76),
+         .driver_info = (unsigned long)&wwan_info,
+       },
 
        /* Infineon(now Intel) HSPA Modem platform */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443,
index 575a583..c8e05e2 100644 (file)
@@ -351,6 +351,10 @@ static const struct usb_device_id products[] = {
                USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57),
                .driver_info        = (unsigned long)&qmi_wwan_info,
        },
+       {       /* HUAWEI_INTERFACE_NDIS_CONTROL_QUALCOMM */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
 
        /* 2. Combined interface devices matching on class+protocol */
        {       /* Huawei E367 and possibly others in "Windows mode" */
@@ -361,6 +365,14 @@ static const struct usb_device_id products[] = {
                USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17),
                .driver_info        = (unsigned long)&qmi_wwan_info,
        },
+       {       /* HUAWEI_NDIS_SINGLE_INTERFACE_VDF */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x37),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
+       {       /* HUAWEI_INTERFACE_NDIS_HW_QUALCOMM */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x67),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
        {       /* Pantech UML290, P4200 and more */
                USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),
                .driver_info        = (unsigned long)&qmi_wwan_info,
@@ -461,6 +473,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x901c, 8)},    /* Sierra Wireless EM7700 */
        {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
        {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
+       {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
index f34b2eb..5e33606 100644 (file)
@@ -380,6 +380,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
        unsigned long           lockflags;
        size_t                  size = dev->rx_urb_size;
 
+       /* prevent rx skb allocation when error ratio is high */
+       if (test_bit(EVENT_RX_KILL, &dev->flags)) {
+               usb_free_urb(urb);
+               return -ENOLINK;
+       }
+
        skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
        if (!skb) {
                netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
@@ -539,6 +545,17 @@ block:
                break;
        }
 
+       /* stop rx if packet error rate is high */
+       if (++dev->pkt_cnt > 30) {
+               dev->pkt_cnt = 0;
+               dev->pkt_err = 0;
+       } else {
+               if (state == rx_cleanup)
+                       dev->pkt_err++;
+               if (dev->pkt_err > 20)
+                       set_bit(EVENT_RX_KILL, &dev->flags);
+       }
+
        state = defer_bh(dev, skb, &dev->rxq, state);
 
        if (urb) {
@@ -791,6 +808,11 @@ int usbnet_open (struct net_device *net)
                   (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" :
                   "simple");
 
+       /* reset rx error state */
+       dev->pkt_cnt = 0;
+       dev->pkt_err = 0;
+       clear_bit(EVENT_RX_KILL, &dev->flags);
+
        // delay posting reads until we're fully open
        tasklet_schedule (&dev->bh);
        if (info->manage_power) {
@@ -1103,13 +1125,11 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
        if (info->tx_fixup) {
                skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
                if (!skb) {
-                       if (netif_msg_tx_err(dev)) {
-                               netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
-                               goto drop;
-                       } else {
-                               /* cdc_ncm collected packet; waits for more */
+                       /* packet collected; minidriver waiting for more */
+                       if (info->flags & FLAG_MULTI_PACKET)
                                goto not_drop;
-                       }
+                       netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
+                       goto drop;
                }
        }
        length = skb->len;
@@ -1254,6 +1274,9 @@ static void usbnet_bh (unsigned long param)
                }
        }
 
+       /* restart RX again after disabling due to high error rate */
+       clear_bit(EVENT_RX_KILL, &dev->flags);
+
        // waiting for all pending urbs to complete?
        if (dev->wait) {
                if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {
index dc8913c..12c6440 100644 (file)
@@ -154,8 +154,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
        if (ret & 1) { /* Link is up. */
                printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n",
                       adapter->netdev->name, adapter->link_speed);
-               if (!netif_carrier_ok(adapter->netdev))
-                       netif_carrier_on(adapter->netdev);
+               netif_carrier_on(adapter->netdev);
 
                if (affectTxQueue) {
                        for (i = 0; i < adapter->num_tx_queues; i++)
@@ -165,8 +164,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
        } else {
                printk(KERN_INFO "%s: NIC Link is Down\n",
                       adapter->netdev->name);
-               if (netif_carrier_ok(adapter->netdev))
-                       netif_carrier_off(adapter->netdev);
+               netif_carrier_off(adapter->netdev);
 
                if (affectTxQueue) {
                        for (i = 0; i < adapter->num_tx_queues; i++)
@@ -3061,6 +3059,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
        netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
        netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues);
 
+       netif_carrier_off(netdev);
        err = register_netdev(netdev);
 
        if (err) {
index 0f71d1d..e5fd209 100644 (file)
@@ -36,6 +36,7 @@
 #include "debug.h"
 
 #define N_TX_QUEUES    4 /* #tx queues on mac80211<->driver interface */
+#define BRCMS_FLUSH_TIMEOUT    500 /* msec */
 
 /* Flags we support */
 #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
@@ -708,16 +709,29 @@ static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
        wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
 }
 
+static bool brcms_tx_flush_completed(struct brcms_info *wl)
+{
+       bool result;
+
+       spin_lock_bh(&wl->lock);
+       result = brcms_c_tx_flush_completed(wl->wlc);
+       spin_unlock_bh(&wl->lock);
+       return result;
+}
+
 static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
 {
        struct brcms_info *wl = hw->priv;
+       int ret;
 
        no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
 
-       /* wait for packet queue and dma fifos to run empty */
-       spin_lock_bh(&wl->lock);
-       brcms_c_wait_for_tx_completion(wl->wlc, drop);
-       spin_unlock_bh(&wl->lock);
+       ret = wait_event_timeout(wl->tx_flush_wq,
+                                brcms_tx_flush_completed(wl),
+                                msecs_to_jiffies(BRCMS_FLUSH_TIMEOUT));
+
+       brcms_dbg_mac80211(wl->wlc->hw->d11core,
+                          "ret=%d\n", jiffies_to_msecs(ret));
 }
 
 static const struct ieee80211_ops brcms_ops = {
@@ -772,6 +786,7 @@ void brcms_dpc(unsigned long data)
 
  done:
        spin_unlock_bh(&wl->lock);
+       wake_up(&wl->tx_flush_wq);
 }
 
 /*
@@ -1020,6 +1035,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
 
        atomic_set(&wl->callbacks, 0);
 
+       init_waitqueue_head(&wl->tx_flush_wq);
+
        /* setup the bottom half handler */
        tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
 
@@ -1609,13 +1626,3 @@ bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
        spin_lock_bh(&wl->lock);
        return blocked;
 }
-
-/*
- * precondition: perimeter lock has been acquired
- */
-void brcms_msleep(struct brcms_info *wl, uint ms)
-{
-       spin_unlock_bh(&wl->lock);
-       msleep(ms);
-       spin_lock_bh(&wl->lock);
-}
index 9358bd5..947ccac 100644 (file)
@@ -68,6 +68,8 @@ struct brcms_info {
        spinlock_t lock;        /* per-device perimeter lock */
        spinlock_t isr_lock;    /* per-device ISR synchronization lock */
 
+       /* tx flush */
+       wait_queue_head_t tx_flush_wq;
 
        /* timer related fields */
        atomic_t callbacks;     /* # outstanding callback functions */
@@ -100,7 +102,6 @@ extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
 extern void brcms_free_timer(struct brcms_timer *timer);
 extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
 extern bool brcms_del_timer(struct brcms_timer *timer);
-extern void brcms_msleep(struct brcms_info *wl, uint ms);
 extern void brcms_dpc(unsigned long data);
 extern void brcms_timer(struct brcms_timer *t);
 extern void brcms_fatal_error(struct brcms_info *wl);
index 17594de..8b58390 100644 (file)
@@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
 static bool
 brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
 {
-       bool morepending = false;
        struct bcma_device *core;
        struct tx_status txstatus, *txs;
        u32 s1, s2;
@@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
        txs = &txstatus;
        core = wlc_hw->d11core;
        *fatal = false;
-       s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
-       while (!(*fatal)
-              && (s1 & TXS_V)) {
-               /* !give others some time to run! */
-               if (n >= max_tx_num) {
-                       morepending = true;
-                       break;
-               }
 
+       while (n < max_tx_num) {
+               s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
                if (s1 == 0xffffffff) {
                        brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
                                  __func__);
                        *fatal = true;
                        return false;
                }
-               s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
+               /* only process when valid */
+               if (!(s1 & TXS_V))
+                       break;
 
+               s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
                txs->status = s1 & TXS_STATUS_MASK;
                txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
                txs->sequence = s2 & TXS_SEQ_MASK;
@@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
                txs->lasttxtime = 0;
 
                *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
-
-               s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
+               if (*fatal == true)
+                       return false;
                n++;
        }
 
-       if (*fatal)
-               return false;
-
-       return morepending;
+       return n >= max_tx_num;
 }
 
 static void brcms_c_tbtt(struct brcms_c_info *wlc)
@@ -7518,25 +7511,16 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)
        return wlc->band->bandunit;
 }
 
-void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
+bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc)
 {
-       int timeout = 20;
        int i;
 
        /* Kick DMA to send any pending AMPDU */
        for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
                if (wlc->hw->di[i])
-                       dma_txflush(wlc->hw->di[i]);
-
-       /* wait for queue and DMA fifos to run dry */
-       while (brcms_txpktpendtot(wlc) > 0) {
-               brcms_msleep(wlc->wl, 1);
-
-               if (--timeout == 0)
-                       break;
-       }
+                       dma_kick_tx(wlc->hw->di[i]);
 
-       WARN_ON_ONCE(timeout == 0);
+       return !brcms_txpktpendtot(wlc);
 }
 
 void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
index 4fb2834..b0f14b7 100644 (file)
@@ -314,8 +314,6 @@ extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
 extern void brcms_c_scan_start(struct brcms_c_info *wlc);
 extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
 extern int brcms_c_get_curband(struct brcms_c_info *wlc);
-extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
-                                          bool drop);
 extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
 extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
 extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
@@ -332,5 +330,6 @@ extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
 extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
 extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
 extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
+extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
 
 #endif                         /* _BRCM_PUB_H_ */
index 31534f7..2797964 100644 (file)
@@ -1153,6 +1153,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                        next_reclaimed = ssn;
                }
 
+               if (tid != IWL_TID_NON_QOS) {
+                       priv->tid_data[sta_id][tid].next_reclaimed =
+                               next_reclaimed;
+                       IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
+                                                 next_reclaimed);
+               }
+
                iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
 
                iwlagn_check_ratid_empty(priv, sta_id, tid);
@@ -1203,28 +1210,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                        if (!is_agg)
                                iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
 
-                       /*
-                        * W/A for FW bug - the seq_ctl isn't updated when the
-                        * queues are flushed. Fetch it from the packet itself
-                        */
-                       if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) {
-                               next_reclaimed = le16_to_cpu(hdr->seq_ctrl);
-                               next_reclaimed =
-                                       SEQ_TO_SN(next_reclaimed + 0x10);
-                       }
-
                        is_offchannel_skb =
                                (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);
                        freed++;
                }
 
-               if (tid != IWL_TID_NON_QOS) {
-                       priv->tid_data[sta_id][tid].next_reclaimed =
-                               next_reclaimed;
-                       IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
-                                          next_reclaimed);
-               }
-
                WARN_ON(!is_agg && freed != 1);
 
                /*
index 9189a32..973a9d9 100644 (file)
@@ -1563,7 +1563,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
                        scan_rsp->number_of_sets);
                ret = -1;
-               goto done;
+               goto check_next_scan;
        }
 
        bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
@@ -1634,7 +1634,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                if (!beacon_size || beacon_size > bytes_left) {
                        bss_info += bytes_left;
                        bytes_left = 0;
-                       return -1;
+                       ret = -1;
+                       goto check_next_scan;
                }
 
                /* Initialize the current working beacon pointer for this BSS
@@ -1690,7 +1691,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                                dev_err(priv->adapter->dev,
                                        "%s: bytes left < IE length\n",
                                        __func__);
-                               goto done;
+                               goto check_next_scan;
                        }
                        if (element_id == WLAN_EID_DS_PARAMS) {
                                channel = *(current_ptr + sizeof(struct ieee_types_header));
@@ -1753,6 +1754,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                }
        }
 
+check_next_scan:
        spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
        if (list_empty(&adapter->scan_pending_q)) {
                spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
@@ -1813,7 +1815,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                }
        }
 
-done:
        return ret;
 }
 
index 4494d13..0f8b051 100644 (file)
@@ -1004,7 +1004,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                                         is_tx ? "Tx" : "Rx");
 
                                if (is_tx) {
-                                       rtl_lps_leave(hw);
+                                       schedule_work(&rtlpriv->
+                                                     works.lps_leave_work);
                                        ppsc->last_delaylps_stamp_jiffies =
                                            jiffies;
                                }
@@ -1014,7 +1015,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                }
        } else if (ETH_P_ARP == ether_type) {
                if (is_tx) {
-                       rtl_lps_leave(hw);
+                       schedule_work(&rtlpriv->works.lps_leave_work);
                        ppsc->last_delaylps_stamp_jiffies = jiffies;
                }
 
@@ -1024,7 +1025,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                         "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");
 
                if (is_tx) {
-                       rtl_lps_leave(hw);
+                       schedule_work(&rtlpriv->works.lps_leave_work);
                        ppsc->last_delaylps_stamp_jiffies = jiffies;
                }
 
index f2ecdeb..1535efd 100644 (file)
@@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
        WARN_ON(skb_queue_empty(&rx_queue));
        while (!skb_queue_empty(&rx_queue)) {
                _skb = skb_dequeue(&rx_queue);
-               _rtl_usb_rx_process_agg(hw, skb);
-               ieee80211_rx_irqsafe(hw, skb);
+               _rtl_usb_rx_process_agg(hw, _skb);
+               ieee80211_rx_irqsafe(hw, _skb);
        }
 }
 
index 94b79c3..9d7f172 100644 (file)
@@ -151,6 +151,9 @@ void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb);
 /* Notify xenvif that ring now has space to send an skb to the frontend */
 void xenvif_notify_tx_completion(struct xenvif *vif);
 
+/* Prevent the device from generating any further traffic. */
+void xenvif_carrier_off(struct xenvif *vif);
+
 /* Returns number of ring slots required to send an skb to the frontend */
 unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb);
 
index b7d41f8..b8c5193 100644 (file)
@@ -343,17 +343,22 @@ err:
        return err;
 }
 
-void xenvif_disconnect(struct xenvif *vif)
+void xenvif_carrier_off(struct xenvif *vif)
 {
        struct net_device *dev = vif->dev;
-       if (netif_carrier_ok(dev)) {
-               rtnl_lock();
-               netif_carrier_off(dev); /* discard queued packets */
-               if (netif_running(dev))
-                       xenvif_down(vif);
-               rtnl_unlock();
-               xenvif_put(vif);
-       }
+
+       rtnl_lock();
+       netif_carrier_off(dev); /* discard queued packets */
+       if (netif_running(dev))
+               xenvif_down(vif);
+       rtnl_unlock();
+       xenvif_put(vif);
+}
+
+void xenvif_disconnect(struct xenvif *vif)
+{
+       if (netif_carrier_ok(vif->dev))
+               xenvif_carrier_off(vif);
 
        atomic_dec(&vif->refcnt);
        wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
index f2d6b78..2b9520c 100644 (file)
@@ -147,7 +147,8 @@ void xen_netbk_remove_xenvif(struct xenvif *vif)
        atomic_dec(&netbk->netfront_count);
 }
 
-static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx);
+static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx,
+                                 u8 status);
 static void make_tx_response(struct xenvif *vif,
                             struct xen_netif_tx_request *txp,
                             s8       st);
@@ -879,7 +880,7 @@ static void netbk_tx_err(struct xenvif *vif,
 
        do {
                make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR);
-               if (cons >= end)
+               if (cons == end)
                        break;
                txp = RING_GET_REQUEST(&vif->tx, cons++);
        } while (1);
@@ -888,6 +889,13 @@ static void netbk_tx_err(struct xenvif *vif,
        xenvif_put(vif);
 }
 
+static void netbk_fatal_tx_err(struct xenvif *vif)
+{
+       netdev_err(vif->dev, "fatal error; disabling device\n");
+       xenvif_carrier_off(vif);
+       xenvif_put(vif);
+}
+
 static int netbk_count_requests(struct xenvif *vif,
                                struct xen_netif_tx_request *first,
                                struct xen_netif_tx_request *txp,
@@ -901,19 +909,22 @@ static int netbk_count_requests(struct xenvif *vif,
 
        do {
                if (frags >= work_to_do) {
-                       netdev_dbg(vif->dev, "Need more frags\n");
+                       netdev_err(vif->dev, "Need more frags\n");
+                       netbk_fatal_tx_err(vif);
                        return -frags;
                }
 
                if (unlikely(frags >= MAX_SKB_FRAGS)) {
-                       netdev_dbg(vif->dev, "Too many frags\n");
+                       netdev_err(vif->dev, "Too many frags\n");
+                       netbk_fatal_tx_err(vif);
                        return -frags;
                }
 
                memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags),
                       sizeof(*txp));
                if (txp->size > first->size) {
-                       netdev_dbg(vif->dev, "Frags galore\n");
+                       netdev_err(vif->dev, "Frag is bigger than frame.\n");
+                       netbk_fatal_tx_err(vif);
                        return -frags;
                }
 
@@ -921,8 +932,9 @@ static int netbk_count_requests(struct xenvif *vif,
                frags++;
 
                if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
-                       netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n",
+                       netdev_err(vif->dev, "txp->offset: %x, size: %u\n",
                                 txp->offset, txp->size);
+                       netbk_fatal_tx_err(vif);
                        return -frags;
                }
        } while ((txp++)->flags & XEN_NETTXF_more_data);
@@ -966,7 +978,7 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk,
                pending_idx = netbk->pending_ring[index];
                page = xen_netbk_alloc_page(netbk, skb, pending_idx);
                if (!page)
-                       return NULL;
+                       goto err;
 
                gop->source.u.ref = txp->gref;
                gop->source.domid = vif->domid;
@@ -988,6 +1000,17 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk,
        }
 
        return gop;
+err:
+       /* Unwind, freeing all pages and sending error responses. */
+       while (i-- > start) {
+               xen_netbk_idx_release(netbk, frag_get_pending_idx(&frags[i]),
+                                     XEN_NETIF_RSP_ERROR);
+       }
+       /* The head too, if necessary. */
+       if (start)
+               xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR);
+
+       return NULL;
 }
 
 static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,
@@ -996,30 +1019,20 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,
 {
        struct gnttab_copy *gop = *gopp;
        u16 pending_idx = *((u16 *)skb->data);
-       struct pending_tx_info *pending_tx_info = netbk->pending_tx_info;
-       struct xenvif *vif = pending_tx_info[pending_idx].vif;
-       struct xen_netif_tx_request *txp;
        struct skb_shared_info *shinfo = skb_shinfo(skb);
        int nr_frags = shinfo->nr_frags;
        int i, err, start;
 
        /* Check status of header. */
        err = gop->status;
-       if (unlikely(err)) {
-               pending_ring_idx_t index;
-               index = pending_index(netbk->pending_prod++);
-               txp = &pending_tx_info[pending_idx].req;
-               make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR);
-               netbk->pending_ring[index] = pending_idx;
-               xenvif_put(vif);
-       }
+       if (unlikely(err))
+               xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR);
 
        /* Skip first skb fragment if it is on same page as header fragment. */
        start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx);
 
        for (i = start; i < nr_frags; i++) {
                int j, newerr;
-               pending_ring_idx_t index;
 
                pending_idx = frag_get_pending_idx(&shinfo->frags[i]);
 
@@ -1028,16 +1041,12 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,
                if (likely(!newerr)) {
                        /* Had a previous error? Invalidate this fragment. */
                        if (unlikely(err))
-                               xen_netbk_idx_release(netbk, pending_idx);
+                               xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);
                        continue;
                }
 
                /* Error on this fragment: respond to client with an error. */
-               txp = &netbk->pending_tx_info[pending_idx].req;
-               make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR);
-               index = pending_index(netbk->pending_prod++);
-               netbk->pending_ring[index] = pending_idx;
-               xenvif_put(vif);
+               xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR);
 
                /* Not the first error? Preceding frags already invalidated. */
                if (err)
@@ -1045,10 +1054,10 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,
 
                /* First error: invalidate header and preceding fragments. */
                pending_idx = *((u16 *)skb->data);
-               xen_netbk_idx_release(netbk, pending_idx);
+               xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);
                for (j = start; j < i; j++) {
                        pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
-                       xen_netbk_idx_release(netbk, pending_idx);
+                       xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);
                }
 
                /* Remember the error: invalidate all subsequent fragments. */
@@ -1082,7 +1091,7 @@ static void xen_netbk_fill_frags(struct xen_netbk *netbk, struct sk_buff *skb)
 
                /* Take an extra reference to offset xen_netbk_idx_release */
                get_page(netbk->mmap_pages[pending_idx]);
-               xen_netbk_idx_release(netbk, pending_idx);
+               xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);
        }
 }
 
@@ -1095,7 +1104,8 @@ static int xen_netbk_get_extras(struct xenvif *vif,
 
        do {
                if (unlikely(work_to_do-- <= 0)) {
-                       netdev_dbg(vif->dev, "Missing extra info\n");
+                       netdev_err(vif->dev, "Missing extra info\n");
+                       netbk_fatal_tx_err(vif);
                        return -EBADR;
                }
 
@@ -1104,8 +1114,9 @@ static int xen_netbk_get_extras(struct xenvif *vif,
                if (unlikely(!extra.type ||
                             extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
                        vif->tx.req_cons = ++cons;
-                       netdev_dbg(vif->dev,
+                       netdev_err(vif->dev,
                                   "Invalid extra type: %d\n", extra.type);
+                       netbk_fatal_tx_err(vif);
                        return -EINVAL;
                }
 
@@ -1121,13 +1132,15 @@ static int netbk_set_skb_gso(struct xenvif *vif,
                             struct xen_netif_extra_info *gso)
 {
        if (!gso->u.gso.size) {
-               netdev_dbg(vif->dev, "GSO size must not be zero.\n");
+               netdev_err(vif->dev, "GSO size must not be zero.\n");
+               netbk_fatal_tx_err(vif);
                return -EINVAL;
        }
 
        /* Currently only TCPv4 S.O. is supported. */
        if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
-               netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type);
+               netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type);
+               netbk_fatal_tx_err(vif);
                return -EINVAL;
        }
 
@@ -1264,9 +1277,25 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
 
                /* Get a netif from the list with work to do. */
                vif = poll_net_schedule_list(netbk);
+               /* This can sometimes happen because the test of
+                * list_empty(net_schedule_list) at the top of the
+                * loop is unlocked.  Just go back and have another
+                * look.
+                */
                if (!vif)
                        continue;
 
+               if (vif->tx.sring->req_prod - vif->tx.req_cons >
+                   XEN_NETIF_TX_RING_SIZE) {
+                       netdev_err(vif->dev,
+                                  "Impossible number of requests. "
+                                  "req_prod %d, req_cons %d, size %ld\n",
+                                  vif->tx.sring->req_prod, vif->tx.req_cons,
+                                  XEN_NETIF_TX_RING_SIZE);
+                       netbk_fatal_tx_err(vif);
+                       continue;
+               }
+
                RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do);
                if (!work_to_do) {
                        xenvif_put(vif);
@@ -1294,17 +1323,14 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
                        work_to_do = xen_netbk_get_extras(vif, extras,
                                                          work_to_do);
                        idx = vif->tx.req_cons;
-                       if (unlikely(work_to_do < 0)) {
-                               netbk_tx_err(vif, &txreq, idx);
+                       if (unlikely(work_to_do < 0))
                                continue;
-                       }
                }
 
                ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do);
-               if (unlikely(ret < 0)) {
-                       netbk_tx_err(vif, &txreq, idx - ret);
+               if (unlikely(ret < 0))
                        continue;
-               }
+
                idx += ret;
 
                if (unlikely(txreq.size < ETH_HLEN)) {
@@ -1316,11 +1342,11 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
 
                /* No crossing a page as the payload mustn't fragment. */
                if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
-                       netdev_dbg(vif->dev,
+                       netdev_err(vif->dev,
                                   "txreq.offset: %x, size: %u, end: %lu\n",
                                   txreq.offset, txreq.size,
                                   (txreq.offset&~PAGE_MASK) + txreq.size);
-                       netbk_tx_err(vif, &txreq, idx);
+                       netbk_fatal_tx_err(vif);
                        continue;
                }
 
@@ -1348,8 +1374,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
                        gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
 
                        if (netbk_set_skb_gso(vif, skb, gso)) {
+                               /* Failure in netbk_set_skb_gso is fatal. */
                                kfree_skb(skb);
-                               netbk_tx_err(vif, &txreq, idx);
                                continue;
                        }
                }
@@ -1448,7 +1474,7 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk)
                        txp->size -= data_len;
                } else {
                        /* Schedule a response immediately. */
-                       xen_netbk_idx_release(netbk, pending_idx);
+                       xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY);
                }
 
                if (txp->flags & XEN_NETTXF_csum_blank)
@@ -1500,7 +1526,8 @@ static void xen_netbk_tx_action(struct xen_netbk *netbk)
        xen_netbk_tx_submit(netbk);
 }
 
-static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx)
+static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx,
+                                 u8 status)
 {
        struct xenvif *vif;
        struct pending_tx_info *pending_tx_info;
@@ -1514,7 +1541,7 @@ static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx)
 
        vif = pending_tx_info->vif;
 
-       make_tx_response(vif, &pending_tx_info->req, XEN_NETIF_RSP_OKAY);
+       make_tx_response(vif, &pending_tx_info->req, status);
 
        index = pending_index(netbk->pending_prod++);
        netbk->pending_ring[index] = pending_idx;
index 3d6d4fd..a951c22 100644 (file)
@@ -734,34 +734,24 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
  */
 static int acpiphp_bus_add(struct acpiphp_func *func)
 {
-       acpi_handle phandle;
-       struct acpi_device *device, *pdevice;
+       struct acpi_device *device;
        int ret_val;
 
-       acpi_get_parent(func->handle, &phandle);
-       if (acpi_bus_get_device(phandle, &pdevice)) {
-               dbg("no parent device, assuming NULL\n");
-               pdevice = NULL;
-       }
        if (!acpi_bus_get_device(func->handle, &device)) {
                dbg("bus exists... trim\n");
                /* this shouldn't be in here, so remove
                 * the bus then re-add it...
                 */
-               ret_val = acpi_bus_trim(device, 1);
-               dbg("acpi_bus_trim return %x\n", ret_val);
+               acpi_bus_trim(device);
        }
 
-       ret_val = acpi_bus_add(&device, pdevice, func->handle,
-               ACPI_BUS_TYPE_DEVICE);
-       if (ret_val) {
-               dbg("error adding bus, %x\n",
-                       -ret_val);
-               goto acpiphp_bus_add_out;
-       }
-       ret_val = acpi_bus_start(device);
+       ret_val = acpi_bus_scan(func->handle);
+       if (!ret_val)
+               ret_val = acpi_bus_get_device(func->handle, &device);
+
+       if (ret_val)
+               dbg("error adding bus, %x\n", -ret_val);
 
-acpiphp_bus_add_out:
        return ret_val;
 }
 
@@ -781,11 +771,8 @@ static int acpiphp_bus_trim(acpi_handle handle)
                return retval;
        }
 
-       retval = acpi_bus_trim(device, 1);
-       if (retval)
-               err("cannot remove from acpi list\n");
-
-       return retval;
+       acpi_bus_trim(device);
+       return 0;
 }
 
 static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
@@ -1130,8 +1117,7 @@ static int acpiphp_configure_bridge (acpi_handle handle)
 
 static void handle_bridge_insertion(acpi_handle handle, u32 type)
 {
-       struct acpi_device *device, *pdevice;
-       acpi_handle phandle;
+       struct acpi_device *device;
 
        if ((type != ACPI_NOTIFY_BUS_CHECK) &&
                        (type != ACPI_NOTIFY_DEVICE_CHECK)) {
@@ -1139,17 +1125,15 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type)
                return;
        }
 
-       acpi_get_parent(handle, &phandle);
-       if (acpi_bus_get_device(phandle, &pdevice)) {
-               dbg("no parent device, assuming NULL\n");
-               pdevice = NULL;
-       }
-       if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
+       if (acpi_bus_scan(handle)) {
                err("cannot add bridge to acpi list\n");
                return;
        }
-       if (!acpiphp_configure_bridge(handle) &&
-               !acpi_bus_start(device))
+       if (acpi_bus_get_device(handle, &device)) {
+               err("ACPI device object missing\n");
+               return;
+       }
+       if (!acpiphp_configure_bridge(handle))
                add_bridge(handle);
        else
                err("cannot configure and start bridge\n");
@@ -1234,6 +1218,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
        handle = hp_work->handle;
        type = hp_work->type;
 
+       acpi_scan_lock_acquire();
+
        if (acpi_bus_get_device(handle, &device)) {
                /* This bridge must have just been physically inserted */
                handle_bridge_insertion(handle, type);
@@ -1311,6 +1297,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
        }
 
 out:
+       acpi_scan_lock_release();
        kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
 }
 
@@ -1357,6 +1344,8 @@ static void _handle_hotplug_event_func(struct work_struct *work)
 
        func = (struct acpiphp_func *)context;
 
+       acpi_scan_lock_acquire();
+
        switch (type) {
        case ACPI_NOTIFY_BUS_CHECK:
                /* bus re-enumerate */
@@ -1387,6 +1376,7 @@ static void _handle_hotplug_event_func(struct work_struct *work)
                break;
        }
 
+       acpi_scan_lock_release();
        kfree(hp_work); /* allocated in handle_hotplug_event_func */
 }
 
index f64ca92..574421b 100644 (file)
@@ -412,7 +412,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
        if (SN_ACPI_BASE_SUPPORT() && ssdt) {
                unsigned long long adr;
                struct acpi_device *pdevice;
-               struct acpi_device *device;
                acpi_handle phandle;
                acpi_handle chandle = NULL;
                acpi_handle rethandle;
@@ -426,6 +425,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
                        pdevice = NULL;
                }
 
+               acpi_scan_lock_acquire();
                /*
                 * Walk the rootbus node's immediate children looking for
                 * the slot's device node(s). There can be more than
@@ -448,20 +448,18 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
                        if (ACPI_SUCCESS(ret) &&
                            (adr>>16) == (slot->device_num + 1)) {
 
-                               ret = acpi_bus_add(&device, pdevice, chandle,
-                                                  ACPI_BUS_TYPE_DEVICE);
+                               ret = acpi_bus_scan(chandle);
                                if (ACPI_FAILURE(ret)) {
-                                       printk(KERN_ERR "%s: acpi_bus_add "
+                                       printk(KERN_ERR "%s: acpi_bus_scan "
                                               "failed (0x%x) for slot %d "
                                               "func %d\n", __func__,
                                               ret, (int)(adr>>16),
                                               (int)(adr&0xffff));
                                        /* try to continue on */
-                               } else {
-                                       acpi_bus_start(device);
                                }
                        }
                }
+               acpi_scan_lock_release();
        }
 
        /* Call the driver for the new device */
@@ -512,6 +510,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
                /* Get the rootbus node pointer */
                phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;
 
+               acpi_scan_lock_acquire();
                /*
                 * Walk the rootbus node's immediate children looking for
                 * the slot's device node(s). There can be more than
@@ -539,10 +538,10 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
                                ret = acpi_bus_get_device(chandle,
                                                          &device);
                                if (ACPI_SUCCESS(ret))
-                                       acpi_bus_trim(device, 1);
+                                       acpi_bus_trim(device);
                        }
                }
-
+               acpi_scan_lock_release();
        }
 
        /* Free the SN resources assigned to the Linux device.*/
index 1af4008..e407c61 100644 (file)
@@ -283,7 +283,6 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = {
        .is_manageable = acpi_pci_power_manageable,
        .set_state = acpi_pci_set_power_state,
        .choose_state = acpi_pci_choose_state,
-       .can_wakeup = acpi_pci_can_wakeup,
        .sleep_wake = acpi_pci_sleep_wake,
        .run_wake = acpi_pci_run_wake,
 };
@@ -321,10 +320,65 @@ static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
        return 0;
 }
 
+static void pci_acpi_setup(struct device *dev)
+{
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       acpi_handle handle = ACPI_HANDLE(dev);
+       struct acpi_device *adev;
+       acpi_status status;
+       acpi_handle dummy;
+
+       /*
+        * Evaluate and parse _PRT, if exists.  This code allows parsing of
+        * _PRT objects within the scope of non-bridge devices.  Note that
+        * _PRTs within the scope of a PCI bridge assume the bridge's
+        * subordinate bus number.
+        *
+        * TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
+        */
+       status = acpi_get_handle(handle, METHOD_NAME__PRT, &dummy);
+       if (ACPI_SUCCESS(status)) {
+               unsigned char bus;
+
+               bus = pci_dev->subordinate ?
+                       pci_dev->subordinate->number : pci_dev->bus->number;
+               acpi_pci_irq_add_prt(handle, pci_domain_nr(pci_dev->bus), bus);
+       }
+
+       if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid)
+               return;
+
+       device_set_wakeup_capable(dev, true);
+       acpi_pci_sleep_wake(pci_dev, false);
+
+       pci_acpi_add_pm_notifier(adev, pci_dev);
+       if (adev->wakeup.flags.run_wake)
+               device_set_run_wake(dev, true);
+}
+
+static void pci_acpi_cleanup(struct device *dev)
+{
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       acpi_handle handle = ACPI_HANDLE(dev);
+       struct acpi_device *adev;
+
+       if (!acpi_bus_get_device(handle, &adev) && adev->wakeup.flags.valid) {
+               device_set_wakeup_capable(dev, false);
+               device_set_run_wake(dev, false);
+               pci_acpi_remove_pm_notifier(adev);
+       }
+
+       if (pci_dev->subordinate)
+               acpi_pci_irq_del_prt(pci_domain_nr(pci_dev->bus),
+                                    pci_dev->subordinate->number);
+}
+
 static struct acpi_bus_type acpi_pci_bus = {
        .bus = &pci_bus_type,
        .find_device = acpi_pci_find_device,
        .find_bridge = acpi_pci_find_root_bridge,
+       .setup = pci_acpi_setup,
+       .cleanup = pci_acpi_cleanup,
 };
 
 static int __init acpi_pci_init(void)
index 5cb5820..0c4f641 100644 (file)
@@ -450,7 +450,7 @@ static struct pci_platform_pm_ops *pci_platform_pm;
 int pci_set_platform_pm(struct pci_platform_pm_ops *ops)
 {
        if (!ops->is_manageable || !ops->set_state || !ops->choose_state
-           || !ops->sleep_wake || !ops->can_wakeup)
+           || !ops->sleep_wake)
                return -EINVAL;
        pci_platform_pm = ops;
        return 0;
@@ -473,11 +473,6 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
                        pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
 }
 
-static inline bool platform_pci_can_wakeup(struct pci_dev *dev)
-{
-       return pci_platform_pm ? pci_platform_pm->can_wakeup(dev) : false;
-}
-
 static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
 {
        return pci_platform_pm ?
@@ -1985,25 +1980,6 @@ void pci_pm_init(struct pci_dev *dev)
        }
 }
 
-/**
- * platform_pci_wakeup_init - init platform wakeup if present
- * @dev: PCI device
- *
- * Some devices don't have PCI PM caps but can still generate wakeup
- * events through platform methods (like ACPI events).  If @dev supports
- * platform wakeup events, set the device flag to indicate as much.  This
- * may be redundant if the device also supports PCI PM caps, but double
- * initialization should be safe in that case.
- */
-void platform_pci_wakeup_init(struct pci_dev *dev)
-{
-       if (!platform_pci_can_wakeup(dev))
-               return;
-
-       device_set_wakeup_capable(&dev->dev, true);
-       platform_pci_sleep_wake(dev, false);
-}
-
 static void pci_add_saved_cap(struct pci_dev *pci_dev,
        struct pci_cap_saved_state *new_cap)
 {
index e851829..adfd172 100644 (file)
@@ -43,9 +43,6 @@ int pci_probe_reset_function(struct pci_dev *dev);
  *                platform; to be used during system-wide transitions from a
  *                sleeping state to the working state and vice versa
  *
- * @can_wakeup: returns 'true' if given device is capable of waking up the
- *              system from a sleeping state
- *
  * @sleep_wake: enables/disables the system wake up capability of given device
  *
  * @run_wake: enables/disables the platform to generate run-time wake-up events
@@ -59,7 +56,6 @@ struct pci_platform_pm_ops {
        bool (*is_manageable)(struct pci_dev *dev);
        int (*set_state)(struct pci_dev *dev, pci_power_t state);
        pci_power_t (*choose_state)(struct pci_dev *dev);
-       bool (*can_wakeup)(struct pci_dev *dev);
        int (*sleep_wake)(struct pci_dev *dev, bool enable);
        int (*run_wake)(struct pci_dev *dev, bool enable);
 };
@@ -74,7 +70,6 @@ extern void pci_wakeup_bus(struct pci_bus *bus);
 extern void pci_config_pm_runtime_get(struct pci_dev *dev);
 extern void pci_config_pm_runtime_put(struct pci_dev *dev);
 extern void pci_pm_init(struct pci_dev *dev);
-extern void platform_pci_wakeup_init(struct pci_dev *dev);
 extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
 void pci_free_cap_save_buffers(struct pci_dev *dev);
 
index 6186f03..2dcd22d 100644 (file)
@@ -1280,7 +1280,6 @@ static void pci_init_capabilities(struct pci_dev *dev)
 
        /* Power Management */
        pci_pm_init(dev);
-       platform_pci_wakeup_init(dev);
 
        /* Vital Product Data */
        pci_vpd_pci22_init(dev);
index efaecef..a5f3c8c 100644 (file)
@@ -184,8 +184,8 @@ config PINCTRL_SAMSUNG
        select PINMUX
        select PINCONF
 
-config PINCTRL_EXYNOS4
-       bool "Pinctrl driver data for Exynos4 SoC"
+config PINCTRL_EXYNOS
+       bool "Pinctrl driver data for Samsung EXYNOS SoCs"
        depends on OF && GPIOLIB
        select PINCTRL_SAMSUNG
 
index fc4606f..6e87e52 100644 (file)
@@ -36,7 +36,7 @@ obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
 obj-$(CONFIG_PINCTRL_U300)     += pinctrl-u300.o
 obj-$(CONFIG_PINCTRL_COH901)   += pinctrl-coh901.o
 obj-$(CONFIG_PINCTRL_SAMSUNG)  += pinctrl-samsung.o
-obj-$(CONFIG_PINCTRL_EXYNOS4)  += pinctrl-exynos.o
+obj-$(CONFIG_PINCTRL_EXYNOS  += pinctrl-exynos.o
 obj-$(CONFIG_PINCTRL_EXYNOS5440)       += pinctrl-exynos5440.o
 obj-$(CONFIG_PINCTRL_XWAY)     += pinctrl-xway.o
 obj-$(CONFIG_PINCTRL_LANTIQ)   += pinctrl-lantiq.o
index 498b2ba..d02498b 100644 (file)
@@ -1246,6 +1246,22 @@ static void __iomem *sirfsoc_rsc_of_iomap(void)
        return of_iomap(np, 0);
 }
 
+static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc,
+       const struct of_phandle_args *gpiospec,
+       u32 *flags)
+{
+       if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE)
+               return -EINVAL;
+
+       if (gc != &sgpio_bank[gpiospec->args[0] / SIRFSOC_GPIO_BANK_SIZE].chip.gc)
+               return -EINVAL;
+
+       if (flags)
+               *flags = gpiospec->args[1];
+
+       return gpiospec->args[0] % SIRFSOC_GPIO_BANK_SIZE;
+}
+
 static int sirfsoc_pinmux_probe(struct platform_device *pdev)
 {
        int ret;
@@ -1736,6 +1752,8 @@ static int sirfsoc_gpio_probe(struct device_node *np)
                bank->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE;
                bank->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL);
                bank->chip.gc.of_node = np;
+               bank->chip.gc.of_xlate = sirfsoc_gpio_of_xlate;
+               bank->chip.gc.of_gpio_n_cells = 2;
                bank->chip.regs = regs;
                bank->id = i;
                bank->is_marco = is_marco;
index fcde4e5..d9f9a0d 100644 (file)
@@ -1910,7 +1910,7 @@ fail_platform:
        return result;
 }
 
-static int asus_acpi_remove(struct acpi_device *device, int type)
+static int asus_acpi_remove(struct acpi_device *device)
 {
        struct asus_laptop *asus = acpi_driver_data(device);
 
index c87ff16..36e5e6c 100644 (file)
@@ -432,7 +432,7 @@ failed_sensitivity:
        return error;
 }
 
-static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type)
+static int cmpc_accel_remove_v4(struct acpi_device *acpi)
 {
        struct input_dev *inputdev;
        struct cmpc_accel *accel;
@@ -668,7 +668,7 @@ failed_file:
        return error;
 }
 
-static int cmpc_accel_remove(struct acpi_device *acpi, int type)
+static int cmpc_accel_remove(struct acpi_device *acpi)
 {
        struct input_dev *inputdev;
        struct cmpc_accel *accel;
@@ -753,7 +753,7 @@ static int cmpc_tablet_add(struct acpi_device *acpi)
                                           cmpc_tablet_idev_init);
 }
 
-static int cmpc_tablet_remove(struct acpi_device *acpi, int type)
+static int cmpc_tablet_remove(struct acpi_device *acpi)
 {
        return cmpc_remove_acpi_notify_device(acpi);
 }
@@ -1000,7 +1000,7 @@ out_bd:
        return retval;
 }
 
-static int cmpc_ipml_remove(struct acpi_device *acpi, int type)
+static int cmpc_ipml_remove(struct acpi_device *acpi)
 {
        struct ipml200_dev *ipml;
 
@@ -1079,7 +1079,7 @@ static int cmpc_keys_add(struct acpi_device *acpi)
                                           cmpc_keys_idev_init);
 }
 
-static int cmpc_keys_remove(struct acpi_device *acpi, int type)
+static int cmpc_keys_remove(struct acpi_device *acpi)
 {
        return cmpc_remove_acpi_notify_device(acpi);
 }
index 528e949..98935f9 100644 (file)
@@ -1501,7 +1501,7 @@ fail_platform:
        return result;
 }
 
-static int eeepc_acpi_remove(struct acpi_device *device, int type)
+static int eeepc_acpi_remove(struct acpi_device *device)
 {
        struct eeepc_laptop *eeepc = acpi_driver_data(device);
 
index c4c1a54..1c9386e 100644 (file)
@@ -733,7 +733,7 @@ err_stop:
        return result;
 }
 
-static int acpi_fujitsu_remove(struct acpi_device *device, int type)
+static int acpi_fujitsu_remove(struct acpi_device *device)
 {
        struct fujitsu_t *fujitsu = acpi_driver_data(device);
        struct input_dev *input = fujitsu->input;
@@ -938,7 +938,7 @@ err_stop:
        return result;
 }
 
-static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
+static int acpi_fujitsu_hotkey_remove(struct acpi_device *device)
 {
        struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device);
        struct input_dev *input = fujitsu_hotkey->input;
index 174ca01..570926c 100644 (file)
@@ -431,7 +431,7 @@ static int acpi_fujitsu_add(struct acpi_device *adev)
        return 0;
 }
 
-static int acpi_fujitsu_remove(struct acpi_device *adev, int type)
+static int acpi_fujitsu_remove(struct acpi_device *adev)
 {
        free_irq(fujitsu.irq, fujitsu_interrupt);
        release_region(fujitsu.io_base, fujitsu.io_length);
index 18d74f2..e64a7a8 100644 (file)
@@ -337,7 +337,7 @@ static int lis3lv02d_add(struct acpi_device *device)
        return ret;
 }
 
-static int lis3lv02d_remove(struct acpi_device *device, int type)
+static int lis3lv02d_remove(struct acpi_device *device)
 {
        if (!device)
                return -EINVAL;
index 64bfb30..17f00b8 100644 (file)
@@ -834,7 +834,7 @@ platform_failed:
        return ret;
 }
 
-static int ideapad_acpi_remove(struct acpi_device *adevice, int type)
+static int ideapad_acpi_remove(struct acpi_device *adevice)
 {
        struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
        int i;
index 3271ac8..d6cfc15 100644 (file)
@@ -200,7 +200,7 @@ static int intel_menlow_memory_add(struct acpi_device *device)
 
 }
 
-static int intel_menlow_memory_remove(struct acpi_device *device, int type)
+static int intel_menlow_memory_remove(struct acpi_device *device)
 {
        struct thermal_cooling_device *cdev = acpi_driver_data(device);
 
index 8e8caa7..4add9a3 100644 (file)
@@ -176,7 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
 /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */
 
 static int acpi_pcc_hotkey_add(struct acpi_device *device);
-static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
+static int acpi_pcc_hotkey_remove(struct acpi_device *device);
 static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id pcc_device_ids[] = {
@@ -663,7 +663,7 @@ static int __init acpi_pcc_init(void)
        return 0;
 }
 
-static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
+static int acpi_pcc_hotkey_remove(struct acpi_device *device)
 {
        struct pcc_acpi *pcc = acpi_driver_data(device);
 
index b8ad71f..ceb41ef 100644 (file)
@@ -2740,7 +2740,7 @@ outwalk:
        return result;
 }
 
-static int sony_nc_remove(struct acpi_device *device, int type)
+static int sony_nc_remove(struct acpi_device *device)
 {
        struct sony_nc_value *item;
 
@@ -4111,7 +4111,7 @@ found:
  *  ACPI driver
  *
  *****************/
-static int sony_pic_remove(struct acpi_device *device, int type)
+static int sony_pic_remove(struct acpi_device *device)
 {
        struct sony_pic_ioport *io, *tmp_io;
        struct sony_pic_irq *irq, *tmp_irq;
index d727bfe..4ab618c 100644 (file)
@@ -157,7 +157,7 @@ add_err:
        return -ENODEV;
 }
 
-static int acpi_topstar_remove(struct acpi_device *device, int type)
+static int acpi_topstar_remove(struct acpi_device *device)
 {
        struct topstar_hkey *tps_hkey = acpi_driver_data(device);
 
index c272789..904476b 100644 (file)
@@ -1118,7 +1118,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev)
        return 0;
 }
 
-static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type)
+static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
 {
        struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
 
@@ -1250,7 +1250,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
        return 0;
 
 error:
-       toshiba_acpi_remove(acpi_dev, 0);
+       toshiba_acpi_remove(acpi_dev);
        return ret;
 }
 
index e95be0b..74dd01a 100644 (file)
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
 
 
 static int toshiba_bt_rfkill_add(struct acpi_device *device);
-static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type);
+static int toshiba_bt_rfkill_remove(struct acpi_device *device);
 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id bt_device_ids[] = {
@@ -122,7 +122,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device)
        return result;
 }
 
-static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type)
+static int toshiba_bt_rfkill_remove(struct acpi_device *device)
 {
        /* clean up */
        return 0;
index 42a4dcc..e4ac38a 100644 (file)
@@ -92,7 +92,7 @@ module_param(debug_dump_wdg, bool, 0444);
 MODULE_PARM_DESC(debug_dump_wdg,
                 "Dump available WMI interfaces [0/1]");
 
-static int acpi_wmi_remove(struct acpi_device *device, int type);
+static int acpi_wmi_remove(struct acpi_device *device);
 static int acpi_wmi_add(struct acpi_device *device);
 static void acpi_wmi_notify(struct acpi_device *device, u32 event);
 
@@ -917,7 +917,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
        }
 }
 
-static int acpi_wmi_remove(struct acpi_device *device, int type)
+static int acpi_wmi_remove(struct acpi_device *device)
 {
        acpi_remove_address_space_handler(device->handle,
                                ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
index 16d340c..4b1377b 100644 (file)
@@ -150,7 +150,7 @@ static int ebook_switch_add(struct acpi_device *device)
        return error;
 }
 
-static int ebook_switch_remove(struct acpi_device *device, int type)
+static int ebook_switch_remove(struct acpi_device *device)
 {
        struct ebook_switch *button = acpi_driver_data(device);
 
index 72e822e..8813fc0 100644 (file)
@@ -90,7 +90,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
        pnp_dbg(&dev->dev, "set resources\n");
 
        handle = DEVICE_ACPI_HANDLE(&dev->dev);
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) {
+       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return -ENODEV;
        }
@@ -123,7 +123,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
        dev_dbg(&dev->dev, "disable resources\n");
 
        handle = DEVICE_ACPI_HANDLE(&dev->dev);
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) {
+       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return 0;
        }
@@ -145,7 +145,7 @@ static bool pnpacpi_can_wakeup(struct pnp_dev *dev)
        acpi_handle handle;
 
        handle = DEVICE_ACPI_HANDLE(&dev->dev);
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) {
+       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return false;
        }
@@ -160,7 +160,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
        int error = 0;
 
        handle = DEVICE_ACPI_HANDLE(&dev->dev);
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) {
+       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return 0;
        }
@@ -197,7 +197,7 @@ static int pnpacpi_resume(struct pnp_dev *dev)
        acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
        int error = 0;
 
-       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) {
+       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return -ENODEV;
        }
index b986d9f..50c3dd0 100644 (file)
@@ -2,8 +2,8 @@
 # Plug and Play BIOS configuration
 #
 config PNPBIOS
-       bool "Plug and Play BIOS support (EXPERIMENTAL)"
-       depends on ISA && X86 && EXPERIMENTAL
+       bool "Plug and Play BIOS support"
+       depends on ISA && X86
        default n
        ---help---
          Linux uses the PNPBIOS as defined in "Plug and Play BIOS
index b85040c..cca18a3 100644 (file)
@@ -379,9 +379,10 @@ static struct regulator_desc regulators[] = {
 };
 
 #ifdef CONFIG_OF
-static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,
+static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev,
                                        struct max77686_platform_data *pdata)
 {
+       struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct device_node *pmic_np, *regulators_np;
        struct max77686_regulator_data *rdata;
        struct of_regulator_match rmatch;
@@ -390,15 +391,15 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,
        pmic_np = iodev->dev->of_node;
        regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators");
        if (!regulators_np) {
-               dev_err(iodev->dev, "could not find regulators sub-node\n");
+               dev_err(&pdev->dev, "could not find regulators sub-node\n");
                return -EINVAL;
        }
 
        pdata->num_regulators = ARRAY_SIZE(regulators);
-       rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
+       rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
                             pdata->num_regulators, GFP_KERNEL);
        if (!rdata) {
-               dev_err(iodev->dev,
+               dev_err(&pdev->dev,
                        "could not allocate memory for regulator data\n");
                return -ENOMEM;
        }
@@ -407,7 +408,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,
                rmatch.name = regulators[i].name;
                rmatch.init_data = NULL;
                rmatch.of_node = NULL;
-               of_regulator_match(iodev->dev, regulators_np, &rmatch, 1);
+               of_regulator_match(&pdev->dev, regulators_np, &rmatch, 1);
                rdata[i].initdata = rmatch.init_data;
                rdata[i].of_node = rmatch.of_node;
        }
@@ -417,7 +418,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,
        return 0;
 }
 #else
-static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,
+static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev,
                                        struct max77686_platform_data *pdata)
 {
        return 0;
@@ -440,7 +441,7 @@ static int max77686_pmic_probe(struct platform_device *pdev)
        }
 
        if (iodev->dev->of_node) {
-               ret = max77686_pmic_dt_parse_pdata(iodev, pdata);
+               ret = max77686_pmic_dt_parse_pdata(pdev, pdata);
                if (ret)
                        return ret;
        }
index d1a7751..d40cf7f 100644 (file)
@@ -237,8 +237,7 @@ static int max8907_regulator_parse_dt(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       ret = of_regulator_match(pdev->dev.parent, regulators,
-                                max8907_matches,
+       ret = of_regulator_match(&pdev->dev, regulators, max8907_matches,
                                 ARRAY_SIZE(max8907_matches));
        if (ret < 0) {
                dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
index 02be7fc..836908c 100644 (file)
@@ -934,7 +934,7 @@ static struct regulator_desc regulators[] = {
 };
 
 #ifdef CONFIG_OF
-static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
+static int max8997_pmic_dt_parse_dvs_gpio(struct platform_device *pdev,
                        struct max8997_platform_data *pdata,
                        struct device_node *pmic_np)
 {
@@ -944,7 +944,7 @@ static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
                gpio = of_get_named_gpio(pmic_np,
                                        "max8997,pmic-buck125-dvs-gpios", i);
                if (!gpio_is_valid(gpio)) {
-                       dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
+                       dev_err(&pdev->dev, "invalid gpio[%d]: %d\n", i, gpio);
                        return -EINVAL;
                }
                pdata->buck125_gpios[i] = gpio;
@@ -952,22 +952,23 @@ static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
        return 0;
 }
 
-static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
                                        struct max8997_platform_data *pdata)
 {
+       struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct device_node *pmic_np, *regulators_np, *reg_np;
        struct max8997_regulator_data *rdata;
        unsigned int i, dvs_voltage_nr = 1, ret;
 
        pmic_np = iodev->dev->of_node;
        if (!pmic_np) {
-               dev_err(iodev->dev, "could not find pmic sub-node\n");
+               dev_err(&pdev->dev, "could not find pmic sub-node\n");
                return -ENODEV;
        }
 
        regulators_np = of_find_node_by_name(pmic_np, "regulators");
        if (!regulators_np) {
-               dev_err(iodev->dev, "could not find regulators sub-node\n");
+               dev_err(&pdev->dev, "could not find regulators sub-node\n");
                return -EINVAL;
        }
 
@@ -976,11 +977,10 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
        for_each_child_of_node(regulators_np, reg_np)
                pdata->num_regulators++;
 
-       rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
+       rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
                                pdata->num_regulators, GFP_KERNEL);
        if (!rdata) {
-               dev_err(iodev->dev, "could not allocate memory for "
-                                               "regulator data\n");
+               dev_err(&pdev->dev, "could not allocate memory for regulator data\n");
                return -ENOMEM;
        }
 
@@ -991,14 +991,14 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
                                break;
 
                if (i == ARRAY_SIZE(regulators)) {
-                       dev_warn(iodev->dev, "don't know how to configure "
-                               "regulator %s\n", reg_np->name);
+                       dev_warn(&pdev->dev, "don't know how to configure regulator %s\n",
+                                reg_np->name);
                        continue;
                }
 
                rdata->id = i;
-               rdata->initdata = of_get_regulator_init_data(
-                                               iodev->dev, reg_np);
+               rdata->initdata = of_get_regulator_init_data(&pdev->dev,
+                                                            reg_np);
                rdata->reg_node = reg_np;
                rdata++;
        }
@@ -1014,7 +1014,7 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
 
        if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
                                                pdata->buck5_gpiodvs) {
-               ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
+               ret = max8997_pmic_dt_parse_dvs_gpio(pdev, pdata, pmic_np);
                if (ret)
                        return -EINVAL;
 
@@ -1025,8 +1025,7 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
                } else {
                        if (pdata->buck125_default_idx >= 8) {
                                pdata->buck125_default_idx = 0;
-                               dev_info(iodev->dev, "invalid value for "
-                               "default dvs index, using 0 instead\n");
+                               dev_info(&pdev->dev, "invalid value for default dvs index, using 0 instead\n");
                        }
                }
 
@@ -1040,28 +1039,28 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
        if (of_property_read_u32_array(pmic_np,
                                "max8997,pmic-buck1-dvs-voltage",
                                pdata->buck1_voltage, dvs_voltage_nr)) {
-               dev_err(iodev->dev, "buck1 voltages not specified\n");
+               dev_err(&pdev->dev, "buck1 voltages not specified\n");
                return -EINVAL;
        }
 
        if (of_property_read_u32_array(pmic_np,
                                "max8997,pmic-buck2-dvs-voltage",
                                pdata->buck2_voltage, dvs_voltage_nr)) {
-               dev_err(iodev->dev, "buck2 voltages not specified\n");
+               dev_err(&pdev->dev, "buck2 voltages not specified\n");
                return -EINVAL;
        }
 
        if (of_property_read_u32_array(pmic_np,
                                "max8997,pmic-buck5-dvs-voltage",
                                pdata->buck5_voltage, dvs_voltage_nr)) {
-               dev_err(iodev->dev, "buck5 voltages not specified\n");
+               dev_err(&pdev->dev, "buck5 voltages not specified\n");
                return -EINVAL;
        }
 
        return 0;
 }
 #else
-static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
                                        struct max8997_platform_data *pdata)
 {
        return 0;
@@ -1085,7 +1084,7 @@ static int max8997_pmic_probe(struct platform_device *pdev)
        }
 
        if (iodev->dev->of_node) {
-               ret = max8997_pmic_dt_parse_pdata(iodev, pdata);
+               ret = max8997_pmic_dt_parse_pdata(pdev, pdata);
                if (ret)
                        return ret;
        }
index 1f0df40..0a8dd1c 100644 (file)
@@ -65,7 +65,7 @@ static const struct voltage_map_desc ldo9_voltage_map_desc = {
        .min = 2800000, .step = 100000, .max = 3100000,
 };
 static const struct voltage_map_desc ldo10_voltage_map_desc = {
-       .min = 95000  .step = 50000,  .max = 1300000,
+       .min = 950000,  .step = 50000,  .max = 1300000,
 };
 static const struct voltage_map_desc ldo1213_voltage_map_desc = {
        .min = 800000,  .step = 100000, .max = 3300000,
index 6f68491..66ca769 100644 (file)
@@ -120,6 +120,12 @@ int of_regulator_match(struct device *dev, struct device_node *node,
        if (!dev || !node)
                return -EINVAL;
 
+       for (i = 0; i < num_matches; i++) {
+               struct of_regulator_match *match = &matches[i];
+               match->init_data = NULL;
+               match->of_node = NULL;
+       }
+
        for_each_child_of_node(node, child) {
                name = of_get_property(child,
                                        "regulator-compatible", NULL);
index bd062a2..cd9ea2e 100644 (file)
@@ -174,9 +174,9 @@ static struct regulator_ops s2mps11_buck_ops = {
        .min_uV         = S2MPS11_BUCK_MIN2,                    \
        .uV_step        = S2MPS11_BUCK_STEP2,                   \
        .n_voltages     = S2MPS11_BUCK_N_VOLTAGES,              \
-       .vsel_reg       = S2MPS11_REG_B9CTRL2,                  \
+       .vsel_reg       = S2MPS11_REG_B10CTRL2,                 \
        .vsel_mask      = S2MPS11_BUCK_VSEL_MASK,               \
-       .enable_reg     = S2MPS11_REG_B9CTRL1,                  \
+       .enable_reg     = S2MPS11_REG_B10CTRL1,                 \
        .enable_mask    = S2MPS11_ENABLE_MASK                   \
 }
 
index 73dce76..df39518 100644 (file)
@@ -305,8 +305,8 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)
        if (!regs)
                return NULL;
 
-       count = of_regulator_match(pdev->dev.parent, regs,
-                               reg_matches, TPS65217_NUM_REGULATOR);
+       count = of_regulator_match(&pdev->dev, regs, reg_matches,
+                                  TPS65217_NUM_REGULATOR);
        of_node_put(regs);
        if ((count < 0) || (count > TPS65217_NUM_REGULATOR))
                return NULL;
index 59c3770..b0e4c0b 100644 (file)
@@ -998,7 +998,7 @@ static struct tps65910_board *tps65910_parse_dt_reg_data(
                return NULL;
        }
 
-       ret = of_regulator_match(pdev->dev.parent, regulators, matches, count);
+       ret = of_regulator_match(&pdev->dev, regulators, matches, count);
        if (ret < 0) {
                dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
                        ret);
index afb7cfa..c016ad8 100644 (file)
@@ -506,6 +506,7 @@ isl1208_rtc_interrupt(int irq, void *data)
 {
        unsigned long timeout = jiffies + msecs_to_jiffies(1000);
        struct i2c_client *client = data;
+       struct rtc_device *rtc = i2c_get_clientdata(client);
        int handled = 0, sr, err;
 
        /*
@@ -528,6 +529,8 @@ isl1208_rtc_interrupt(int irq, void *data)
        if (sr & ISL1208_REG_SR_ALM) {
                dev_dbg(&client->dev, "alarm!\n");
 
+               rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
+
                /* Clear the alarm */
                sr &= ~ISL1208_REG_SR_ALM;
                sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr);
index 08378e3..10c1a34 100644 (file)
@@ -44,6 +44,7 @@
 #define RTC_YMR                0x34    /* Year match register */
 #define RTC_YLR                0x38    /* Year data load register */
 
+#define RTC_CR_EN      (1 << 0)        /* counter enable bit */
 #define RTC_CR_CWEN    (1 << 26)       /* Clockwatch enable bit */
 
 #define RTC_TCR_EN     (1 << 1) /* Periodic timer enable bit */
@@ -320,7 +321,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
        struct pl031_local *ldata;
        struct pl031_vendor_data *vendor = id->data;
        struct rtc_class_ops *ops = &vendor->ops;
-       unsigned long time;
+       unsigned long time, data;
 
        ret = amba_request_regions(adev, NULL);
        if (ret)
@@ -345,10 +346,11 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
        dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev));
        dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev));
 
+       data = readl(ldata->base + RTC_CR);
        /* Enable the clockwatch on ST Variants */
        if (vendor->clockwatch)
-               writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
-                      ldata->base + RTC_CR);
+               data |= RTC_CR_CWEN;
+       writel(data | RTC_CR_EN, ldata->base + RTC_CR);
 
        /*
         * On ST PL031 variants, the RTC reset value does not provide correct
index 00c930f..2730533 100644 (file)
@@ -137,7 +137,7 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
                return -EINVAL;
        }
 
-       writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S)
+       writel((bin2bcd(tm->tm_year % 100) << DATE_YEAR_S)
                | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S)
                | (bin2bcd(tm->tm_mday))
                | ((tm->tm_year >= 200) << DATE_CENTURY_S),
index 97ac0a3..eb27530 100644 (file)
@@ -174,3 +174,15 @@ int ssb_gpio_init(struct ssb_bus *bus)
 
        return -1;
 }
+
+int ssb_gpio_unregister(struct ssb_bus *bus)
+{
+       if (ssb_chipco_available(&bus->chipco) ||
+           ssb_extif_available(&bus->extif)) {
+               return gpiochip_remove(&bus->gpio);
+       } else {
+               SSB_WARN_ON(1);
+       }
+
+       return -1;
+}
index 772ad9b..24dc331 100644 (file)
@@ -443,6 +443,15 @@ static void ssb_devices_unregister(struct ssb_bus *bus)
 
 void ssb_bus_unregister(struct ssb_bus *bus)
 {
+       int err;
+
+       err = ssb_gpio_unregister(bus);
+       if (err == -EBUSY)
+               ssb_dprintk(KERN_ERR PFX "Some GPIOs are still in use.\n");
+       else if (err)
+               ssb_dprintk(KERN_ERR PFX
+                           "Can not unregister GPIO driver: %i\n", err);
+
        ssb_buses_lock();
        ssb_devices_unregister(bus);
        list_del(&bus->list);
index 6c10b66..da38305 100644 (file)
@@ -252,11 +252,16 @@ static inline void ssb_extif_init(struct ssb_extif *extif)
 
 #ifdef CONFIG_SSB_DRIVER_GPIO
 extern int ssb_gpio_init(struct ssb_bus *bus);
+extern int ssb_gpio_unregister(struct ssb_bus *bus);
 #else /* CONFIG_SSB_DRIVER_GPIO */
 static inline int ssb_gpio_init(struct ssb_bus *bus)
 {
        return -ENOTSUPP;
 }
+static inline int ssb_gpio_unregister(struct ssb_bus *bus)
+{
+       return 0;
+}
 #endif /* CONFIG_SSB_DRIVER_GPIO */
 
 #endif /* LINUX_SSB_PRIVATE_H_ */
index cac3207..adb8da5 100644 (file)
@@ -296,7 +296,7 @@ fail_config:
        return ret;
 }
 
-static int quickstart_acpi_remove(struct acpi_device *device, int type)
+static int quickstart_acpi_remove(struct acpi_device *device)
 {
        acpi_status status;
        struct quickstart_acpi *quickstart;
index e269510..f2aa754 100644 (file)
@@ -941,6 +941,8 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)
 
 int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
 {
+       int block_size = dev->dev_attrib.block_size;
+
        if (dev->export_count) {
                pr_err("dev[%p]: Unable to change SE Device"
                        " fabric_max_sectors while export_count is %d\n",
@@ -978,8 +980,12 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
        /*
         * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks()
         */
+       if (!block_size) {
+               block_size = 512;
+               pr_warn("Defaulting to 512 for zero block_size\n");
+       }
        fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors,
-                                                     dev->dev_attrib.block_size);
+                                                     block_size);
 
        dev->dev_attrib.fabric_max_sectors = fabric_max_sectors;
        pr_debug("dev[%p]: SE Device max_sectors changed to %u\n",
index 810263d..c57bbbc 100644 (file)
@@ -754,6 +754,11 @@ static int target_fabric_port_link(
                return -EFAULT;
        }
 
+       if (!(dev->dev_flags & DF_CONFIGURED)) {
+               pr_err("se_device not configured yet, cannot port link\n");
+               return -ENODEV;
+       }
+
        tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;
        se_tpg = container_of(to_config_group(tpg_ci),
                                struct se_portal_group, tpg_group);
index 26a6d18..a664c66 100644 (file)
@@ -58,11 +58,10 @@ sbc_emulate_readcapacity(struct se_cmd *cmd)
        buf[7] = dev->dev_attrib.block_size & 0xff;
 
        rbuf = transport_kmap_data_sg(cmd);
-       if (!rbuf)
-               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-
-       memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
-       transport_kunmap_data_sg(cmd);
+       if (rbuf) {
+               memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+               transport_kunmap_data_sg(cmd);
+       }
 
        target_complete_cmd(cmd, GOOD);
        return 0;
@@ -97,11 +96,10 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)
                buf[14] = 0x80;
 
        rbuf = transport_kmap_data_sg(cmd);
-       if (!rbuf)
-               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-
-       memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
-       transport_kunmap_data_sg(cmd);
+       if (rbuf) {
+               memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+               transport_kunmap_data_sg(cmd);
+       }
 
        target_complete_cmd(cmd, GOOD);
        return 0;
index 84f9e96..2d88f08 100644 (file)
@@ -641,11 +641,10 @@ spc_emulate_inquiry(struct se_cmd *cmd)
 
 out:
        rbuf = transport_kmap_data_sg(cmd);
-       if (!rbuf)
-               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-
-       memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
-       transport_kunmap_data_sg(cmd);
+       if (rbuf) {
+               memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+               transport_kunmap_data_sg(cmd);
+       }
 
        if (!ret)
                target_complete_cmd(cmd, GOOD);
@@ -851,7 +850,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
 {
        struct se_device *dev = cmd->se_dev;
        char *cdb = cmd->t_task_cdb;
-       unsigned char *buf, *map_buf;
+       unsigned char buf[SE_MODE_PAGE_BUF], *rbuf;
        int type = dev->transport->get_device_type(dev);
        int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
        bool dbd = !!(cdb[1] & 0x08);
@@ -863,26 +862,8 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
        int ret;
        int i;
 
-       map_buf = transport_kmap_data_sg(cmd);
-       if (!map_buf)
-               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-       /*
-        * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we
-        * know we actually allocated a full page.  Otherwise, if the
-        * data buffer is too small, allocate a temporary buffer so we
-        * don't have to worry about overruns in all our INQUIRY
-        * emulation handling.
-        */
-       if (cmd->data_length < SE_MODE_PAGE_BUF &&
-           (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) {
-               buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL);
-               if (!buf) {
-                       transport_kunmap_data_sg(cmd);
-                       return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-               }
-       } else {
-               buf = map_buf;
-       }
+       memset(buf, 0, SE_MODE_PAGE_BUF);
+
        /*
         * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for
         * MODE_SENSE_10 and byte 2 for MODE_SENSE (6).
@@ -934,8 +915,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
        if (page == 0x3f) {
                if (subpage != 0x00 && subpage != 0xff) {
                        pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage);
-                       kfree(buf);
-                       transport_kunmap_data_sg(cmd);
                        return TCM_INVALID_CDB_FIELD;
                }
 
@@ -972,7 +951,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
                pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",
                       page, subpage);
 
-       transport_kunmap_data_sg(cmd);
        return TCM_UNKNOWN_MODE_PAGE;
 
 set_length:
@@ -981,12 +959,12 @@ set_length:
        else
                buf[0] = length - 1;
 
-       if (buf != map_buf) {
-               memcpy(map_buf, buf, cmd->data_length);
-               kfree(buf);
+       rbuf = transport_kmap_data_sg(cmd);
+       if (rbuf) {
+               memcpy(rbuf, buf, min_t(u32, SE_MODE_PAGE_BUF, cmd->data_length));
+               transport_kunmap_data_sg(cmd);
        }
 
-       transport_kunmap_data_sg(cmd);
        target_complete_cmd(cmd, GOOD);
        return 0;
 }
index 4225d5e..8e64adf 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/unaligned.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
@@ -1025,6 +1026,49 @@ static int register_root_hub(struct usb_hcd *hcd)
        return retval;
 }
 
+/*
+ * usb_hcd_start_port_resume - a root-hub port is sending a resume signal
+ * @bus: the bus which the root hub belongs to
+ * @portnum: the port which is being resumed
+ *
+ * HCDs should call this function when they know that a resume signal is
+ * being sent to a root-hub port.  The root hub will be prevented from
+ * going into autosuspend until usb_hcd_end_port_resume() is called.
+ *
+ * The bus's private lock must be held by the caller.
+ */
+void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum)
+{
+       unsigned bit = 1 << portnum;
+
+       if (!(bus->resuming_ports & bit)) {
+               bus->resuming_ports |= bit;
+               pm_runtime_get_noresume(&bus->root_hub->dev);
+       }
+}
+EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume);
+
+/*
+ * usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal
+ * @bus: the bus which the root hub belongs to
+ * @portnum: the port which is being resumed
+ *
+ * HCDs should call this function when they know that a resume signal has
+ * stopped being sent to a root-hub port.  The root hub will be allowed to
+ * autosuspend again.
+ *
+ * The bus's private lock must be held by the caller.
+ */
+void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum)
+{
+       unsigned bit = 1 << portnum;
+
+       if (bus->resuming_ports & bit) {
+               bus->resuming_ports &= ~bit;
+               pm_runtime_put_noidle(&bus->root_hub->dev);
+       }
+}
+EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume);
 
 /*-------------------------------------------------------------------------*/
 
index 957ed2c..cbf7168 100644 (file)
@@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev)
 EXPORT_SYMBOL_GPL(usb_enable_ltm);
 
 #ifdef CONFIG_USB_SUSPEND
+/*
+ * usb_disable_function_remotewakeup - disable usb3.0
+ * device's function remote wakeup
+ * @udev: target device
+ *
+ * Assume there's only one function on the USB 3.0
+ * device and disable remote wake for the first
+ * interface. FIXME if the interface association
+ * descriptor shows there's more than one function.
+ */
+static int usb_disable_function_remotewakeup(struct usb_device *udev)
+{
+       return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                               USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
+                               USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
+                               USB_CTRL_SET_TIMEOUT);
+}
 
 /*
  * usb_port_suspend - suspend a usb device's upstream port
@@ -2955,12 +2972,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
                dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
                                port1, status);
                /* paranoia:  "should not happen" */
-               if (udev->do_remote_wakeup)
-                       (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                               USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
-                               USB_DEVICE_REMOTE_WAKEUP, 0,
-                               NULL, 0,
-                               USB_CTRL_SET_TIMEOUT);
+               if (udev->do_remote_wakeup) {
+                       if (!hub_is_superspeed(hub->hdev)) {
+                               (void) usb_control_msg(udev,
+                                               usb_sndctrlpipe(udev, 0),
+                                               USB_REQ_CLEAR_FEATURE,
+                                               USB_RECIP_DEVICE,
+                                               USB_DEVICE_REMOTE_WAKEUP, 0,
+                                               NULL, 0,
+                                               USB_CTRL_SET_TIMEOUT);
+                       } else
+                               (void) usb_disable_function_remotewakeup(udev);
+
+               }
 
                /* Try to enable USB2 hardware LPM again */
                if (udev->usb2_hw_lpm_capable == 1)
@@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev)
         * udev->reset_resume
         */
        } else if (udev->actconfig && !udev->reset_resume) {
-               le16_to_cpus(&devstatus);
-               if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
-                       status = usb_control_msg(udev,
-                                       usb_sndctrlpipe(udev, 0),
-                                       USB_REQ_CLEAR_FEATURE,
+               if (!hub_is_superspeed(udev->parent)) {
+                       le16_to_cpus(&devstatus);
+                       if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
+                               status = usb_control_msg(udev,
+                                               usb_sndctrlpipe(udev, 0),
+                                               USB_REQ_CLEAR_FEATURE,
                                                USB_RECIP_DEVICE,
-                                       USB_DEVICE_REMOTE_WAKEUP, 0,
-                                       NULL, 0,
-                                       USB_CTRL_SET_TIMEOUT);
-                       if (status)
-                               dev_dbg(&udev->dev,
-                                       "disable remote wakeup, status %d\n",
-                                       status);
+                                               USB_DEVICE_REMOTE_WAKEUP, 0,
+                                               NULL, 0,
+                                               USB_CTRL_SET_TIMEOUT);
+               } else {
+                       status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
+                                       &devstatus);
+                       le16_to_cpus(&devstatus);
+                       if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP
+                                       | USB_INTRF_STAT_FUNC_RW))
+                               status =
+                                       usb_disable_function_remotewakeup(udev);
                }
+
+               if (status)
+                       dev_dbg(&udev->dev,
+                               "disable remote wakeup, status %d\n",
+                               status);
                status = 0;
        }
        return status;
index 09537b2..b416a3f 100644 (file)
@@ -797,6 +797,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                        ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
                        set_bit(i, &ehci->resuming_ports);
                        ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
+                       usb_hcd_start_port_resume(&hcd->self, i);
                        mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
                }
        }
index 4ccb97c..4d3b294 100644 (file)
@@ -649,7 +649,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
                        status = STS_PCD;
                }
        }
-       /* FIXME autosuspend idle root hubs */
+
+       /* If a resume is in progress, make sure it can finish */
+       if (ehci->resuming_ports)
+               mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25));
+
        spin_unlock_irqrestore (&ehci->lock, flags);
        return status ? retval : 0;
 }
@@ -851,6 +855,7 @@ static int ehci_hub_control (
                                /* resume signaling for 20 msec */
                                ehci->reset_done[wIndex] = jiffies
                                                + msecs_to_jiffies(20);
+                               usb_hcd_start_port_resume(&hcd->self, wIndex);
                                /* check the port again */
                                mod_timer(&ehci_to_hcd(ehci)->rh_timer,
                                                ehci->reset_done[wIndex]);
@@ -862,6 +867,7 @@ static int ehci_hub_control (
                                clear_bit(wIndex, &ehci->suspended_ports);
                                set_bit(wIndex, &ehci->port_c_suspend);
                                ehci->reset_done[wIndex] = 0;
+                               usb_hcd_end_port_resume(&hcd->self, wIndex);
 
                                /* stop resume signaling */
                                temp = ehci_readl(ehci, status_reg);
@@ -950,6 +956,7 @@ static int ehci_hub_control (
                        ehci->reset_done[wIndex] = 0;
                        if (temp & PORT_PE)
                                set_bit(wIndex, &ehci->port_c_suspend);
+                       usb_hcd_end_port_resume(&hcd->self, wIndex);
                }
 
                if (temp & PORT_OC)
index 3d98902..fd252f0 100644 (file)
@@ -1197,17 +1197,26 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)
        if (ehci->async_iaa || ehci->async_unlinking)
                return;
 
-       /* Do all the waiting QHs at once */
-       ehci->async_iaa = ehci->async_unlink;
-       ehci->async_unlink = NULL;
-
        /* If the controller isn't running, we don't have to wait for it */
        if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) {
+
+               /* Do all the waiting QHs */
+               ehci->async_iaa = ehci->async_unlink;
+               ehci->async_unlink = NULL;
+
                if (!nested)            /* Avoid recursion */
                        end_unlink_async(ehci);
 
        /* Otherwise start a new IAA cycle */
        } else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) {
+               struct ehci_qh          *qh;
+
+               /* Do only the first waiting QH (nVidia bug?) */
+               qh = ehci->async_unlink;
+               ehci->async_iaa = qh;
+               ehci->async_unlink = qh->unlink_next;
+               qh->unlink_next = NULL;
+
                /* Make sure the unlinks are all visible to the hardware */
                wmb();
 
@@ -1255,34 +1264,35 @@ static void end_unlink_async(struct ehci_hcd *ehci)
        }
 }
 
+static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
+
 static void unlink_empty_async(struct ehci_hcd *ehci)
 {
-       struct ehci_qh          *qh, *next;
-       bool                    stopped = (ehci->rh_state < EHCI_RH_RUNNING);
+       struct ehci_qh          *qh;
+       struct ehci_qh          *qh_to_unlink = NULL;
        bool                    check_unlinks_later = false;
+       int                     count = 0;
 
-       /* Unlink all the async QHs that have been empty for a timer cycle */
-       next = ehci->async->qh_next.qh;
-       while (next) {
-               qh = next;
-               next = qh->qh_next.qh;
-
+       /* Find the last async QH which has been empty for a timer cycle */
+       for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) {
                if (list_empty(&qh->qtd_list) &&
                                qh->qh_state == QH_STATE_LINKED) {
-                       if (!stopped && qh->unlink_cycle ==
-                                       ehci->async_unlink_cycle)
+                       ++count;
+                       if (qh->unlink_cycle == ehci->async_unlink_cycle)
                                check_unlinks_later = true;
                        else
-                               single_unlink_async(ehci, qh);
+                               qh_to_unlink = qh;
                }
        }
 
-       /* Start a new IAA cycle if any QHs are waiting for it */
-       if (ehci->async_unlink)
-               start_iaa_cycle(ehci, false);
+       /* If nothing else is being unlinked, unlink the last empty QH */
+       if (!ehci->async_iaa && !ehci->async_unlink && qh_to_unlink) {
+               start_unlink_async(ehci, qh_to_unlink);
+               --count;
+       }
 
-       /* QHs that haven't been empty for long enough will be handled later */
-       if (check_unlinks_later) {
+       /* Other QHs will be handled later */
+       if (count > 0) {
                ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true);
                ++ehci->async_unlink_cycle;
        }
index 69ebee7..b476daf 100644 (file)
@@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
 }
 
 static const unsigned char
-max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
+max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
 
 /* carryover low/fullspeed bandwidth that crosses uframe boundries */
 static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
@@ -2212,11 +2212,11 @@ static void scan_isoc(struct ehci_hcd *ehci)
        }
        ehci->now_frame = now_frame;
 
+       frame = ehci->last_iso_frame;
        for (;;) {
                union ehci_shadow       q, *q_p;
                __hc32                  type, *hw_p;
 
-               frame = ehci->last_iso_frame;
 restart:
                /* scan each element in frame's queue for completions */
                q_p = &ehci->pshadow [frame];
@@ -2321,6 +2321,9 @@ restart:
                /* Stop when we have reached the current frame */
                if (frame == now_frame)
                        break;
-               ehci->last_iso_frame = (frame + 1) & fmask;
+
+               /* The last frame may still have active siTDs */
+               ehci->last_iso_frame = frame;
+               frame = (frame + 1) & fmask;
        }
 }
index 20dbdcb..f904071 100644 (file)
@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
 
        if (want != actual) {
 
-               /* Poll again later, but give up after about 20 ms */
-               if (ehci->ASS_poll_count++ < 20) {
-                       ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
-                       return;
-               }
-               ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n",
-                               want, actual);
+               /* Poll again later */
+               ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
+               ++ehci->ASS_poll_count;
+               return;
        }
+
+       if (ehci->ASS_poll_count > 20)
+               ehci_dbg(ehci, "ASS poll count reached %d\n",
+                               ehci->ASS_poll_count);
        ehci->ASS_poll_count = 0;
 
        /* The status is up-to-date; restart or stop the schedule as needed */
@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
 
        if (want != actual) {
 
-               /* Poll again later, but give up after about 20 ms */
-               if (ehci->PSS_poll_count++ < 20) {
-                       ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
-                       return;
-               }
-               ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
-                               want, actual);
+               /* Poll again later */
+               ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
+               return;
        }
+
+       if (ehci->PSS_poll_count > 20)
+               ehci_dbg(ehci, "PSS poll count reached %d\n",
+                               ehci->PSS_poll_count);
        ehci->PSS_poll_count = 0;
 
        /* The status is up-to-date; restart or stop the schedule as needed */
index a3b6d71..4c338ec 100644 (file)
@@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
                                "defaulting to EHCI.\n");
                dev_warn(&xhci_pdev->dev,
                                "USB 3.0 devices will work at USB 2.0 speeds.\n");
+               usb_disable_xhci_ports(xhci_pdev);
                return;
        }
 
index 768d542..15d1322 100644 (file)
@@ -116,6 +116,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
                }
        }
        clear_bit(port, &uhci->resuming_ports);
+       usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port);
 }
 
 /* Wait for the UHCI controller in HP's iLO2 server management chip.
@@ -167,6 +168,8 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
                                set_bit(port, &uhci->resuming_ports);
                                uhci->ports_timeout = jiffies +
                                                msecs_to_jiffies(25);
+                               usb_hcd_start_port_resume(
+                                               &uhci_to_hcd(uhci)->self, port);
 
                                /* Make sure we see the port again
                                 * after the resuming period is over. */
index 59fb5c6..7f76a49 100644 (file)
@@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
                                faked_port_index + 1);
                if (slot_id && xhci->devs[slot_id])
                        xhci_ring_device(xhci, slot_id);
-               if (bus_state->port_remote_wakeup && (1 << faked_port_index)) {
+               if (bus_state->port_remote_wakeup & (1 << faked_port_index)) {
                        bus_state->port_remote_wakeup &=
                                ~(1 << faked_port_index);
                        xhci_test_and_clear_bit(xhci, port_array,
@@ -2589,6 +2589,8 @@ cleanup:
                                (trb_comp_code != COMP_STALL &&
                                        trb_comp_code != COMP_BABBLE))
                                xhci_urb_free_priv(xhci, urb_priv);
+                       else
+                               kfree(urb_priv);
 
                        usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
                        if ((urb->actual_length != urb->transfer_buffer_length &&
@@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
         * running_total.
         */
        packets_transferred = (running_total + trb_buff_len) /
-               usb_endpoint_maxp(&urb->ep->desc);
+               GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
 
        if ((total_packet_count - packets_transferred) > 31)
                return 31 << 17;
@@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                td_len = urb->iso_frame_desc[i].length;
                td_remain_len = td_len;
                total_packet_count = DIV_ROUND_UP(td_len,
-                               usb_endpoint_maxp(&urb->ep->desc));
+                               GET_MAX_PACKET(
+                                       usb_endpoint_maxp(&urb->ep->desc)));
                /* A zero-length transfer still involves at least one packet. */
                if (total_packet_count == 0)
                        total_packet_count++;
@@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                td = urb_priv->td[i];
                for (j = 0; j < trbs_per_td; j++) {
                        u32 remainder = 0;
-                       field = TRB_TBC(burst_count) | TRB_TLBPC(residue);
+                       field = 0;
 
                        if (first_trb) {
+                               field = TRB_TBC(burst_count) |
+                                       TRB_TLBPC(residue);
                                /* Queue the isoc TRB */
                                field |= TRB_TYPE(TRB_ISOC);
                                /* Assume URB_ISO_ASAP is set */
index f14736f..edc0f0d 100644 (file)
@@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
        { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
        { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
+       { USB_DEVICE(0x0FDE, 0xCA05) }, /* OWL Wireless Electricity Monitor CM-160 */
        { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
        { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
        { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
index ba68835..90ceef1 100644 (file)
@@ -584,6 +584,7 @@ static struct usb_device_id id_table_combined [] = {
        /*
         * ELV devices:
         */
+       { USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) },
@@ -670,6 +671,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
        { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
        { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) },
        { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) },
index fa5d560..9d359e1 100644 (file)
 #define XSENS_CONVERTER_6_PID  0xD38E
 #define XSENS_CONVERTER_7_PID  0xD38F
 
+/**
+ * Zolix (www.zolix.com.cb) product ids
+ */
+#define FTDI_OMNI1509                  0xD491  /* Omni1509 embedded USB-serial */
+
 /*
  * NDI (www.ndigital.com) product ids
  */
 
 /*
  * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
- * All of these devices use FTDI's vendor ID (0x0403).
+ * Almost all of these devices use FTDI's vendor ID (0x0403).
  * Further IDs taken from ELV Windows .inf file.
  *
  * The previously included PID for the UO 100 module was incorrect.
  *
  * Armin Laeuger originally sent the PID for the UM 100 module.
  */
+#define FTDI_ELV_VID   0x1B1F  /* ELV AG */
+#define FTDI_ELV_WS300_PID     0xC006  /* eQ3 WS 300 PC II */
 #define FTDI_ELV_USR_PID       0xE000  /* ELV Universal-Sound-Recorder */
 #define FTDI_ELV_MSM1_PID      0xE001  /* ELV Mini-Sound-Modul */
 #define FTDI_ELV_KL100_PID     0xE002  /* ELV Kfz-Leistungsmesser KL 100 */
index 0d9dac9..567bc77 100644 (file)
@@ -242,6 +242,7 @@ static void option_instat_callback(struct urb *urb);
 #define TELIT_PRODUCT_CC864_DUAL               0x1005
 #define TELIT_PRODUCT_CC864_SINGLE             0x1006
 #define TELIT_PRODUCT_DE910_DUAL               0x1010
+#define TELIT_PRODUCT_LE920                    0x1200
 
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID                          0x19d2
@@ -453,6 +454,10 @@ static void option_instat_callback(struct urb *urb);
 #define TPLINK_VENDOR_ID                       0x2357
 #define TPLINK_PRODUCT_MA180                   0x0201
 
+/* Changhong products */
+#define CHANGHONG_VENDOR_ID                    0x2077
+#define CHANGHONG_PRODUCT_CH690                        0x7001
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
                OPTION_BLACKLIST_NONE = 0,
@@ -534,6 +539,11 @@ static const struct option_blacklist_info zte_1255_blacklist = {
        .reserved = BIT(3) | BIT(4),
 };
 
+static const struct option_blacklist_info telit_le920_blacklist = {
+       .sendsetup = BIT(0),
+       .reserved = BIT(1) | BIT(5),
+};
+
 static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -784,6 +794,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
+               .driver_info = (kernel_ulong_t)&telit_le920_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
@@ -1318,6 +1330,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) },
        { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index aa148c2..2466254 100644 (file)
@@ -53,6 +53,7 @@ static const struct usb_device_id id_table[] = {
        {DEVICE_G1K(0x05c6, 0x9221)},   /* Generic Gobi QDL device */
        {DEVICE_G1K(0x05c6, 0x9231)},   /* Generic Gobi QDL device */
        {DEVICE_G1K(0x1f45, 0x0001)},   /* Unknown Gobi QDL device */
+       {DEVICE_G1K(0x1bc7, 0x900e)},   /* Telit Gobi QDL device */
 
        /* Gobi 2000 devices */
        {USB_DEVICE(0x1410, 0xa010)},   /* Novatel Gobi 2000 QDL device */
index 105d900..16b0bf0 100644 (file)
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
        return 0;
 }
 
-/* This places the HUAWEI E220 devices in multi-port mode */
-int usb_stor_huawei_e220_init(struct us_data *us)
+/* This places the HUAWEI usb dongles in multi-port mode */
+static int usb_stor_huawei_feature_init(struct us_data *us)
 {
        int result;
 
@@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us)
        US_DEBUGP("Huawei mode set result is %d\n", result);
        return 0;
 }
+
+/*
+ * It will send a scsi switch command called rewind' to huawei dongle.
+ * When the dongle receives this command at the first time,
+ * it will reboot immediately. After rebooted, it will ignore this command.
+ * So it is  unnecessary to read its response.
+ */
+static int usb_stor_huawei_scsi_init(struct us_data *us)
+{
+       int result = 0;
+       int act_len = 0;
+       struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
+       char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
+                       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+       bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+       bcbw->Tag = 0;
+       bcbw->DataTransferLength = 0;
+       bcbw->Flags = bcbw->Lun = 0;
+       bcbw->Length = sizeof(rewind_cmd);
+       memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
+       memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
+
+       result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
+                                       US_BULK_CB_WRAP_LEN, &act_len);
+       US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
+       return result;
+}
+
+/*
+ * It tries to find the supported Huawei USB dongles.
+ * In Huawei, they assign the following product IDs
+ * for all of their mobile broadband dongles,
+ * including the new dongles in the future.
+ * So if the product ID is not included in this list,
+ * it means it is not Huawei's mobile broadband dongles.
+ */
+static int usb_stor_huawei_dongles_pid(struct us_data *us)
+{
+       struct usb_interface_descriptor *idesc;
+       int idProduct;
+
+       idesc = &us->pusb_intf->cur_altsetting->desc;
+       idProduct = us->pusb_dev->descriptor.idProduct;
+       /* The first port is CDROM,
+        * means the dongle in the single port mode,
+        * and a switch command is required to be sent. */
+       if (idesc && idesc->bInterfaceNumber == 0) {
+               if ((idProduct == 0x1001)
+                       || (idProduct == 0x1003)
+                       || (idProduct == 0x1004)
+                       || (idProduct >= 0x1401 && idProduct <= 0x1500)
+                       || (idProduct >= 0x1505 && idProduct <= 0x1600)
+                       || (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+int usb_stor_huawei_init(struct us_data *us)
+{
+       int result = 0;
+
+       if (usb_stor_huawei_dongles_pid(us)) {
+               if (us->pusb_dev->descriptor.idProduct >= 0x1446)
+                       result = usb_stor_huawei_scsi_init(us);
+               else
+                       result = usb_stor_huawei_feature_init(us);
+       }
+       return result;
+}
index 529327f..5376d4f 100644 (file)
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
 
-/* This places the HUAWEI E220 devices in multi-port mode */
-int usb_stor_huawei_e220_init(struct us_data *us);
+/* This places the HUAWEI usb dongles in multi-port mode */
+int usb_stor_huawei_init(struct us_data *us);
index d305a5a..72923b5 100644 (file)
@@ -1527,335 +1527,10 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x0100,
 /* Reported by fangxiaozhi <huananhu@huawei.com>
  * This brings the HUAWEI data card devices into multi-port mode
  */
-UNUSUAL_DEV(  0x12d1, 0x1001, 0x0000, 0x0000,
+UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
                "HUAWEI MOBILE",
                "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1003, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1004, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1401, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1402, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1403, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1404, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1405, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1406, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1407, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1408, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1409, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x140A, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x140B, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x140C, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x140D, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x140E, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x140F, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1410, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1411, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1412, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1413, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1414, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1415, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1416, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1417, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1418, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1419, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x141A, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x141B, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x141C, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x141D, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x141E, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x141F, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1420, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1421, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1422, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1423, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1424, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1425, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1426, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1427, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1428, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1429, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x142A, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x142B, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x142C, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x142D, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x142E, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x142F, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1430, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1431, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1432, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1433, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1434, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1435, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1436, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1437, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1438, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x1439, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x143A, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x143B, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x143C, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x143D, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x143E, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
-               0),
-UNUSUAL_DEV(  0x12d1, 0x143F, 0x0000, 0x0000,
-               "HUAWEI MOBILE",
-               "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
                0),
 
 /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
index 31b3e1a..cf09b6b 100644 (file)
@@ -120,6 +120,17 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
        .useTransport = use_transport,  \
 }
 
+#define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \
+               vendor_name, product_name, use_protocol, use_transport, \
+               init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
 static struct us_unusual_dev us_unusual_dev_list[] = {
 #      include "unusual_devs.h"
        { }             /* Terminating entry */
@@ -131,6 +142,7 @@ static struct us_unusual_dev for_dynamic_ids =
 #undef UNUSUAL_DEV
 #undef COMPLIANT_DEV
 #undef USUAL_DEV
+#undef UNUSUAL_VENDOR_INTF
 
 #ifdef CONFIG_LOCKDEP
 
index b78a526..5ef8ce7 100644 (file)
 #define USUAL_DEV(useProto, useTrans) \
 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) }
 
+/* Define the device is matched with Vendor ID and interface descriptors */
+#define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \
+                       vendorName, productName, useProtocol, useTransport, \
+                       initFunction, flags) \
+{ \
+       .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
+                               | USB_DEVICE_ID_MATCH_VENDOR, \
+       .idVendor    = (id_vendor), \
+       .bInterfaceClass = (cl), \
+       .bInterfaceSubClass = (sc), \
+       .bInterfaceProtocol = (pr), \
+       .driver_info = (flags) \
+}
+
 struct usb_device_id usb_storage_usb_ids[] = {
 #      include "unusual_devs.h"
        { }             /* Terminating entry */
@@ -50,6 +64,7 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);
 #undef UNUSUAL_DEV
 #undef COMPLIANT_DEV
 #undef USUAL_DEV
+#undef UNUSUAL_VENDOR_INTF
 
 /*
  * The table of devices to ignore
index ebd08b2..959b1cd 100644 (file)
@@ -165,12 +165,16 @@ static void tx_poll_stop(struct vhost_net *net)
 }
 
 /* Caller must have TX VQ lock */
-static void tx_poll_start(struct vhost_net *net, struct socket *sock)
+static int tx_poll_start(struct vhost_net *net, struct socket *sock)
 {
+       int ret;
+
        if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
-               return;
-       vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
-       net->tx_poll_state = VHOST_NET_POLL_STARTED;
+               return 0;
+       ret = vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
+       if (!ret)
+               net->tx_poll_state = VHOST_NET_POLL_STARTED;
+       return ret;
 }
 
 /* In case of DMA done not in order in lower device driver for some reason.
@@ -642,20 +646,23 @@ static void vhost_net_disable_vq(struct vhost_net *n,
                vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);
 }
 
-static void vhost_net_enable_vq(struct vhost_net *n,
+static int vhost_net_enable_vq(struct vhost_net *n,
                                struct vhost_virtqueue *vq)
 {
        struct socket *sock;
+       int ret;
 
        sock = rcu_dereference_protected(vq->private_data,
                                         lockdep_is_held(&vq->mutex));
        if (!sock)
-               return;
+               return 0;
        if (vq == n->vqs + VHOST_NET_VQ_TX) {
                n->tx_poll_state = VHOST_NET_POLL_STOPPED;
-               tx_poll_start(n, sock);
+               ret = tx_poll_start(n, sock);
        } else
-               vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
+               ret = vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
+
+       return ret;
 }
 
 static struct socket *vhost_net_stop_vq(struct vhost_net *n,
@@ -827,15 +834,18 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
                        r = PTR_ERR(ubufs);
                        goto err_ubufs;
                }
-               oldubufs = vq->ubufs;
-               vq->ubufs = ubufs;
+
                vhost_net_disable_vq(n, vq);
                rcu_assign_pointer(vq->private_data, sock);
-               vhost_net_enable_vq(n, vq);
-
                r = vhost_init_used(vq);
                if (r)
-                       goto err_vq;
+                       goto err_used;
+               r = vhost_net_enable_vq(n, vq);
+               if (r)
+                       goto err_used;
+
+               oldubufs = vq->ubufs;
+               vq->ubufs = ubufs;
 
                n->tx_packets = 0;
                n->tx_zcopy_err = 0;
@@ -859,6 +869,11 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
        mutex_unlock(&n->dev.mutex);
        return 0;
 
+err_used:
+       rcu_assign_pointer(vq->private_data, oldsock);
+       vhost_net_enable_vq(n, vq);
+       if (ubufs)
+               vhost_ubuf_put_and_wait(ubufs);
 err_ubufs:
        fput(sock->file);
 err_vq:
index b20df5c..22321cf 100644 (file)
@@ -575,10 +575,8 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
 
        /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */
        tv_tpg = vs->vs_tpg;
-       if (unlikely(!tv_tpg)) {
-               pr_err("%s endpoint not set\n", __func__);
+       if (unlikely(!tv_tpg))
                return;
-       }
 
        mutex_lock(&vq->mutex);
        vhost_disable_notify(&vs->dev, vq);
index 34389f7..9759249 100644 (file)
@@ -77,26 +77,38 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
        init_poll_funcptr(&poll->table, vhost_poll_func);
        poll->mask = mask;
        poll->dev = dev;
+       poll->wqh = NULL;
 
        vhost_work_init(&poll->work, fn);
 }
 
 /* Start polling a file. We add ourselves to file's wait queue. The caller must
  * keep a reference to a file until after vhost_poll_stop is called. */
-void vhost_poll_start(struct vhost_poll *poll, struct file *file)
+int vhost_poll_start(struct vhost_poll *poll, struct file *file)
 {
        unsigned long mask;
+       int ret = 0;
 
        mask = file->f_op->poll(file, &poll->table);
        if (mask)
                vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
+       if (mask & POLLERR) {
+               if (poll->wqh)
+                       remove_wait_queue(poll->wqh, &poll->wait);
+               ret = -EINVAL;
+       }
+
+       return ret;
 }
 
 /* Stop polling a file. After this function returns, it becomes safe to drop the
  * file reference. You must also flush afterwards. */
 void vhost_poll_stop(struct vhost_poll *poll)
 {
-       remove_wait_queue(poll->wqh, &poll->wait);
+       if (poll->wqh) {
+               remove_wait_queue(poll->wqh, &poll->wait);
+               poll->wqh = NULL;
+       }
 }
 
 static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
@@ -792,7 +804,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
                fput(filep);
 
        if (pollstart && vq->handle_kick)
-               vhost_poll_start(&vq->poll, vq->kick);
+               r = vhost_poll_start(&vq->poll, vq->kick);
 
        mutex_unlock(&vq->mutex);
 
index 2639c58..17261e2 100644 (file)
@@ -42,7 +42,7 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work);
 
 void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
                     unsigned long mask, struct vhost_dev *dev);
-void vhost_poll_start(struct vhost_poll *poll, struct file *file);
+int vhost_poll_start(struct vhost_poll *poll, struct file *file);
 void vhost_poll_stop(struct vhost_poll *poll);
 void vhost_poll_flush(struct vhost_poll *poll);
 void vhost_poll_queue(struct vhost_poll *poll);
index f088d4c..d843296 100644 (file)
@@ -196,7 +196,7 @@ static int apple_bl_add(struct acpi_device *dev)
        return 0;
 }
 
-static int apple_bl_remove(struct acpi_device *dev, int type)
+static int apple_bl_remove(struct acpi_device *dev)
 {
        backlight_device_unregister(apple_backlight_device);
 
index 0be4df3..74d77df 100644 (file)
@@ -840,7 +840,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
 
        if (irq == -1) {
                irq = xen_allocate_irq_dynamic();
-               if (irq == -1)
+               if (irq < 0)
                        goto out;
 
                irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
@@ -944,7 +944,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
 
        if (irq == -1) {
                irq = xen_allocate_irq_dynamic();
-               if (irq == -1)
+               if (irq < 0)
                        goto out;
 
                irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
index da39191..c763479 100644 (file)
@@ -140,8 +140,7 @@ static int acpi_pad_add(struct acpi_device *device)
        return 0;
 }
 
-static int acpi_pad_remove(struct acpi_device *device,
-       int type)
+static int acpi_pad_remove(struct acpi_device *device)
 {
        mutex_lock(&xen_cpu_lock);
        xen_acpi_pad_idle_cpus(0);
index 97f5d26..37c1f82 100644 (file)
@@ -135,7 +135,6 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
                         struct pci_dev *dev, struct xen_pci_op *op)
 {
        struct xen_pcibk_dev_data *dev_data;
-       int otherend = pdev->xdev->otherend_id;
        int status;
 
        if (unlikely(verbose_request))
@@ -144,8 +143,9 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
        status = pci_enable_msi(dev);
 
        if (status) {
-               printk(KERN_ERR "error enable msi for guest %x status %x\n",
-                       otherend, status);
+               pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI for guest %u: err %d\n",
+                                   pci_name(dev), pdev->xdev->otherend_id,
+                                   status);
                op->value = 0;
                return XEN_PCI_ERR_op_failed;
        }
@@ -223,10 +223,10 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
                                                pci_name(dev), i,
                                                op->msix_entries[i].vector);
                }
-       } else {
-               printk(KERN_WARNING DRV_NAME ": %s: failed to enable MSI-X: err %d!\n",
-                       pci_name(dev), result);
-       }
+       } else
+               pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI-X for guest %u: err %d!\n",
+                                   pci_name(dev), pdev->xdev->otherend_id,
+                                   result);
        kfree(entries);
 
        op->value = result;
index a8b8adc..5a3327b 100644 (file)
@@ -4534,7 +4534,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        unsigned nr_extents = 0;
        int extra_reserve = 0;
        enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL;
-       int ret;
+       int ret = 0;
        bool delalloc_lock = true;
 
        /* If we are a free space inode we need to not flush since we will be in
@@ -4579,20 +4579,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        csum_bytes = BTRFS_I(inode)->csum_bytes;
        spin_unlock(&BTRFS_I(inode)->lock);
 
-       if (root->fs_info->quota_enabled) {
+       if (root->fs_info->quota_enabled)
                ret = btrfs_qgroup_reserve(root, num_bytes +
                                           nr_extents * root->leafsize);
-               if (ret) {
-                       spin_lock(&BTRFS_I(inode)->lock);
-                       calc_csum_metadata_size(inode, num_bytes, 0);
-                       spin_unlock(&BTRFS_I(inode)->lock);
-                       if (delalloc_lock)
-                               mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
-                       return ret;
-               }
-       }
 
-       ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
+       /*
+        * ret != 0 here means the qgroup reservation failed, we go straight to
+        * the shared error handling then.
+        */
+       if (ret == 0)
+               ret = reserve_metadata_bytes(root, block_rsv,
+                                            to_reserve, flush);
+
        if (ret) {
                u64 to_free = 0;
                unsigned dropped;
index 2e8cae6..fdb7a8d 100644 (file)
@@ -288,7 +288,8 @@ out:
 void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em)
 {
        clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
-       try_merge_map(tree, em);
+       if (em->in_tree)
+               try_merge_map(tree, em);
 }
 
 /**
index f76b1fd..aeb8446 100644 (file)
@@ -293,15 +293,24 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
        struct btrfs_key key;
        struct btrfs_ioctl_defrag_range_args range;
        int num_defrag;
+       int index;
+       int ret;
 
        /* get the inode */
        key.objectid = defrag->root;
        btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
        key.offset = (u64)-1;
+
+       index = srcu_read_lock(&fs_info->subvol_srcu);
+
        inode_root = btrfs_read_fs_root_no_name(fs_info, &key);
        if (IS_ERR(inode_root)) {
-               kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
-               return PTR_ERR(inode_root);
+               ret = PTR_ERR(inode_root);
+               goto cleanup;
+       }
+       if (btrfs_root_refs(&inode_root->root_item) == 0) {
+               ret = -ENOENT;
+               goto cleanup;
        }
 
        key.objectid = defrag->ino;
@@ -309,9 +318,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
        key.offset = 0;
        inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL);
        if (IS_ERR(inode)) {
-               kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
-               return PTR_ERR(inode);
+               ret = PTR_ERR(inode);
+               goto cleanup;
        }
+       srcu_read_unlock(&fs_info->subvol_srcu, index);
 
        /* do a chunk of defrag */
        clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
@@ -346,6 +356,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
 
        iput(inode);
        return 0;
+cleanup:
+       srcu_read_unlock(&fs_info->subvol_srcu, index);
+       kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
+       return ret;
 }
 
 /*
@@ -1594,9 +1608,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                if (err < 0 && num_written > 0)
                        num_written = err;
        }
-out:
+
        if (sync)
                atomic_dec(&BTRFS_I(inode)->sync_writers);
+out:
        sb_end_write(inode->i_sb);
        current->backing_dev_info = NULL;
        return num_written ? num_written : err;
index 5b22d45..338f259 100644 (file)
@@ -515,7 +515,6 @@ static noinline int create_subvol(struct btrfs_root *root,
 
        BUG_ON(ret);
 
-       d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
 fail:
        if (async_transid) {
                *async_transid = trans->transid;
@@ -525,6 +524,10 @@ fail:
        }
        if (err && !ret)
                ret = err;
+
+       if (!ret)
+               d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
+
        return ret;
 }
 
index f107312..e5ed567 100644 (file)
@@ -836,9 +836,16 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
         * if the disk i_size is already at the inode->i_size, or
         * this ordered extent is inside the disk i_size, we're done
         */
-       if (disk_i_size == i_size || offset <= disk_i_size) {
+       if (disk_i_size == i_size)
+               goto out;
+
+       /*
+        * We still need to update disk_i_size if outstanding_isize is greater
+        * than disk_i_size.
+        */
+       if (offset <= disk_i_size &&
+           (!ordered || ordered->outstanding_isize <= disk_i_size))
                goto out;
-       }
 
        /*
         * walk backward from this ordered extent to disk_i_size.
@@ -870,7 +877,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
                        break;
                if (test->file_offset >= i_size)
                        break;
-               if (test->file_offset >= disk_i_size) {
+               if (entry_end(test) > disk_i_size) {
                        /*
                         * we don't update disk_i_size now, so record this
                         * undealt i_size. Or we will not know the real
index bdbb94f..67783e0 100644 (file)
@@ -580,20 +580,29 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx)
        int corrected = 0;
        struct btrfs_key key;
        struct inode *inode = NULL;
+       struct btrfs_fs_info *fs_info;
        u64 end = offset + PAGE_SIZE - 1;
        struct btrfs_root *local_root;
+       int srcu_index;
 
        key.objectid = root;
        key.type = BTRFS_ROOT_ITEM_KEY;
        key.offset = (u64)-1;
-       local_root = btrfs_read_fs_root_no_name(fixup->root->fs_info, &key);
-       if (IS_ERR(local_root))
+
+       fs_info = fixup->root->fs_info;
+       srcu_index = srcu_read_lock(&fs_info->subvol_srcu);
+
+       local_root = btrfs_read_fs_root_no_name(fs_info, &key);
+       if (IS_ERR(local_root)) {
+               srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
                return PTR_ERR(local_root);
+       }
 
        key.type = BTRFS_INODE_ITEM_KEY;
        key.objectid = inum;
        key.offset = 0;
-       inode = btrfs_iget(fixup->root->fs_info->sb, &key, local_root, NULL);
+       inode = btrfs_iget(fs_info->sb, &key, local_root, NULL);
+       srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
        if (IS_ERR(inode))
                return PTR_ERR(inode);
 
@@ -606,7 +615,6 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx)
        }
 
        if (PageUptodate(page)) {
-               struct btrfs_fs_info *fs_info;
                if (PageDirty(page)) {
                        /*
                         * we need to write the data to the defect sector. the
@@ -3180,18 +3188,25 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, void *ctx)
        u64 physical_for_dev_replace;
        u64 len;
        struct btrfs_fs_info *fs_info = nocow_ctx->sctx->dev_root->fs_info;
+       int srcu_index;
 
        key.objectid = root;
        key.type = BTRFS_ROOT_ITEM_KEY;
        key.offset = (u64)-1;
+
+       srcu_index = srcu_read_lock(&fs_info->subvol_srcu);
+
        local_root = btrfs_read_fs_root_no_name(fs_info, &key);
-       if (IS_ERR(local_root))
+       if (IS_ERR(local_root)) {
+               srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
                return PTR_ERR(local_root);
+       }
 
        key.type = BTRFS_INODE_ITEM_KEY;
        key.objectid = inum;
        key.offset = 0;
        inode = btrfs_iget(fs_info->sb, &key, local_root, NULL);
+       srcu_read_unlock(&fs_info->subvol_srcu, srcu_index);
        if (IS_ERR(inode))
                return PTR_ERR(inode);
 
index f154946..fc03aa6 100644 (file)
@@ -333,12 +333,14 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type,
                                          &root->fs_info->trans_block_rsv,
                                          num_bytes, flush);
                if (ret)
-                       return ERR_PTR(ret);
+                       goto reserve_fail;
        }
 again:
        h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
-       if (!h)
-               return ERR_PTR(-ENOMEM);
+       if (!h) {
+               ret = -ENOMEM;
+               goto alloc_fail;
+       }
 
        /*
         * If we are JOIN_NOLOCK we're already committing a transaction and
@@ -365,11 +367,7 @@ again:
        if (ret < 0) {
                /* We must get the transaction if we are JOIN_NOLOCK. */
                BUG_ON(type == TRANS_JOIN_NOLOCK);
-
-               if (type < TRANS_JOIN_NOLOCK)
-                       sb_end_intwrite(root->fs_info->sb);
-               kmem_cache_free(btrfs_trans_handle_cachep, h);
-               return ERR_PTR(ret);
+               goto join_fail;
        }
 
        cur_trans = root->fs_info->running_transaction;
@@ -410,6 +408,19 @@ got_it:
        if (!current->journal_info && type != TRANS_USERSPACE)
                current->journal_info = h;
        return h;
+
+join_fail:
+       if (type < TRANS_JOIN_NOLOCK)
+               sb_end_intwrite(root->fs_info->sb);
+       kmem_cache_free(btrfs_trans_handle_cachep, h);
+alloc_fail:
+       if (num_bytes)
+               btrfs_block_rsv_release(root, &root->fs_info->trans_block_rsv,
+                                       num_bytes);
+reserve_fail:
+       if (qgroup_reserved)
+               btrfs_qgroup_free(root, qgroup_reserved);
+       return ERR_PTR(ret);
 }
 
 struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
index 15f6efd..5cbb7f4 100644 (file)
@@ -1556,7 +1556,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
        ret = 0;
 
        /* Notify udev that device has changed */
-       btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
+       if (bdev)
+               btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
 
 error_brelse:
        brelse(bh);
index 7ff4985..911649a 100644 (file)
@@ -503,11 +503,11 @@ static ssize_t device_write(struct file *file, const char __user *buf,
 #endif
                return -EINVAL;
 
-#ifdef CONFIG_COMPAT
-       if (count > sizeof(struct dlm_write_request32) + DLM_RESNAME_MAXLEN)
-#else
+       /*
+        * can't compare against COMPAT/dlm_write_request32 because
+        * we don't yet know if is64bit is zero
+        */
        if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN)
-#endif
                return -EINVAL;
 
        kbuf = kzalloc(count + 1, GFP_NOFS);
index fdb1807..f385935 100644 (file)
@@ -664,8 +664,11 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
        if (ret < 0)
                printk(KERN_ERR "NILFS: GC failed during preparation: "
                        "cannot read source blocks: err=%d\n", ret);
-       else
+       else {
+               if (nilfs_sb_need_update(nilfs))
+                       set_nilfs_discontinued(nilfs);
                ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+       }
 
        nilfs_remove_all_gcinodes(nilfs);
        clear_nilfs_gc_running(nilfs);
index 2df555c..aec3d5c 100644 (file)
@@ -205,6 +205,48 @@ void sysfs_unmerge_group(struct kobject *kobj,
 }
 EXPORT_SYMBOL_GPL(sysfs_unmerge_group);
 
+/**
+ * sysfs_add_link_to_group - add a symlink to an attribute group.
+ * @kobj:      The kobject containing the group.
+ * @group_name:        The name of the group.
+ * @target:    The target kobject of the symlink to create.
+ * @link_name: The name of the symlink to create.
+ */
+int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
+                           struct kobject *target, const char *link_name)
+{
+       struct sysfs_dirent *dir_sd;
+       int error = 0;
+
+       dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
+       if (!dir_sd)
+               return -ENOENT;
+
+       error = sysfs_create_link_sd(dir_sd, target, link_name);
+       sysfs_put(dir_sd);
+
+       return error;
+}
+EXPORT_SYMBOL_GPL(sysfs_add_link_to_group);
+
+/**
+ * sysfs_remove_link_from_group - remove a symlink from an attribute group.
+ * @kobj:      The kobject containing the group.
+ * @group_name:        The name of the group.
+ * @link_name: The name of the symlink to remove.
+ */
+void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
+                                 const char *link_name)
+{
+       struct sysfs_dirent *dir_sd;
+
+       dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
+       if (dir_sd) {
+               sysfs_hash_and_remove(dir_sd, NULL, link_name);
+               sysfs_put(dir_sd);
+       }
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group);
 
 EXPORT_SYMBOL_GPL(sysfs_create_group);
 EXPORT_SYMBOL_GPL(sysfs_update_group);
index 3c9eb56..8c940df 100644 (file)
 
 #include "sysfs.h"
 
-static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
-                               const char *name, int warn)
+static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
+                                  struct kobject *target,
+                                  const char *name, int warn)
 {
-       struct sysfs_dirent *parent_sd = NULL;
        struct sysfs_dirent *target_sd = NULL;
        struct sysfs_dirent *sd = NULL;
        struct sysfs_addrm_cxt acxt;
        enum kobj_ns_type ns_type;
        int error;
 
-       BUG_ON(!name);
-
-       if (!kobj)
-               parent_sd = &sysfs_root;
-       else
-               parent_sd = kobj->sd;
-
-       error = -EFAULT;
-       if (!parent_sd)
-               goto out_put;
+       BUG_ON(!name || !parent_sd);
 
        /* target->sd can go away beneath us but is protected with
         * sysfs_assoc_lock.  Fetch target_sd from it.
@@ -96,6 +87,34 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
 }
 
 /**
+ *     sysfs_create_link_sd - create symlink to a given object.
+ *     @sd:            directory we're creating the link in.
+ *     @target:        object we're pointing to.
+ *     @name:          name of the symlink.
+ */
+int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
+                        const char *name)
+{
+       return sysfs_do_create_link_sd(sd, target, name, 1);
+}
+
+static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
+                               const char *name, int warn)
+{
+       struct sysfs_dirent *parent_sd = NULL;
+
+       if (!kobj)
+               parent_sd = &sysfs_root;
+       else
+               parent_sd = kobj->sd;
+
+       if (!parent_sd)
+               return -EFAULT;
+
+       return sysfs_do_create_link_sd(parent_sd, target, name, warn);
+}
+
+/**
  *     sysfs_create_link - create symlink between two objects.
  *     @kobj:  object whose directory we're creating the link in.
  *     @target:        object we're pointing to.
index d73c093..d1e4043 100644 (file)
@@ -240,3 +240,5 @@ void unmap_bin_file(struct sysfs_dirent *attr_sd);
  * symlink.c
  */
 extern const struct inode_operations sysfs_symlink_inode_operations;
+int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target,
+                        const char *name);
index a1e45cd..c927a0b 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 0943457..14ceff7 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 /* Maximum sleep allowed via Sleep() operator */
 
-#define ACPI_MAX_SLEEP                  2000   /* Two seconds */
+#define ACPI_MAX_SLEEP                  2000   /* 2000 millisec == two seconds */
 
 /* Address Range lists are per-space_id (Memory and I/O only) */
 
  *
  *****************************************************************************/
 
-/* Number of distinct GPE register blocks and register width */
-
-#define ACPI_MAX_GPE_BLOCKS             2
-#define ACPI_GPE_REGISTER_WIDTH         8
-
 /* Method info (in WALK_STATE), containing local variables and argumetns */
 
 #define ACPI_METHOD_NUM_LOCALS          8
 #define ACPI_METHOD_NUM_ARGS            7
 #define ACPI_METHOD_MAX_ARG             6
 
-/* Length of _HID, _UID, _CID, and UUID values */
-
-#define ACPI_DEVICE_ID_LENGTH           0x09
-#define ACPI_MAX_CID_LENGTH             48
-#define ACPI_UUID_LENGTH                16
-
 /*
  * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
  */
  */
 #define ACPI_RESULTS_OBJ_NUM_MAX        255
 
-/* Names within the namespace are 4 bytes long */
-
-#define ACPI_NAME_SIZE                  4
-#define ACPI_PATH_SEGMENT_LENGTH        5      /* 4 chars for name + 1 char for separator */
-#define ACPI_PATH_SEPARATOR             '.'
-
-/* Sizes for ACPI table headers */
-
-#define ACPI_OEM_ID_SIZE                6
-#define ACPI_OEM_TABLE_ID_SIZE          8
-
 /* Constants used in searching for the RSDP in low memory */
 
 #define ACPI_EBDA_PTR_LOCATION          0x0000040E     /* Physical Address */
 /* Maximum space_ids for Operation Regions */
 
 #define ACPI_MAX_ADDRESS_SPACE          255
+#define ACPI_NUM_DEFAULT_SPACES         4
 
 /* Array sizes.  Used for range checking also */
 
index 6c3890e..9bf59d0 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7665df6..ce08ef7 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 2457ac8..9885276 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -72,6 +72,7 @@
 #define ACPI_EXAMPLE                0x00004000
 #define ACPI_DRIVER                 0x00008000
 #define DT_COMPILER                 0x00010000
+#define ASL_PREPROCESSOR            0x00020000
 
 #define ACPI_ALL_COMPONENTS         0x0001FFFF
 #define ACPI_COMPONENT_DEFAULT      (ACPI_ALL_COMPONENTS)
  * Common parameters used for debug output functions:
  * line number, function name, module(file) name, component ID
  */
-#define ACPI_DEBUG_PARAMETERS           __LINE__, ACPI_GET_FUNCTION_NAME, _acpi_module_name, _COMPONENT
+#define ACPI_DEBUG_PARAMETERS \
+       __LINE__, ACPI_GET_FUNCTION_NAME, _acpi_module_name, _COMPONENT
+
+/* Check if debug output is currently dynamically enabled */
+
+#define ACPI_IS_DEBUG_ENABLED(level, component) \
+       ((level & acpi_dbg_level) && (component & acpi_dbg_layer))
 
 /*
  * Master debug print macros
  * Print message if and only if:
  *    1) Debug print for the current component is enabled
  *    2) Debug error level or trace level for the print statement is enabled
+ *
+ * November 2012: Moved the runtime check for whether to actually emit the
+ * debug message outside of the print function itself. This improves overall
+ * performance at a relatively small code cost. Implementation involves the
+ * use of variadic macros supported by C99.
+ *
+ * Note: the ACPI_DO_WHILE0 macro is used to prevent some compilers from
+ * complaining about these constructs. On other compilers the do...while
+ * adds some extra code, so this feature is optional.
  */
-#define ACPI_DEBUG_PRINT(plist)         acpi_debug_print plist
-#define ACPI_DEBUG_PRINT_RAW(plist)     acpi_debug_print_raw plist
-
+#ifdef ACPI_USE_DO_WHILE_0
+#define ACPI_DO_WHILE0(a)               do a while(0)
 #else
+#define ACPI_DO_WHILE0(a)               a
+#endif
+
+/* DEBUG_PRINT functions */
+
+#define ACPI_DEBUG_PRINT(plist)         ACPI_ACTUAL_DEBUG plist
+#define ACPI_DEBUG_PRINT_RAW(plist)     ACPI_ACTUAL_DEBUG_RAW plist
+
+/* Helper macros for DEBUG_PRINT */
+
+#define ACPI_DO_DEBUG_PRINT(function, level, line, filename, modulename, component, ...) \
+       ACPI_DO_WHILE0 ({ \
+               if (ACPI_IS_DEBUG_ENABLED (level, component)) \
+               { \
+                       function (level, line, filename, modulename, component, __VA_ARGS__); \
+               } \
+       })
+
+#define ACPI_ACTUAL_DEBUG(level, line, filename, modulename, component, ...) \
+       ACPI_DO_DEBUG_PRINT (acpi_debug_print, level, line, \
+               filename, modulename, component, __VA_ARGS__)
+
+#define ACPI_ACTUAL_DEBUG_RAW(level, line, filename, modulename, component, ...) \
+       ACPI_DO_DEBUG_PRINT (acpi_debug_print_raw, level, line, \
+               filename, modulename, component, __VA_ARGS__)
+
+/*
+ * Function entry tracing
+ *
+ * The name of the function is emitted as a local variable that is
+ * intended to be used by both the entry trace and the exit trace.
+ */
+
+/* Helper macro */
+
+#define ACPI_TRACE_ENTRY(name, function, cast, param) \
+       ACPI_FUNCTION_NAME (name) \
+       function (ACPI_DEBUG_PARAMETERS, cast (param))
+
+/* The actual entry trace macros */
+
+#define ACPI_FUNCTION_TRACE(name) \
+       ACPI_FUNCTION_NAME(name) \
+       acpi_ut_trace (ACPI_DEBUG_PARAMETERS)
+
+#define ACPI_FUNCTION_TRACE_PTR(name, pointer) \
+       ACPI_TRACE_ENTRY (name, acpi_ut_trace_ptr, (void *), pointer)
+
+#define ACPI_FUNCTION_TRACE_U32(name, value) \
+       ACPI_TRACE_ENTRY (name, acpi_ut_trace_u32, (u32), value)
+
+#define ACPI_FUNCTION_TRACE_STR(name, string) \
+       ACPI_TRACE_ENTRY (name, acpi_ut_trace_str, (char *), string)
+
+#define ACPI_FUNCTION_ENTRY() \
+       acpi_ut_track_stack_ptr()
+
+/*
+ * Function exit tracing
+ *
+ * These macros include a return statement. This is usually considered
+ * bad form, but having a separate exit macro before the actual return
+ * is very ugly and difficult to maintain.
+ *
+ * One of the FUNCTION_TRACE macros above must be used in conjunction
+ * with these macros so that "_AcpiFunctionName" is defined.
+ */
+
+/* Exit trace helper macro */
+
+#define ACPI_TRACE_EXIT(function, cast, param) \
+       ACPI_DO_WHILE0 ({ \
+               function (ACPI_DEBUG_PARAMETERS, cast (param)); \
+               return ((param)); \
+       })
+
+/* The actual exit macros */
+
+#define return_VOID \
+       ACPI_DO_WHILE0 ({ \
+               acpi_ut_exit (ACPI_DEBUG_PARAMETERS); \
+               return; \
+       })
+
+#define return_ACPI_STATUS(status) \
+       ACPI_TRACE_EXIT (acpi_ut_status_exit, (acpi_status), status)
+
+#define return_PTR(pointer) \
+       ACPI_TRACE_EXIT (acpi_ut_ptr_exit, (u8 *), pointer)
+
+#define return_VALUE(value) \
+       ACPI_TRACE_EXIT (acpi_ut_value_exit, (u64), value)
+
+/* Conditional execution */
+
+#define ACPI_DEBUG_EXEC(a)              a
+#define ACPI_DEBUG_ONLY_MEMBERS(a)      a;
+#define _VERBOSE_STRUCTURES
+
+/* Various object display routines for debug */
+
+#define ACPI_DUMP_STACK_ENTRY(a)        acpi_ex_dump_operand((a), 0)
+#define ACPI_DUMP_OPERANDS(a, b ,c)     acpi_ex_dump_operands(a, b, c)
+#define ACPI_DUMP_ENTRY(a, b)           acpi_ns_dump_entry (a, b)
+#define ACPI_DUMP_PATHNAME(a, b, c, d)  acpi_ns_dump_pathname(a, b, c, d)
+#define ACPI_DUMP_BUFFER(a, b)          acpi_ut_debug_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT)
+
+#else                          /* ACPI_DEBUG_OUTPUT */
 /*
  * This is the non-debug case -- make everything go away,
  * leaving no executable debug code!
 #define ACPI_FUNCTION_NAME(a)
 #define ACPI_DEBUG_PRINT(pl)
 #define ACPI_DEBUG_PRINT_RAW(pl)
+#define ACPI_DEBUG_EXEC(a)
+#define ACPI_DEBUG_ONLY_MEMBERS(a)
+#define ACPI_FUNCTION_TRACE(a)
+#define ACPI_FUNCTION_TRACE_PTR(a, b)
+#define ACPI_FUNCTION_TRACE_U32(a, b)
+#define ACPI_FUNCTION_TRACE_STR(a, b)
+#define ACPI_FUNCTION_EXIT
+#define ACPI_FUNCTION_STATUS_EXIT(s)
+#define ACPI_FUNCTION_VALUE_EXIT(s)
+#define ACPI_FUNCTION_ENTRY()
+#define ACPI_DUMP_STACK_ENTRY(a)
+#define ACPI_DUMP_OPERANDS(a, b, c)
+#define ACPI_DUMP_ENTRY(a, b)
+#define ACPI_DUMP_TABLES(a, b)
+#define ACPI_DUMP_PATHNAME(a, b, c, d)
+#define ACPI_DUMP_BUFFER(a, b)
+#define ACPI_DEBUG_PRINT(pl)
+#define ACPI_DEBUG_PRINT_RAW(pl)
+#define ACPI_IS_DEBUG_ENABLED(level, component) 0
+
+/* Return macros must have a return statement at the minimum */
+
+#define return_VOID                     return
+#define return_ACPI_STATUS(s)           return(s)
+#define return_VALUE(s)                 return(s)
+#define return_PTR(s)                   return(s)
 
 #endif                         /* ACPI_DEBUG_OUTPUT */
 
index c1ea843..6187877 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index 7ced5dc..227ba7d 100644 (file)
@@ -84,28 +84,29 @@ struct acpi_driver;
 struct acpi_device;
 
 /*
+ * ACPI Scan Handler
+ * -----------------
+ */
+
+struct acpi_scan_handler {
+       const struct acpi_device_id *ids;
+       struct list_head list_node;
+       int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
+       void (*detach)(struct acpi_device *dev);
+};
+
+/*
  * ACPI Driver
  * -----------
  */
 
 typedef int (*acpi_op_add) (struct acpi_device * device);
-typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
-typedef int (*acpi_op_start) (struct acpi_device * device);
-typedef int (*acpi_op_bind) (struct acpi_device * device);
-typedef int (*acpi_op_unbind) (struct acpi_device * device);
+typedef int (*acpi_op_remove) (struct acpi_device * device);
 typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
 
-struct acpi_bus_ops {
-       u32 acpi_op_add:1;
-       u32 acpi_op_start:1;
-};
-
 struct acpi_device_ops {
        acpi_op_add add;
        acpi_op_remove remove;
-       acpi_op_start start;
-       acpi_op_bind bind;
-       acpi_op_unbind unbind;
        acpi_op_notify notify;
 };
 
@@ -148,7 +149,8 @@ struct acpi_device_flags {
        u32 power_manageable:1;
        u32 performance_manageable:1;
        u32 eject_pending:1;
-       u32 reserved:24;
+       u32 match_driver:1;
+       u32 reserved:23;
 };
 
 /* File System */
@@ -207,7 +209,7 @@ struct acpi_device_power_state {
        } flags;
        int power;              /* % Power (compared to D0) */
        int latency;            /* Dx->D0 time (microseconds) */
-       struct acpi_handle_list resources;      /* Power resources referenced */
+       struct list_head resources;     /* Power resources referenced */
 };
 
 struct acpi_device_power {
@@ -250,7 +252,7 @@ struct acpi_device_wakeup {
        acpi_handle gpe_device;
        u64 gpe_number;
        u64 sleep_state;
-       struct acpi_handle_list resources;
+       struct list_head resources;
        struct acpi_device_wakeup_flags flags;
        int prepare_count;
 };
@@ -279,16 +281,17 @@ struct acpi_device {
        struct acpi_device_wakeup wakeup;
        struct acpi_device_perf performance;
        struct acpi_device_dir dir;
-       struct acpi_device_ops ops;
+       struct acpi_scan_handler *handler;
        struct acpi_driver *driver;
        void *driver_data;
        struct device dev;
-       struct acpi_bus_ops bus_ops;    /* workaround for different code path for hotplug */
        enum acpi_bus_removal_type removal_type;        /* indicate for different removal type */
        u8 physical_node_count;
        struct list_head physical_node_list;
        struct mutex physical_node_lock;
        DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
+       struct list_head power_dependent;
+       void (*remove)(struct acpi_device *);
 };
 
 static inline void *acpi_driver_data(struct acpi_device *d)
@@ -316,7 +319,7 @@ struct acpi_bus_event {
 };
 
 struct acpi_eject_event {
-       acpi_handle     handle;
+       struct acpi_device      *device;
        u32             event;
 };
 
@@ -339,13 +342,51 @@ void acpi_bus_data_handler(acpi_handle handle, void *context);
 acpi_status acpi_bus_get_status_handle(acpi_handle handle,
                                       unsigned long long *sta);
 int acpi_bus_get_status(struct acpi_device *device);
+
+#ifdef CONFIG_PM
 int acpi_bus_set_power(acpi_handle handle, int state);
+const char *acpi_power_state_string(int state);
+int acpi_device_get_power(struct acpi_device *device, int *state);
 int acpi_device_set_power(struct acpi_device *device, int state);
+int acpi_bus_init_power(struct acpi_device *device);
 int acpi_bus_update_power(acpi_handle handle, int *state_p);
 bool acpi_bus_power_manageable(acpi_handle handle);
 bool acpi_bus_can_wakeup(acpi_handle handle);
-int acpi_power_resource_register_device(struct device *dev, acpi_handle handle);
-void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle);
+#else /* !CONFIG_PM */
+static inline int acpi_bus_set_power(acpi_handle handle, int state)
+{
+       return 0;
+}
+static inline const char *acpi_power_state_string(int state)
+{
+       return "D0";
+}
+static inline int acpi_device_get_power(struct acpi_device *device, int *state)
+{
+       return 0;
+}
+static inline int acpi_device_set_power(struct acpi_device *device, int state)
+{
+       return 0;
+}
+static inline int acpi_bus_init_power(struct acpi_device *device)
+{
+       return 0;
+}
+static inline int acpi_bus_update_power(acpi_handle handle, int *state_p)
+{
+       return 0;
+}
+static inline bool acpi_bus_power_manageable(acpi_handle handle)
+{
+       return false;
+}
+static inline bool acpi_bus_can_wakeup(acpi_handle handle)
+{
+       return false;
+}
+#endif /* !CONFIG_PM */
+
 #ifdef CONFIG_ACPI_PROC_EVENT
 int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
 int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
@@ -354,13 +395,15 @@ int acpi_bus_receive_event(struct acpi_bus_event *event);
 static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
        { return 0; }
 #endif
+
+void acpi_scan_lock_acquire(void);
+void acpi_scan_lock_release(void);
+int acpi_scan_add_handler(struct acpi_scan_handler *handler);
 int acpi_bus_register_driver(struct acpi_driver *driver);
 void acpi_bus_unregister_driver(struct acpi_driver *driver);
-int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
-                acpi_handle handle, int type);
+int acpi_bus_scan(acpi_handle handle);
 void acpi_bus_hot_remove_device(void *context);
-int acpi_bus_trim(struct acpi_device *start, int rmdevice);
-int acpi_bus_start(struct acpi_device *device);
+void acpi_bus_trim(struct acpi_device *start);
 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
 int acpi_match_device_ids(struct acpi_device *device,
                          const struct acpi_device_id *ids);
@@ -390,6 +433,8 @@ struct acpi_bus_type {
        int (*find_device) (struct device *, acpi_handle *);
        /* For bridges, such as PCI root bridge, IDE controller */
        int (*find_bridge) (struct device *, acpi_handle *);
+       void (*setup)(struct device *);
+       void (*cleanup)(struct device *);
 };
 int register_acpi_bus_type(struct acpi_bus_type *);
 int unregister_acpi_bus_type(struct acpi_bus_type *);
@@ -397,7 +442,6 @@ int unregister_acpi_bus_type(struct acpi_bus_type *);
 struct acpi_pci_root {
        struct list_head node;
        struct acpi_device * device;
-       struct acpi_pci_id id;
        struct pci_bus *bus;
        u16 segment;
        struct resource secondary;      /* downstream bus range */
@@ -425,6 +469,8 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
 int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
                            u32 target_state, int d_max_in, int *d_min_p);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
+void acpi_dev_pm_add_dependent(acpi_handle handle, struct device *depdev);
+void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev);
 #else
 static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
                                               acpi_notify_handler handler,
@@ -454,6 +500,10 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
 {
        return __acpi_device_power_state(m, p);
 }
+static inline void acpi_dev_pm_add_dependent(acpi_handle handle,
+                                            struct device *depdev) {}
+static inline void acpi_dev_pm_remove_dependent(acpi_handle handle,
+                                               struct device *depdev) {}
 #endif
 
 #ifdef CONFIG_PM_RUNTIME
index 4315274..7d2a9ea 100644 (file)
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -102,10 +102,8 @@ acpi_os_physical_table_override(struct acpi_table_header *existing_table,
 /*
  * Spinlock primitives
  */
-
 #ifndef acpi_os_create_lock
-acpi_status
-acpi_os_create_lock(acpi_spinlock *out_handle);
+acpi_status acpi_os_create_lock(acpi_spinlock * out_handle);
 #endif
 
 void acpi_os_delete_lock(acpi_spinlock handle);
@@ -148,6 +146,8 @@ void acpi_os_release_mutex(acpi_mutex handle);
  */
 void *acpi_os_allocate(acpi_size size);
 
+void acpi_os_free(void *memory);
+
 void __iomem *acpi_os_map_memory(acpi_physical_address where,
                                acpi_size length);
 
@@ -180,12 +180,13 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object);
  * Interrupt handlers
  */
 acpi_status
-acpi_os_install_interrupt_handler(u32 gsi,
+acpi_os_install_interrupt_handler(u32 interrupt_number,
                                  acpi_osd_handler service_routine,
                                  void *context);
 
 acpi_status
-acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
+acpi_os_remove_interrupt_handler(u32 interrupt_number,
+                                acpi_osd_handler service_routine);
 
 void acpi_os_gpe_count(u32 gpe_number);
 void acpi_os_fixed_event_count(u32 fixed_event_number);
index 3d88395..03322dd 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20121018
+#define ACPI_CA_VERSION                 0x20130117
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
 extern u8 acpi_gbl_permanent_mmap;
 
 /*
- * Globals that are publicly available, allowing for
- * run time configuration
+ * Globals that are publically available
  */
+extern u32 acpi_current_gpe_count;
+extern struct acpi_table_fadt acpi_gbl_FADT;
+extern u8 acpi_gbl_system_awake_and_running;
+extern u8 acpi_gbl_reduced_hardware;   /* ACPI 5.0 */
+
+/* Runtime configuration of debug print levels */
+
 extern u32 acpi_dbg_level;
 extern u32 acpi_dbg_layer;
+
+/* ACPICA runtime options */
+
 extern u8 acpi_gbl_enable_interpreter_slack;
 extern u8 acpi_gbl_all_methods_serialized;
 extern u8 acpi_gbl_create_osi_method;
@@ -99,14 +108,9 @@ extern u8 acpi_gbl_disable_auto_repair;
 
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
-extern u32 acpi_current_gpe_count;
-extern struct acpi_table_fadt acpi_gbl_FADT;
-extern u8 acpi_gbl_system_awake_and_running;
-extern u8 acpi_gbl_reduced_hardware;   /* ACPI 5.0 */
-
 extern u32 acpi_rsdt_forced;
 /*
- * Global interfaces
+ * Initialization
  */
 acpi_status
 acpi_initialize_tables(struct acpi_table_desc *initial_storage,
@@ -120,13 +124,15 @@ acpi_status acpi_initialize_objects(u32 flags);
 
 acpi_status acpi_terminate(void);
 
+/*
+ * Miscellaneous global interfaces
+ */
+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_status acpi_subsystem_status(void);
 #endif
 
-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_status acpi_get_system_info(struct acpi_buffer *ret_buffer);
 #endif
@@ -191,9 +197,9 @@ acpi_status
 acpi_get_table_by_index(u32 table_index, struct acpi_table_header **out_table);
 
 acpi_status
-acpi_install_table_handler(acpi_tbl_handler handler, void *context);
+acpi_install_table_handler(acpi_table_handler handler, void *context);
 
-acpi_status acpi_remove_table_handler(acpi_tbl_handler handler);
+acpi_status acpi_remove_table_handler(acpi_table_handler handler);
 
 /*
  * Namespace and name interfaces
@@ -438,6 +444,11 @@ acpi_get_event_resources(acpi_handle device_handle,
                         struct acpi_buffer *ret_buffer);
 
 acpi_status
+acpi_walk_resource_buffer(struct acpi_buffer *buffer,
+                         acpi_walk_resource_callback user_function,
+                         void *context);
+
+acpi_status
 acpi_walk_resources(acpi_handle device,
                    char *name,
                    acpi_walk_resource_callback user_function, void *context);
@@ -462,6 +473,10 @@ acpi_buffer_to_resource(u8 *aml_buffer,
  */
 acpi_status acpi_reset(void);
 
+acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg);
+
+acpi_status acpi_write(u64 value, struct acpi_generic_address *reg);
+
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
                                acpi_read_bit_register(u32 register_id,
                                                       u32 *return_value))
@@ -470,20 +485,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
                                acpi_write_bit_register(u32 register_id,
                                                        u32 value))
 
-ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-                               acpi_set_firmware_waking_vector(u32
-                                                               physical_address))
-
-#if ACPI_MACHINE_WIDTH == 64
-ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-                               acpi_set_firmware_waking_vector64(u64
-                                                                 physical_address))
-#endif
-
-acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg);
-
-acpi_status acpi_write(u64 value, struct acpi_generic_address *reg);
-
 /*
  * Sleep/Wake interfaces
  */
@@ -500,6 +501,15 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state);
 
 acpi_status acpi_leave_sleep_state(u8 sleep_state);
 
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
+                               acpi_set_firmware_waking_vector(u32
+                                                               physical_address))
+
+#if ACPI_MACHINE_WIDTH == 64
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
+                               acpi_set_firmware_waking_vector64(u64
+                                                                 physical_address))
+#endif
 /*
  * ACPI Timer interfaces
  */
index 40349ae..cbf4bf9 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -102,8 +102,11 @@ typedef u32 acpi_rsdesc_size;      /* Max Resource Descriptor size is (Length+3) = (6
 
 #define ACPI_EXCLUSIVE                  (u8) 0x00
 #define ACPI_SHARED                     (u8) 0x01
-#define ACPI_EXCLUSIVE_AND_WAKE         (u8) 0x02
-#define ACPI_SHARED_AND_WAKE            (u8) 0x03
+
+/* Wake */
+
+#define ACPI_NOT_WAKE_CAPABLE           (u8) 0x00
+#define ACPI_WAKE_CAPABLE               (u8) 0x01
 
 /*
  * DMA Attributes
@@ -171,6 +174,7 @@ struct acpi_resource_irq {
        u8 triggering;
        u8 polarity;
        u8 sharable;
+       u8 wake_capable;
        u8 interrupt_count;
        u8 interrupts[1];
 };
@@ -346,6 +350,7 @@ struct acpi_resource_extended_irq {
        u8 triggering;
        u8 polarity;
        u8 sharable;
+       u8 wake_capable;
        u8 interrupt_count;
        struct acpi_resource_source resource_source;
        u32 interrupts[1];
@@ -365,6 +370,7 @@ struct acpi_resource_gpio {
        u8 producer_consumer;   /* For values, see Producer/Consumer above */
        u8 pin_config;
        u8 sharable;            /* For values, see Interrupt Attributes above */
+       u8 wake_capable;        /* For values, see Interrupt Attributes above */
        u8 io_restriction;
        u8 triggering;          /* For values, see Interrupt Attributes above */
        u8 polarity;            /* For values, see Interrupt Attributes above */
@@ -591,7 +597,10 @@ struct acpi_resource {
 #define ACPI_RS_SIZE_MIN                    (u32) ACPI_ROUND_UP_TO_NATIVE_WORD (12)
 #define ACPI_RS_SIZE(type)                  (u32) (ACPI_RS_SIZE_NO_DATA + sizeof (type))
 
-#define ACPI_NEXT_RESOURCE(res)             (struct acpi_resource *)((u8 *) res + res->length)
+/* Macro for walking resource templates with multiple descriptors */
+
+#define ACPI_NEXT_RESOURCE(res) \
+       ACPI_ADD_PTR (struct acpi_resource, (res), (res)->length)
 
 struct acpi_pci_routing_table {
        u32 length;
index 4f94b1d..9b58a8f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -326,8 +326,6 @@ enum acpi_preferred_pm_profiles {
 
 #pragma pack()
 
-#define ACPI_FADT_OFFSET(f)             (u16) ACPI_OFFSET (struct acpi_table_fadt, f)
-
 /*
  * Internal table-related structures
  */
@@ -359,11 +357,14 @@ struct acpi_table_desc {
 /*
  * Get the remaining ACPI tables
  */
-
 #include <acpi/actbl1.h>
 #include <acpi/actbl2.h>
 #include <acpi/actbl3.h>
 
+/* Macros used to generate offsets to specific table fields */
+
+#define ACPI_FADT_OFFSET(f)             (u16) ACPI_OFFSET (struct acpi_table_fadt, f)
+
 /*
  * Sizes of the various flavors of FADT. We need to look closely
  * at the FADT length because the version number essentially tells
index 280fc45..0bd750e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -768,7 +768,7 @@ struct acpi_madt_interrupt_source {
 
 struct acpi_madt_local_x2apic {
        struct acpi_subtable_header header;
-       u16 reserved;           /* Reserved - must be zero */
+       u16 reserved;           /* reserved - must be zero */
        u32 local_apic_id;      /* Processor x2APIC ID  */
        u32 lapic_flags;
        u32 uid;                /* ACPI processor UID */
@@ -781,14 +781,14 @@ struct acpi_madt_local_x2apic_nmi {
        u16 inti_flags;
        u32 uid;                /* ACPI processor UID */
        u8 lint;                /* LINTn to which NMI is connected */
-       u8 reserved[3];
+       u8 reserved[3];         /* reserved - must be zero */
 };
 
 /* 11: Generic Interrupt (ACPI 5.0) */
 
 struct acpi_madt_generic_interrupt {
        struct acpi_subtable_header header;
-       u16 reserved;           /* Reserved - must be zero */
+       u16 reserved;           /* reserved - must be zero */
        u32 gic_id;
        u32 uid;
        u32 flags;
index 1b2b356..77dc7a4 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -261,9 +261,28 @@ struct acpi_csrt_group {
        u16 subdevice_id;
        u16 revision;
        u16 reserved;
-       u32 info_length;
+       u32 shared_info_length;
 
-       /* Shared data (length = info_length) immediately follows */
+       /* Shared data immediately follows (Length = shared_info_length) */
+};
+
+/* Shared Info subtable */
+
+struct acpi_csrt_shared_info {
+       u16 major_version;
+       u16 minor_version;
+       u32 mmio_base_low;
+       u32 mmio_base_high;
+       u32 gsi_interrupt;
+       u8 interrupt_polarity;
+       u8 interrupt_mode;
+       u8 num_channels;
+       u8 dma_address_width;
+       u16 base_request_line;
+       u16 num_handshake_signals;
+       u32 max_block_size;
+
+       /* Resource descriptors immediately follow (Length = Group length - shared_info_length) */
 };
 
 /* Resource Descriptor subtable */
index 6585141..332b17e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #define ACPI_SIG_PCCT           "PCCT" /* Platform Communications Channel Table */
 #define ACPI_SIG_PMTT           "PMTT" /* Platform Memory Topology Table */
 #define ACPI_SIG_RASF           "RASF" /* RAS Feature table */
+#define ACPI_SIG_TPM2           "TPM2" /* Trusted Platform Module 2.0 H/W interface table */
 
 #define ACPI_SIG_S3PT           "S3PT" /* S3 Performance (sub)Table */
 #define ACPI_SIG_PCCS           "PCC"  /* PCC Shared Memory Region */
 
 /* Reserved table signatures */
 
-#define ACPI_SIG_CSRT           "CSRT" /* Core System Resources Table */
 #define ACPI_SIG_MATR           "MATR" /* Memory Address Translation Table */
 #define ACPI_SIG_MSDM           "MSDM" /* Microsoft Data Management Table */
 #define ACPI_SIG_WPBT           "WPBT" /* Windows Platform Binary Table */
@@ -550,6 +550,36 @@ enum acpi_rasf_status {
 #define ACPI_RASF_ERROR                 (1<<2)
 #define ACPI_RASF_STATUS                (0x1F<<3)
 
+/*******************************************************************************
+ *
+ * TPM2 - Trusted Platform Module (TPM) 2.0 Hardware Interface Table
+ *        Version 3
+ *
+ * Conforms to "TPM 2.0 Hardware Interface Table (TPM2)" 29 November 2011
+ *
+ ******************************************************************************/
+
+struct acpi_table_tpm2 {
+       struct acpi_table_header header;        /* Common ACPI table header */
+       u32 flags;
+       u64 control_address;
+       u32 start_method;
+};
+
+/* Control area structure (not part of table, pointed to by control_address) */
+
+struct acpi_tpm2_control {
+       u32 reserved;
+       u32 error;
+       u32 cancel;
+       u32 start;
+       u64 interrupt_control;
+       u32 command_size;
+       u64 command_address;
+       u32 response_size;
+       u64 response_address;
+};
+
 /* Reset to default packing */
 
 #pragma pack()
index 4f43f1f..845e75f 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -341,7 +341,7 @@ typedef u32 acpi_physical_address;
 
 /* PM Timer ticks per second (HZ) */
 
-#define PM_TIMER_FREQUENCY              3579545
+#define ACPI_PM_TIMER_FREQUENCY         3579545
 
 /*******************************************************************************
  *
@@ -373,6 +373,21 @@ typedef u32 acpi_name;             /* 4-byte ACPI name */
 typedef char *acpi_string;     /* Null terminated ASCII string */
 typedef void *acpi_handle;     /* Actually a ptr to a NS Node */
 
+/* Time constants for timer calculations */
+
+#define ACPI_MSEC_PER_SEC               1000L
+
+#define ACPI_USEC_PER_MSEC              1000L
+#define ACPI_USEC_PER_SEC               1000000L
+
+#define ACPI_100NSEC_PER_USEC           10L
+#define ACPI_100NSEC_PER_MSEC           10000L
+#define ACPI_100NSEC_PER_SEC            10000000L
+
+#define ACPI_NSEC_PER_USEC              1000L
+#define ACPI_NSEC_PER_MSEC              1000000L
+#define ACPI_NSEC_PER_SEC               1000000000L
+
 /* Owner IDs are used to track namespace nodes for selective deletion */
 
 typedef u8 acpi_owner_id;
@@ -390,10 +405,6 @@ typedef u8 acpi_owner_id;
 #define ACPI_MAX16_DECIMAL_DIGITS        5
 #define ACPI_MAX8_DECIMAL_DIGITS         3
 
-/* PM Timer ticks per second (HZ) */
-
-#define PM_TIMER_FREQUENCY  3579545
-
 /*
  * Constants with special meanings
  */
@@ -474,6 +485,7 @@ typedef u64 acpi_integer;
  */
 #define ACPI_FULL_INITIALIZATION        0x00
 #define ACPI_NO_ADDRESS_SPACE_INIT      0x01
+#define ACPI_NO_HARDWARE_INIT           0x02
 #define ACPI_NO_EVENT_INIT              0x04
 #define ACPI_NO_HANDLER_INIT            0x08
 #define ACPI_NO_ACPI_ENABLE             0x10
@@ -595,7 +607,7 @@ typedef u32 acpi_object_type;
 
 /*
  * These are special object types that never appear in
- * a Namespace node, only in a union acpi_operand_object
+ * a Namespace node, only in an object of union acpi_operand_object
  */
 #define ACPI_TYPE_LOCAL_EXTRA           0x1C
 #define ACPI_TYPE_LOCAL_DATA            0x1D
@@ -662,7 +674,7 @@ typedef u32 acpi_event_status;
 #define ACPI_GPE_MAX                    0xFF
 #define ACPI_NUM_GPE                    256
 
-/* Actions for acpi_set_gpe_wake_mask, acpi_hw_low_set_gpe */
+/* Actions for acpi_set_gpe, acpi_gpe_wakeup, acpi_hw_low_set_gpe */
 
 #define ACPI_GPE_ENABLE                 0
 #define ACPI_GPE_DISABLE                1
@@ -880,6 +892,10 @@ struct acpi_buffer {
        void *pointer;          /* pointer to buffer */
 };
 
+/* Free a buffer created in an struct acpi_buffer via ACPI_ALLOCATE_LOCAL_BUFFER */
+
+#define ACPI_FREE_BUFFER(b)         ACPI_FREE(b.pointer)
+
 /*
  * name_type for acpi_get_name
  */
@@ -968,7 +984,11 @@ acpi_status(*acpi_exception_handler) (acpi_status aml_status,
 /* Table Event handler (Load, load_table, etc.) and types */
 
 typedef
-acpi_status(*acpi_tbl_handler) (u32 event, void *table, void *context);
+acpi_status(*acpi_table_handler) (u32 event, void *table, void *context);
+
+#define ACPI_TABLE_LOAD             0x0
+#define ACPI_TABLE_UNLOAD           0x1
+#define ACPI_NUM_TABLE_EVENTS       2
 
 /* Address Spaces (For Operation Regions) */
 
diff --git a/include/acpi/container.h b/include/acpi/container.h
deleted file mode 100644 (file)
index a703f14..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __ACPI_CONTAINER_H
-#define __ACPI_CONTAINER_H
-
-#include <linux/kernel.h>
-
-struct acpi_container {
-       acpi_handle handle;
-       unsigned long sun;
-       int state;
-};
-
-#endif                         /* __ACPI_CONTAINER_H */
index 89cee88..ef04b36 100644 (file)
@@ -1,11 +1,11 @@
 /******************************************************************************
  *
- * Name: acenv.h - Generation environment specific items
+ * Name: acenv.h - Host and compiler configuration
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifndef __ACENV_H__
 #define __ACENV_H__
 
+/*
+ * Environment configuration. The purpose of this file is to interface ACPICA
+ * to the local environment. This includes compiler-specific, OS-specific,
+ * and machine-specific configuration.
+ */
+
 /* Types for ACPI_MUTEX_TYPE */
 
 #define ACPI_BINARY_SEMAPHORE       0
  *
  *****************************************************************************/
 
-#ifdef ACPI_LIBRARY
-/*
- * Note: The non-debug version of the acpi_library does not contain any
- * debug support, for minimal size. The debug version uses ACPI_FULL_DEBUG
- */
-#define ACPI_USE_LOCAL_CACHE
-#endif
+/* iASL configuration */
 
 #ifdef ACPI_ASL_COMPILER
-#define ACPI_DEBUG_OUTPUT
 #define ACPI_APPLICATION
 #define ACPI_DISASSEMBLER
+#define ACPI_DEBUG_OUTPUT
 #define ACPI_CONSTANT_EVAL_ONLY
 #define ACPI_LARGE_NAMESPACE_NODE
 #define ACPI_DATA_TABLE_DISASSEMBLY
+#define ACPI_SINGLE_THREADED
 #endif
 
+/* acpi_exec configuration. Multithreaded with full AML debugger */
+
 #ifdef ACPI_EXEC_APP
-#undef DEBUGGER_THREADING
-#define DEBUGGER_THREADING      DEBUGGER_SINGLE_THREADED
-#define ACPI_FULL_DEBUG
 #define ACPI_APPLICATION
-#define ACPI_DEBUGGER
+#define ACPI_FULL_DEBUG
 #define ACPI_MUTEX_DEBUG
 #define ACPI_DBG_TRACK_ALLOCATIONS
 #endif
 
+/* acpi_names configuration. Single threaded with debugger output enabled. */
+
+#ifdef ACPI_NAMES_APP
+#define ACPI_DEBUGGER
+#define ACPI_APPLICATION
+#define ACPI_SINGLE_THREADED
+#endif
+
+/*
+ * acpi_bin/acpi_help/acpi_src configuration. All single threaded, with
+ * no debug output.
+ */
+#if (defined ACPI_BIN_APP)   || \
+       (defined ACPI_SRC_APP)   || \
+       (defined ACPI_XTRACT_APP)
+#define ACPI_APPLICATION
+#define ACPI_SINGLE_THREADED
+#endif
+
+#ifdef ACPI_HELP_APP
+#define ACPI_APPLICATION
+#define ACPI_SINGLE_THREADED
+#define ACPI_NO_ERROR_MESSAGES
+#endif
+
+/* Linkable ACPICA library */
+
+#ifdef ACPI_LIBRARY
+#define ACPI_USE_LOCAL_CACHE
+#define ACPI_FUTURE_USAGE
+#endif
+
+/* Common for all ACPICA applications */
+
 #ifdef ACPI_APPLICATION
 #define ACPI_USE_SYSTEM_CLIBRARY
 #define ACPI_USE_LOCAL_CACHE
 #endif
 
+/* Common debug support */
+
 #ifdef ACPI_FULL_DEBUG
 #define ACPI_DEBUGGER
 #define ACPI_DEBUG_OUTPUT
 #define ACPI_DISASSEMBLER
 #endif
 
-/*
- * Environment configuration.  The purpose of this file is to interface to the
- * local generation environment.
- *
- * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
- *      Otherwise, local versions of string/memory functions will be used.
- * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
- *      the standard header files may be used.
- *
- * The ACPI subsystem only uses low level C library functions that do not call
- * operating system services and may therefore be inlined in the code.
- *
- * It may be necessary to tailor these include files to the target
- * generation environment.
- *
- *
- * Functions and constants used from each header:
- *
- * string.h:    memcpy
- *              memset
- *              strcat
- *              strcmp
- *              strcpy
- *              strlen
- *              strncmp
- *              strncat
- *              strncpy
- *
- * stdlib.h:    strtoul
- *
- * stdarg.h:    va_list
- *              va_arg
- *              va_start
- *              va_end
- *
- */
 
 /*! [Begin] no source code translation */
 
+/******************************************************************************
+ *
+ * Host configuration files. The compiler configuration files are included
+ * by the host files.
+ *
+ *****************************************************************************/
+
 #if defined(_LINUX) || defined(__linux__)
 #include <acpi/platform/aclinux.h>
 
-#elif defined(_AED_EFI)
-#include "acefi.h"
-
-#elif defined(WIN32)
-#include "acwin.h"
-
-#elif defined(WIN64)
-#include "acwin64.h"
-
-#elif defined(MSDOS)           /* Must appear after WIN32 and WIN64 check */
-#include "acdos16.h"
-
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include "acfreebsd.h"
 
 #elif defined(__NetBSD__)
 #include "acnetbsd.h"
 
+#elif defined(__sun)
+#include "acsolaris.h"
+
 #elif defined(MODESTO)
 #include "acmodesto.h"
 
 #elif defined(NETWARE)
 #include "acnetware.h"
 
-#elif defined(__sun)
-#include "acsolaris.h"
+#elif defined(_CYGWIN)
+#include "accygwin.h"
 
-#else
+#elif defined(WIN32)
+#include "acwin.h"
+
+#elif defined(WIN64)
+#include "acwin64.h"
 
-/* All other environments */
+#elif defined(_WRS_LIB_BUILD)
+#include "acvxworks.h"
 
-#define ACPI_USE_STANDARD_HEADERS
+#elif defined(__OS2__)
+#include "acos2.h"
 
-#define COMPILER_DEPENDENT_INT64   long long
-#define COMPILER_DEPENDENT_UINT64  unsigned long long
+#elif defined(_AED_EFI)
+#include "acefi.h"
+
+#elif defined(__HAIKU__)
+#include "achaiku.h"
 
+#else
+
+/* Unknown environment */
+
+#error Unknown target environment
 #endif
 
 /*! [End] no source code translation !*/
 
 /******************************************************************************
  *
- * Miscellaneous configuration
+ * Setup defaults for the required symbols that were not defined in one of
+ * the host/compiler files above.
  *
  *****************************************************************************/
 
-/*
- * Are mutexes supported by the host? default is no, use binary semaphores.
- */
+/* 64-bit data types */
+
+#ifndef COMPILER_DEPENDENT_INT64
+#define COMPILER_DEPENDENT_INT64   long long
+#endif
+
+#ifndef COMPILER_DEPENDENT_UINT64
+#define COMPILER_DEPENDENT_UINT64  unsigned long long
+#endif
+
+/* Type of mutex supported by host. Default is binary semaphores. */
 #ifndef ACPI_MUTEX_TYPE
 #define ACPI_MUTEX_TYPE             ACPI_BINARY_SEMAPHORE
 #endif
 
+/* Global Lock acquire/release */
+
+#ifndef ACPI_ACQUIRE_GLOBAL_LOCK
+#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acquired) acquired = 1
+#endif
+
+#ifndef ACPI_RELEASE_GLOBAL_LOCK
+#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, pending) pending = 0
+#endif
+
+/* Flush CPU cache - used when going to sleep. Wbinvd or similar. */
+
+#ifndef ACPI_FLUSH_CPU_CACHE
+#define ACPI_FLUSH_CPU_CACHE()
+#endif
+
 /* "inline" keywords - configurable since inline is not standardized */
 
 #ifndef ACPI_INLINE
 #endif
 
 /*
+ * Configurable calling conventions:
+ *
+ * ACPI_SYSTEM_XFACE        - Interfaces to host OS (handlers, threads)
+ * ACPI_EXTERNAL_XFACE      - External ACPI interfaces
+ * ACPI_INTERNAL_XFACE      - Internal ACPI interfaces
+ * ACPI_INTERNAL_VAR_XFACE  - Internal variable-parameter list interfaces
+ */
+#ifndef ACPI_SYSTEM_XFACE
+#define ACPI_SYSTEM_XFACE
+#endif
+
+#ifndef ACPI_EXTERNAL_XFACE
+#define ACPI_EXTERNAL_XFACE
+#endif
+
+#ifndef ACPI_INTERNAL_XFACE
+#define ACPI_INTERNAL_XFACE
+#endif
+
+#ifndef ACPI_INTERNAL_VAR_XFACE
+#define ACPI_INTERNAL_VAR_XFACE
+#endif
+
+/*
  * Debugger threading model
  * Use single threaded if the entire subsystem is contained in an application
  * Use multiple threaded when the subsystem is running in the kernel.
  *
  *****************************************************************************/
 
-#define ACPI_IS_ASCII(c)  ((c) < 0x80)
-
-#ifdef ACPI_USE_SYSTEM_CLIBRARY
 /*
- * Use the standard C library headers.
- * We want to keep these to a minimum.
+ * ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
+ *      Otherwise, local versions of string/memory functions will be used.
+ * ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
+ *      the standard header files may be used.
+ *
+ * The ACPICA subsystem only uses low level C library functions that do not call
+ * operating system services and may therefore be inlined in the code.
+ *
+ * It may be necessary to tailor these include files to the target
+ * generation environment.
  */
+#ifdef ACPI_USE_SYSTEM_CLIBRARY
+
+/* Use the standard C library headers. We want to keep these to a minimum. */
+
 #ifdef ACPI_USE_STANDARD_HEADERS
-/*
- * Use the standard headers from the standard locations
- */
+
+/* Use the standard headers from the standard locations */
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 
 #endif                         /* ACPI_USE_STANDARD_HEADERS */
 
-/*
- * We will be linking to the standard Clib functions
- */
+/* We will be linking to the standard Clib functions */
+
 #define ACPI_STRSTR(s1,s2)      strstr((s1), (s2))
 #define ACPI_STRCHR(s1,c)       strchr((s1), (c))
 #define ACPI_STRLEN(s)          (acpi_size) strlen((s))
  *
  *****************************************************************************/
 
- /*
-  * Use local definitions of C library macros and functions
-  * NOTE: The function implementations may not be as efficient
-  * as an inline or assembly code implementation provided by a
-  * native C library.
-  */
-
+/*
+ * Use local definitions of C library macros and functions. These function
+ * implementations may not be as efficient as an inline or assembly code
+ * implementation provided by a native C library, but they are functionally
+ * equivalent.
+ */
 #ifndef va_arg
 
 #ifndef _VALIST
 typedef char *va_list;
 #endif                         /* _VALIST */
 
-/*
- * Storage alignment properties
- */
+/* Storage alignment properties */
+
 #define  _AUPBND                (sizeof (acpi_native_int) - 1)
 #define  _ADNBND                (sizeof (acpi_native_int) - 1)
 
-/*
- * Variable argument list macro definitions
- */
+/* Variable argument list macro definitions */
+
 #define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))
 #define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
-#define va_end(ap)              (void) 0
+#define va_end(ap)              (ap = (va_list) NULL)
 #define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
 
 #endif                         /* va_arg */
 
+/* Use the local (ACPICA) definitions of the clib functions */
+
 #define ACPI_STRSTR(s1,s2)      acpi_ut_strstr ((s1), (s2))
 #define ACPI_STRCHR(s1,c)       acpi_ut_strchr ((s1), (c))
 #define ACPI_STRLEN(s)          (acpi_size) acpi_ut_strlen ((s))
@@ -322,59 +390,4 @@ typedef char *va_list;
 
 #endif                         /* ACPI_USE_SYSTEM_CLIBRARY */
 
-/******************************************************************************
- *
- * Assembly code macros
- *
- *****************************************************************************/
-
-/*
- * Handle platform- and compiler-specific assembly language differences.
- * These should already have been defined by the platform includes above.
- *
- * Notes:
- * 1) Interrupt 3 is used to break into a debugger
- * 2) Interrupts are turned off during ACPI register setup
- */
-
-/* Unrecognized compiler, use defaults */
-
-#ifndef ACPI_ASM_MACROS
-
-/*
- * Calling conventions:
- *
- * ACPI_SYSTEM_XFACE        - Interfaces to host OS (handlers, threads)
- * ACPI_EXTERNAL_XFACE      - External ACPI interfaces
- * ACPI_INTERNAL_XFACE      - Internal ACPI interfaces
- * ACPI_INTERNAL_VAR_XFACE  - Internal variable-parameter list interfaces
- */
-#define ACPI_SYSTEM_XFACE
-#define ACPI_EXTERNAL_XFACE
-#define ACPI_INTERNAL_XFACE
-#define ACPI_INTERNAL_VAR_XFACE
-
-#define ACPI_ASM_MACROS
-#define BREAKPOINT3
-#define ACPI_DISABLE_IRQS()
-#define ACPI_ENABLE_IRQS()
-#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq)
-#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq)
-
-#endif                         /* ACPI_ASM_MACROS */
-
-#ifdef ACPI_APPLICATION
-
-/* Don't want software interrupts within a ring3 application */
-
-#undef BREAKPOINT3
-#define BREAKPOINT3
-#endif
-
-/******************************************************************************
- *
- * Compiler-specific information is contained in the compiler-specific
- * headers.
- *
- *****************************************************************************/
 #endif                         /* __ACENV_H__ */
index 72553b0..e077ce6 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -64,8 +64,4 @@
  */
 #define ACPI_UNUSED_VAR __attribute__ ((unused))
 
-#ifdef _ANSI
-#define inline
-#endif
-
 #endif                         /* __ACGCC_H__ */
index 85d5d8f..68534ef 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2012, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <acpi/platform/acgcc.h>
 
-
 #ifdef __KERNEL__
 #include <acpi/actypes.h>
 /*
index 3994d77..bcbdd74 100644 (file)
@@ -74,9 +74,10 @@ enum acpi_address_range_id {
 
 /* Table Handlers */
 
-typedef int (*acpi_table_handler) (struct acpi_table_header *table);
+typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);
 
-typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
+typedef int (*acpi_tbl_entry_handler)(struct acpi_subtable_header *header,
+                                     const unsigned long end);
 
 #ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
 void acpi_initrd_override(void *data, size_t size);
@@ -95,10 +96,14 @@ int acpi_mps_check (void);
 int acpi_numa_init (void);
 
 int acpi_table_init (void);
-int acpi_table_parse (char *id, acpi_table_handler handler);
+int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
-       int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
-int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
+                                   int entry_id,
+                                   acpi_tbl_entry_handler handler,
+                                   unsigned int max_entries);
+int acpi_table_parse_madt(enum acpi_madt_type id,
+                         acpi_tbl_entry_handler handler,
+                         unsigned int max_entries);
 int acpi_parse_mcfg (struct acpi_table_header *header);
 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
 
@@ -358,8 +363,7 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
 #if defined(CONFIG_ACPI_HOTPLUG_CPU) &&                        \
        (defined(CONFIG_ACPI_HOTPLUG_MEMORY) ||         \
         defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) && \
-       (defined(CONFIG_ACPI_CONTAINER) ||              \
-        defined(CONFIG_ACPI_CONTAINER_MODULE))
+       defined(CONFIG_ACPI_CONTAINER)
 #define ACPI_HOTPLUG_OST
 #endif
 
@@ -511,7 +515,7 @@ static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
 static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
 #endif
 
-#ifdef CONFIG_ACPI_SLEEP
+#if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
 int acpi_dev_suspend_late(struct device *dev);
 int acpi_dev_resume_early(struct device *dev);
 int acpi_subsys_prepare(struct device *dev);
@@ -526,9 +530,14 @@ static inline int acpi_subsys_resume_early(struct device *dev) { return 0; }
 #endif
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
+struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
 int acpi_dev_pm_attach(struct device *dev, bool power_on);
 void acpi_dev_pm_detach(struct device *dev, bool power_off);
 #else
+static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
+{
+       return NULL;
+}
 static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
 {
        return -ENODEV;
index a55b88e..a22944c 100644 (file)
@@ -89,11 +89,15 @@ struct cpufreq_real_policy {
 };
 
 struct cpufreq_policy {
-       cpumask_var_t           cpus;   /* CPUs requiring sw coordination */
-       cpumask_var_t           related_cpus; /* CPUs with any coordination */
-       unsigned int            shared_type; /* ANY or ALL affected CPUs
+       /* CPUs sharing clock, require sw coordination */
+       cpumask_var_t           cpus;   /* Online CPUs only */
+       cpumask_var_t           related_cpus; /* Online + Offline CPUs */
+
+       unsigned int            shared_type; /* ACPI: ANY or ALL affected CPUs
                                                should set cpufreq */
-       unsigned int            cpu;    /* cpu nr of registered CPU */
+       unsigned int            cpu;    /* cpu nr of CPU managing this policy */
+       unsigned int            last_cpu; /* cpu nr of previous CPU that managed
+                                          * this policy */
        struct cpufreq_cpuinfo  cpuinfo;/* see above */
 
        unsigned int            min;    /* in kHz */
@@ -112,16 +116,23 @@ struct cpufreq_policy {
        struct completion       kobj_unregister;
 };
 
-#define CPUFREQ_ADJUST         (0)
-#define CPUFREQ_INCOMPATIBLE   (1)
-#define CPUFREQ_NOTIFY         (2)
-#define CPUFREQ_START          (3)
+#define CPUFREQ_ADJUST                 (0)
+#define CPUFREQ_INCOMPATIBLE           (1)
+#define CPUFREQ_NOTIFY                 (2)
+#define CPUFREQ_START                  (3)
+#define CPUFREQ_UPDATE_POLICY_CPU      (4)
 
+/* Only for ACPI */
 #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
 #define CPUFREQ_SHARED_TYPE_HW  (1) /* HW does needed coordination */
 #define CPUFREQ_SHARED_TYPE_ALL         (2) /* All dependent CPUs should set freq */
 #define CPUFREQ_SHARED_TYPE_ANY         (3) /* Freq can be set from any dependent CPU*/
 
+static inline bool policy_is_shared(struct cpufreq_policy *policy)
+{
+       return cpumask_weight(policy->cpus) > 1;
+}
+
 /******************** cpufreq transition notifiers *******************/
 
 #define CPUFREQ_PRECHANGE      (0)
@@ -173,6 +184,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu
 
 struct cpufreq_governor {
        char    name[CPUFREQ_NAME_LEN];
+       int     initialized;
        int     (*governor)     (struct cpufreq_policy *policy,
                                 unsigned int event);
        ssize_t (*show_setspeed)        (struct cpufreq_policy *policy,
@@ -308,6 +320,9 @@ __ATTR(_name, 0444, show_##_name, NULL)
 static struct global_attr _name =              \
 __ATTR(_name, 0644, show_##_name, store_##_name)
 
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
+void cpufreq_cpu_put(struct cpufreq_policy *data);
+const char *cpufreq_get_current_driver(void);
 
 /*********************************************************************
  *                        CPUFREQ 2.6. INTERFACE                     *
@@ -397,14 +412,13 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
 
 /* the following 3 funtions are for cpufreq core use only */
 struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
-struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
-void   cpufreq_cpu_put(struct cpufreq_policy *data);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
 
 void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
                                      unsigned int cpu);
+void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy);
 
 void cpufreq_frequency_table_put_attr(unsigned int cpu);
 #endif /* _LINUX_CPUFREQ_H */
index e4238ce..e70df40 100644 (file)
@@ -13,6 +13,11 @@ extern bool pm_freezing;             /* PM freezing in effect */
 extern bool pm_nosig_freezing;         /* PM nosig freezing in effect */
 
 /*
+ * Timeout for stopping processes
+ */
+extern unsigned int freeze_timeout_msecs;
+
+/*
  * Check if a process has been frozen
  */
 static inline bool frozen(struct task_struct *p)
index a5199f6..d0ab98f 100644 (file)
@@ -125,6 +125,31 @@ static inline void init_llist_head(struct llist_head *list)
             (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))
 
 /**
+ * llist_for_each_entry_safe - iterate safely against remove over some entries
+ * of lock-less list of given type.
+ * @pos:       the type * to use as a loop cursor.
+ * @n:         another type * to use as a temporary storage.
+ * @node:      the fist entry of deleted list entries.
+ * @member:    the name of the llist_node with the struct.
+ *
+ * In general, some entries of the lock-less list can be traversed
+ * safely only after being removed from list, so start with an entry
+ * instead of list head. This variant allows removal of entries
+ * as we iterate.
+ *
+ * If being used on entries deleted from lock-less list directly, the
+ * traverse order is from the newest to the oldest added entry.  If
+ * you want to traverse from the oldest to the newest, you must
+ * reverse the order by yourself before traversing.
+ */
+#define llist_for_each_entry_safe(pos, n, node, member)                \
+       for ((pos) = llist_entry((node), typeof(*(pos)), member),       \
+            (n) = (pos)->member.next;                                  \
+            &(pos)->member != NULL;                                    \
+            (pos) = llist_entry(n, typeof(*(pos)), member),            \
+            (n) = (&(pos)->member != NULL) ? (pos)->member.next : NULL)
+
+/**
  * llist_empty - tests whether a lock-less list is empty
  * @head:      the list to test
  *
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
new file mode 100644 (file)
index 0000000..5161f63
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 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/>.
+ */
+
+int pl320_ipc_transmit(u32 *data);
+int pl320_ipc_register_notifier(struct notifier_block *nb);
+int pl320_ipc_unregister_notifier(struct notifier_block *nb);
index 0108a56..28bd5fa 100644 (file)
@@ -429,7 +429,7 @@ extern int memcg_limited_groups_array_size;
  * the slab_mutex must be held when looping through those caches
  */
 #define for_each_memcg_cache_index(_idx)       \
-       for ((_idx) = 0; i < memcg_limited_groups_array_size; (_idx)++)
+       for ((_idx) = 0; (_idx) < memcg_limited_groups_array_size; (_idx)++)
 
 static inline bool memcg_kmem_enabled(void)
 {
index bc823c4..deca874 100644 (file)
@@ -151,7 +151,7 @@ struct mmu_notifier_ops {
  * Therefore notifier chains can only be traversed when either
  *
  * 1. mmap_sem is held.
- * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->mutex).
+ * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->rwsem).
  * 3. No other concurrent thread can access the list (release)
  */
 struct mmu_notifier {
index f271860..c785c21 100644 (file)
@@ -80,6 +80,12 @@ static inline bool pm_runtime_suspended(struct device *dev)
                && !dev->power.disable_depth;
 }
 
+static inline bool pm_runtime_active(struct device *dev)
+{
+       return dev->power.runtime_status == RPM_ACTIVE
+               || dev->power.disable_depth;
+}
+
 static inline bool pm_runtime_status_suspended(struct device *dev)
 {
        return dev->power.runtime_status == RPM_SUSPENDED;
@@ -132,6 +138,7 @@ static inline void pm_runtime_put_noidle(struct device *dev) {}
 static inline bool device_run_wake(struct device *dev) { return false; }
 static inline void device_set_run_wake(struct device *dev, bool enable) {}
 static inline bool pm_runtime_suspended(struct device *dev) { return false; }
+static inline bool pm_runtime_active(struct device *dev) { return true; }
 static inline bool pm_runtime_status_suspended(struct device *dev) { return false; }
 static inline bool pm_runtime_enabled(struct device *dev) { return false; }
 
index 0c808d7..d4e3f16 100644 (file)
@@ -34,8 +34,10 @@ static inline void pm_restore_console(void)
 typedef int __bitwise suspend_state_t;
 
 #define PM_SUSPEND_ON          ((__force suspend_state_t) 0)
-#define PM_SUSPEND_STANDBY     ((__force suspend_state_t) 1)
+#define PM_SUSPEND_FREEZE      ((__force suspend_state_t) 1)
+#define PM_SUSPEND_STANDBY     ((__force suspend_state_t) 2)
 #define PM_SUSPEND_MEM         ((__force suspend_state_t) 3)
+#define PM_SUSPEND_MIN         PM_SUSPEND_FREEZE
 #define PM_SUSPEND_MAX         ((__force suspend_state_t) 4)
 
 enum suspend_stat_step {
@@ -192,6 +194,7 @@ struct platform_suspend_ops {
  */
 extern void suspend_set_ops(const struct platform_suspend_ops *ops);
 extern int suspend_valid_only_mem(suspend_state_t state);
+extern void freeze_wake(void);
 
 /**
  * arch_suspend_disable_irqs - disable IRQs for suspend
@@ -217,6 +220,7 @@ extern int pm_suspend(suspend_state_t state);
 
 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 void freeze_wake(void) {}
 #endif /* !CONFIG_SUSPEND */
 
 /* struct pbe is used for creating lists of pages that should be restored
index 381f06d..e2cee22 100644 (file)
@@ -181,6 +181,10 @@ int sysfs_merge_group(struct kobject *kobj,
                       const struct attribute_group *grp);
 void sysfs_unmerge_group(struct kobject *kobj,
                       const struct attribute_group *grp);
+int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
+                           struct kobject *target, const char *link_name);
+void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
+                                 const char *link_name);
 
 void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
 void sysfs_notify_dirent(struct sysfs_dirent *sd);
@@ -326,6 +330,18 @@ static inline void sysfs_unmerge_group(struct kobject *kobj,
 {
 }
 
+static inline int sysfs_add_link_to_group(struct kobject *kobj,
+               const char *group_name, struct kobject *target,
+               const char *link_name)
+{
+       return 0;
+}
+
+static inline void sysfs_remove_link_from_group(struct kobject *kobj,
+               const char *group_name, const char *link_name)
+{
+}
+
 static inline void sysfs_notify(struct kobject *kobj, const char *dir,
                                const char *attr)
 {
index 689b14b..4d22d0f 100644 (file)
@@ -357,6 +357,8 @@ struct usb_bus {
        int bandwidth_int_reqs;         /* number of Interrupt requests */
        int bandwidth_isoc_reqs;        /* number of Isoc. requests */
 
+       unsigned resuming_ports;        /* bit array: resuming root-hub ports */
+
 #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
        struct mon_bus *mon_bus;        /* non-null when associated */
        int monitored;                  /* non-zero when monitored */
index 608050b..0a78df5 100644 (file)
@@ -430,6 +430,9 @@ extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
 extern void usb_wakeup_notification(struct usb_device *hdev,
                unsigned int portnum);
 
+extern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum);
+extern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum);
+
 /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
 #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
 #define        usb_dotoggle(dev, ep, out)  ((dev)->toggle[out] ^= (1 << (ep)))
index 5de7a22..0e5ac93 100644 (file)
@@ -33,6 +33,7 @@ struct usbnet {
        wait_queue_head_t       *wait;
        struct mutex            phy_mutex;
        unsigned char           suspend_count;
+       unsigned char           pkt_cnt, pkt_err;
 
        /* i/o info: pipes etc */
        unsigned                in, out;
@@ -70,6 +71,7 @@ struct usbnet {
 #              define EVENT_DEV_OPEN   7
 #              define EVENT_DEVICE_REPORT_IDLE 8
 #              define EVENT_NO_RUNTIME_PM      9
+#              define EVENT_RX_KILL    10
 };
 
 static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -100,7 +102,6 @@ struct driver_info {
 #define FLAG_LINK_INTR 0x0800          /* updates link (carrier) status */
 
 #define FLAG_POINTTOPOINT 0x1000       /* possibly use "usb%d" names */
-#define FLAG_NOARP     0x2000          /* device can't do ARP */
 
 /*
  * Indicates to usbnet, that USB driver accumulates multiple IP packets.
@@ -108,6 +109,7 @@ struct driver_info {
  */
 #define FLAG_MULTI_PACKET      0x2000
 #define FLAG_RX_ASSEMBLE       0x4000  /* rx packets may span >1 frames */
+#define FLAG_NOARP             0x8000  /* device can't do ARP */
 
        /* init device ... can sleep, or cause probe() failure */
        int     (*bind)(struct usbnet *, struct usb_interface *);
index 498433d..938b7fd 100644 (file)
@@ -34,17 +34,17 @@ extern int                          udpv6_connect(struct sock *sk,
                                                      struct sockaddr *uaddr,
                                                      int addr_len);
 
-extern int                     datagram_recv_ctl(struct sock *sk,
-                                                 struct msghdr *msg,
-                                                 struct sk_buff *skb);
-
-extern int                     datagram_send_ctl(struct net *net,
-                                                 struct sock *sk,
-                                                 struct msghdr *msg,
-                                                 struct flowi6 *fl6,
-                                                 struct ipv6_txoptions *opt,
-                                                 int *hlimit, int *tclass,
-                                                 int *dontfrag);
+extern int                     ip6_datagram_recv_ctl(struct sock *sk,
+                                                     struct msghdr *msg,
+                                                     struct sk_buff *skb);
+
+extern int                     ip6_datagram_send_ctl(struct net *net,
+                                                     struct sock *sk,
+                                                     struct msghdr *msg,
+                                                     struct flowi6 *fl6,
+                                                     struct ipv6_txoptions *opt,
+                                                     int *hlimit, int *tclass,
+                                                     int *dontfrag);
 
 #define                LOOPBACK4_IPV6          cpu_to_be32(0x7f000006)
 
index 0c97838..427acab 100644 (file)
@@ -99,98 +99,6 @@ DEFINE_EVENT(wakeup_source, wakeup_source_deactivate,
        TP_ARGS(name, state)
 );
 
-#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED
-
-/*
- * The power events are used for cpuidle & suspend (power_start, power_end)
- *  and for cpufreq (power_frequency)
- */
-DECLARE_EVENT_CLASS(power,
-
-       TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id),
-
-       TP_ARGS(type, state, cpu_id),
-
-       TP_STRUCT__entry(
-               __field(        u64,            type            )
-               __field(        u64,            state           )
-               __field(        u64,            cpu_id          )
-       ),
-
-       TP_fast_assign(
-               __entry->type = type;
-               __entry->state = state;
-               __entry->cpu_id = cpu_id;
-       ),
-
-       TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type,
-               (unsigned long)__entry->state, (unsigned long)__entry->cpu_id)
-);
-
-DEFINE_EVENT(power, power_start,
-
-       TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id),
-
-       TP_ARGS(type, state, cpu_id)
-);
-
-DEFINE_EVENT(power, power_frequency,
-
-       TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id),
-
-       TP_ARGS(type, state, cpu_id)
-);
-
-TRACE_EVENT(power_end,
-
-       TP_PROTO(unsigned int cpu_id),
-
-       TP_ARGS(cpu_id),
-
-       TP_STRUCT__entry(
-               __field(        u64,            cpu_id          )
-       ),
-
-       TP_fast_assign(
-               __entry->cpu_id = cpu_id;
-       ),
-
-       TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id)
-
-);
-
-/* Deprecated dummy functions must be protected against multi-declartion */
-#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
-#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
-
-enum {
-       POWER_NONE = 0,
-       POWER_CSTATE = 1,
-       POWER_PSTATE = 2,
-};
-#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */
-
-#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */
-
-#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
-#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
-enum {
-       POWER_NONE = 0,
-       POWER_CSTATE = 1,
-       POWER_PSTATE = 2,
-};
-
-/* These dummy declaration have to be ripped out when the deprecated
-   events get removed */
-static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {};
-static inline void trace_power_end(u64 cpuid) {};
-static inline void trace_power_start_rcuidle(u64 type, u64 state, u64 cpuid) {};
-static inline void trace_power_end_rcuidle(u64 cpuid) {};
-static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {};
-#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */
-
-#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */
-
 /*
  * The clock events are used for clock enable/disable and for
  *  clock rate change
index 5059847..f738e25 100644 (file)
 #define USB_INTRF_FUNC_SUSPEND_LP      (1 << (8 + 0))
 #define USB_INTRF_FUNC_SUSPEND_RW      (1 << (8 + 1))
 
+/*
+ * Interface status, Figure 9-5 USB 3.0 spec
+ */
+#define USB_INTRF_STAT_FUNC_RW_CAP     1
+#define USB_INTRF_STAT_FUNC_RW         2
+
 #define USB_ENDPOINT_HALT              0       /* IN/OUT will STALL */
 
 /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
index 301079d..7b6646a 100644 (file)
@@ -908,6 +908,15 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
 }
 
 /*
+ * Initialize event state based on the perf_event_attr::disabled.
+ */
+static inline void perf_event__state_init(struct perf_event *event)
+{
+       event->state = event->attr.disabled ? PERF_EVENT_STATE_OFF :
+                                             PERF_EVENT_STATE_INACTIVE;
+}
+
+/*
  * Called at perf_event creation and when events are attached/detached from a
  * group.
  */
@@ -6179,8 +6188,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
        event->overflow_handler = overflow_handler;
        event->overflow_handler_context = context;
 
-       if (attr->disabled)
-               event->state = PERF_EVENT_STATE_OFF;
+       perf_event__state_init(event);
 
        pmu = NULL;
 
@@ -6609,9 +6617,17 @@ SYSCALL_DEFINE5(perf_event_open,
 
                mutex_lock(&gctx->mutex);
                perf_remove_from_context(group_leader);
+
+               /*
+                * Removing from the context ends up with disabled
+                * event. What we want here is event in the initial
+                * startup state, ready to be add into new context.
+                */
+               perf_event__state_init(group_leader);
                list_for_each_entry(sibling, &group_leader->sibling_list,
                                    group_entry) {
                        perf_remove_from_context(sibling);
+                       perf_event__state_init(sibling);
                        put_ctx(gctx);
                }
                mutex_unlock(&gctx->mutex);
index ca30404..c6422ff 100644 (file)
@@ -66,7 +66,7 @@ static DECLARE_WORK(suspend_work, try_to_suspend);
 
 void queue_up_suspend_work(void)
 {
-       if (!work_pending(&suspend_work) && autosleep_state > PM_SUSPEND_ON)
+       if (autosleep_state > PM_SUSPEND_ON)
                queue_work(autosleep_wq, &suspend_work);
 }
 
index 1c16f91..d77663b 100644 (file)
@@ -313,7 +313,7 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
 static suspend_state_t decode_state(const char *buf, size_t n)
 {
 #ifdef CONFIG_SUSPEND
-       suspend_state_t state = PM_SUSPEND_STANDBY;
+       suspend_state_t state = PM_SUSPEND_MIN;
        const char * const *s;
 #endif
        char *p;
@@ -553,6 +553,30 @@ power_attr(pm_trace_dev_match);
 
 #endif /* CONFIG_PM_TRACE */
 
+#ifdef CONFIG_FREEZER
+static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
+                                     struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%u\n", freeze_timeout_msecs);
+}
+
+static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      const char *buf, size_t n)
+{
+       unsigned long val;
+
+       if (kstrtoul(buf, 10, &val))
+               return -EINVAL;
+
+       freeze_timeout_msecs = val;
+       return n;
+}
+
+power_attr(pm_freeze_timeout);
+
+#endif /* CONFIG_FREEZER*/
+
 static struct attribute * g[] = {
        &state_attr.attr,
 #ifdef CONFIG_PM_TRACE
@@ -576,6 +600,9 @@ static struct attribute * g[] = {
        &pm_print_times_attr.attr,
 #endif
 #endif
+#ifdef CONFIG_FREEZER
+       &pm_freeze_timeout_attr.attr,
+#endif
        NULL,
 };
 
index d5a258b..98088e0 100644 (file)
@@ -21,7 +21,7 @@
 /* 
  * Timeout for stopping processes
  */
-#define TIMEOUT        (20 * HZ)
+unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC;
 
 static int try_to_freeze_tasks(bool user_only)
 {
@@ -36,7 +36,7 @@ static int try_to_freeze_tasks(bool user_only)
 
        do_gettimeofday(&start);
 
-       end_time = jiffies + TIMEOUT;
+       end_time = jiffies + msecs_to_jiffies(freeze_timeout_msecs);
 
        if (!user_only)
                freeze_workqueues_begin();
index 9322ff7..587ddde 100644 (file)
@@ -359,8 +359,7 @@ void pm_qos_update_request(struct pm_qos_request *req,
                return;
        }
 
-       if (delayed_work_pending(&req->work))
-               cancel_delayed_work_sync(&req->work);
+       cancel_delayed_work_sync(&req->work);
 
        if (new_value != req->node.prio)
                pm_qos_update_target(
@@ -386,8 +385,7 @@ void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value,
                 "%s called for unknown object.", __func__))
                return;
 
-       if (delayed_work_pending(&req->work))
-               cancel_delayed_work_sync(&req->work);
+       cancel_delayed_work_sync(&req->work);
 
        if (new_value != req->node.prio)
                pm_qos_update_target(
@@ -416,8 +414,7 @@ void pm_qos_remove_request(struct pm_qos_request *req)
                return;
        }
 
-       if (delayed_work_pending(&req->work))
-               cancel_delayed_work_sync(&req->work);
+       cancel_delayed_work_sync(&req->work);
 
        pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints,
                             &req->node, PM_QOS_REMOVE_REQ,
index c8b7446..d4feda0 100644 (file)
 #include "power.h"
 
 const char *const pm_states[PM_SUSPEND_MAX] = {
+       [PM_SUSPEND_FREEZE]     = "freeze",
        [PM_SUSPEND_STANDBY]    = "standby",
        [PM_SUSPEND_MEM]        = "mem",
 };
 
 static const struct platform_suspend_ops *suspend_ops;
 
+static bool need_suspend_ops(suspend_state_t state)
+{
+       return !!(state > PM_SUSPEND_FREEZE);
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
+static bool suspend_freeze_wake;
+
+static void freeze_begin(void)
+{
+       suspend_freeze_wake = false;
+}
+
+static void freeze_enter(void)
+{
+       wait_event(suspend_freeze_wait_head, suspend_freeze_wake);
+}
+
+void freeze_wake(void)
+{
+       suspend_freeze_wake = true;
+       wake_up(&suspend_freeze_wait_head);
+}
+EXPORT_SYMBOL_GPL(freeze_wake);
+
 /**
  * suspend_set_ops - Set the global suspend method table.
  * @ops: Suspend operations to use.
@@ -50,8 +76,11 @@ EXPORT_SYMBOL_GPL(suspend_set_ops);
 
 bool valid_state(suspend_state_t state)
 {
+       if (state == PM_SUSPEND_FREEZE)
+               return true;
        /*
-        * All states need lowlevel support and need to be valid to the lowlevel
+        * PM_SUSPEND_STANDBY and PM_SUSPEND_MEMORY states need lowlevel
+        * support and need to be valid to the lowlevel
         * implementation, no valid callback implies that none are valid.
         */
        return suspend_ops && suspend_ops->valid && suspend_ops->valid(state);
@@ -89,11 +118,11 @@ static int suspend_test(int level)
  * hibernation).  Run suspend notifiers, allocate the "suspend" console and
  * freeze processes.
  */
-static int suspend_prepare(void)
+static int suspend_prepare(suspend_state_t state)
 {
        int error;
 
-       if (!suspend_ops || !suspend_ops->enter)
+       if (need_suspend_ops(state) && (!suspend_ops || !suspend_ops->enter))
                return -EPERM;
 
        pm_prepare_console();
@@ -137,7 +166,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
 {
        int error;
 
-       if (suspend_ops->prepare) {
+       if (need_suspend_ops(state) && suspend_ops->prepare) {
                error = suspend_ops->prepare();
                if (error)
                        goto Platform_finish;
@@ -149,12 +178,23 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
                goto Platform_finish;
        }
 
-       if (suspend_ops->prepare_late) {
+       if (need_suspend_ops(state) && suspend_ops->prepare_late) {
                error = suspend_ops->prepare_late();
                if (error)
                        goto Platform_wake;
        }
 
+       /*
+        * PM_SUSPEND_FREEZE equals
+        * frozen processes + suspended devices + idle processors.
+        * Thus we should invoke freeze_enter() soon after
+        * all the devices are suspended.
+        */
+       if (state == PM_SUSPEND_FREEZE) {
+               freeze_enter();
+               goto Platform_wake;
+       }
+
        if (suspend_test(TEST_PLATFORM))
                goto Platform_wake;
 
@@ -182,13 +222,13 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
        enable_nonboot_cpus();
 
  Platform_wake:
-       if (suspend_ops->wake)
+       if (need_suspend_ops(state) && suspend_ops->wake)
                suspend_ops->wake();
 
        dpm_resume_start(PMSG_RESUME);
 
  Platform_finish:
-       if (suspend_ops->finish)
+       if (need_suspend_ops(state) && suspend_ops->finish)
                suspend_ops->finish();
 
        return error;
@@ -203,11 +243,11 @@ int suspend_devices_and_enter(suspend_state_t state)
        int error;
        bool wakeup = false;
 
-       if (!suspend_ops)
+       if (need_suspend_ops(state) && !suspend_ops)
                return -ENOSYS;
 
        trace_machine_suspend(state);
-       if (suspend_ops->begin) {
+       if (need_suspend_ops(state) && suspend_ops->begin) {
                error = suspend_ops->begin(state);
                if (error)
                        goto Close;
@@ -226,7 +266,7 @@ int suspend_devices_and_enter(suspend_state_t state)
 
        do {
                error = suspend_enter(state, &wakeup);
-       } while (!error && !wakeup
+       } while (!error && !wakeup && need_suspend_ops(state)
                && suspend_ops->suspend_again && suspend_ops->suspend_again());
 
  Resume_devices:
@@ -236,13 +276,13 @@ int suspend_devices_and_enter(suspend_state_t state)
        ftrace_start();
        resume_console();
  Close:
-       if (suspend_ops->end)
+       if (need_suspend_ops(state) && suspend_ops->end)
                suspend_ops->end();
        trace_machine_suspend(PWR_EVENT_EXIT);
        return error;
 
  Recover_platform:
-       if (suspend_ops->recover)
+       if (need_suspend_ops(state) && suspend_ops->recover)
                suspend_ops->recover();
        goto Resume_devices;
 }
@@ -278,12 +318,15 @@ static int enter_state(suspend_state_t state)
        if (!mutex_trylock(&pm_mutex))
                return -EBUSY;
 
+       if (state == PM_SUSPEND_FREEZE)
+               freeze_begin();
+
        printk(KERN_INFO "PM: Syncing filesystems ... ");
        sys_sync();
        printk("done.\n");
 
        pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
-       error = suspend_prepare();
+       error = suspend_prepare(state);
        if (error)
                goto Unlock;
 
index f6e5ec2..c1cc7e1 100644 (file)
@@ -40,8 +40,7 @@
 #ifdef CONFIG_RCU_NOCB_CPU
 static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */
 static bool have_rcu_nocb_mask;            /* Was rcu_nocb_mask allocated? */
-static bool rcu_nocb_poll;         /* Offload kthread are to poll. */
-module_param(rcu_nocb_poll, bool, 0444);
+static bool __read_mostly rcu_nocb_poll;    /* Offload kthread are to poll. */
 static char __initdata nocb_buf[NR_CPUS * 5];
 #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
 
@@ -2159,6 +2158,13 @@ static int __init rcu_nocb_setup(char *str)
 }
 __setup("rcu_nocbs=", rcu_nocb_setup);
 
+static int __init parse_rcu_nocb_poll(char *arg)
+{
+       rcu_nocb_poll = 1;
+       return 0;
+}
+early_param("rcu_nocb_poll", parse_rcu_nocb_poll);
+
 /* Is the specified CPU a no-CPUs CPU? */
 static bool is_nocb_cpu(int cpu)
 {
@@ -2366,10 +2372,11 @@ static int rcu_nocb_kthread(void *arg)
        for (;;) {
                /* If not polling, wait for next batch of callbacks. */
                if (!rcu_nocb_poll)
-                       wait_event(rdp->nocb_wq, rdp->nocb_head);
+                       wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head);
                list = ACCESS_ONCE(rdp->nocb_head);
                if (!list) {
                        schedule_timeout_interruptible(1);
+                       flush_signals(current);
                        continue;
                }
 
index 2cd3c1b..7ae4c4c 100644 (file)
@@ -222,8 +222,8 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
                        cfs_rq->runnable_load_avg);
        SEQ_printf(m, "  .%-30s: %lld\n", "blocked_load_avg",
                        cfs_rq->blocked_load_avg);
-       SEQ_printf(m, "  .%-30s: %ld\n", "tg_load_avg",
-                       atomic64_read(&cfs_rq->tg->load_avg));
+       SEQ_printf(m, "  .%-30s: %lld\n", "tg_load_avg",
+                       (unsigned long long)atomic64_read(&cfs_rq->tg->load_avg));
        SEQ_printf(m, "  .%-30s: %lld\n", "tg_load_contrib",
                        cfs_rq->tg_load_contrib);
        SEQ_printf(m, "  .%-30s: %d\n", "tg_runnable_contrib",
index 5eea870..81fa536 100644 (file)
@@ -2663,7 +2663,7 @@ static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
        hrtimer_cancel(&cfs_b->slack_timer);
 }
 
-static void unthrottle_offline_cfs_rqs(struct rq *rq)
+static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq)
 {
        struct cfs_rq *cfs_rq;
 
index 418feb0..4f02b28 100644 (file)
@@ -566,7 +566,7 @@ static inline struct rt_bandwidth *sched_rt_bandwidth(struct rt_rq *rt_rq)
 static int do_balance_runtime(struct rt_rq *rt_rq)
 {
        struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
-       struct root_domain *rd = cpu_rq(smp_processor_id())->rd;
+       struct root_domain *rd = rq_of_rt_rq(rt_rq)->rd;
        int i, weight, more = 0;
        u64 rt_period;
 
index 5d89335..ad0a067 100644 (file)
@@ -78,21 +78,6 @@ config EVENT_TRACING
        select CONTEXT_SWITCH_TRACER
        bool
 
-config EVENT_POWER_TRACING_DEPRECATED
-       depends on EVENT_TRACING
-       bool "Deprecated power event trace API, to be removed"
-       default y
-       help
-         Provides old power event types:
-         C-state/idle accounting events:
-         power:power_start
-         power:power_end
-         and old cpufreq accounting event:
-         power:power_frequency
-         This is for userspace compatibility
-         and will vanish after 5 kernel iterations,
-         namely 3.1.
-
 config CONTEXT_SWITCH_TRACER
        bool
 
index f55fcf6..1c71382 100644 (file)
@@ -13,8 +13,5 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/power.h>
 
-#ifdef EVENT_POWER_TRACING_DEPRECATED
-EXPORT_TRACEPOINT_SYMBOL_GPL(power_start);
-#endif
 EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle);
 
index 8c0e629..dc2be7e 100644 (file)
@@ -162,6 +162,8 @@ static int digsig_verify_rsa(struct key *key,
        memset(out1, 0, head);
        memcpy(out1 + head, p, l);
 
+       kfree(p);
+
        err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len);
        if (err)
                goto err;
index 6001ee6..b5783d8 100644 (file)
@@ -1257,6 +1257,10 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
        if (flags & FOLL_WRITE && !pmd_write(*pmd))
                goto out;
 
+       /* Avoid dumping huge zero page */
+       if ((flags & FOLL_DUMP) && is_huge_zero_pmd(*pmd))
+               return ERR_PTR(-EFAULT);
+
        page = pmd_page(*pmd);
        VM_BUG_ON(!PageHead(page));
        if (flags & FOLL_TOUCH) {
index 4f3ea0b..546db81 100644 (file)
@@ -3033,6 +3033,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
                if (!huge_pte_none(huge_ptep_get(ptep))) {
                        pte = huge_ptep_get_and_clear(mm, address, ptep);
                        pte = pte_mkhuge(pte_modify(pte, newprot));
+                       pte = arch_make_huge_pte(pte, vma, NULL, 0);
                        set_huge_pte_at(mm, address, ptep, pte);
                        pages++;
                }
index c387786..2fd8b4a 100644 (file)
@@ -160,8 +160,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
        if (is_write_migration_entry(entry))
                pte = pte_mkwrite(pte);
 #ifdef CONFIG_HUGETLB_PAGE
-       if (PageHuge(new))
+       if (PageHuge(new)) {
                pte = pte_mkhuge(pte);
+               pte = arch_make_huge_pte(pte, vma, new, 0);
+       }
 #endif
        flush_cache_page(vma, addr, pte_pfn(pte));
        set_pte_at(mm, addr, ptep, pte);
index 35730ee..d1e4124 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2943,7 +2943,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
  * vma in this mm is backed by the same anon_vma or address_space.
  *
  * We can take all the locks in random order because the VM code
- * taking i_mmap_mutex or anon_vma->mutex outside the mmap_sem never
+ * taking i_mmap_mutex or anon_vma->rwsem outside the mmap_sem never
  * takes more than one of them in a row. Secondly we're protected
  * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex.
  *
index 25bfce0..4925a02 100644 (file)
@@ -249,12 +249,12 @@ static void hci_conn_disconnect(struct hci_conn *conn)
        __u8 reason = hci_proto_disconn_ind(conn);
 
        switch (conn->type) {
-       case ACL_LINK:
-               hci_acl_disconn(conn, reason);
-               break;
        case AMP_LINK:
                hci_amp_disconn(conn, reason);
                break;
+       default:
+               hci_acl_disconn(conn, reason);
+               break;
        }
 }
 
index 68a9587..5abefb1 100644 (file)
@@ -859,6 +859,19 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
        skb_pull(skb, sizeof(code));
 
+       /*
+        * The SMP context must be initialized for all other PDUs except
+        * pairing and security requests. If we get any other PDU when
+        * not initialized simply disconnect (done if this function
+        * returns an error).
+        */
+       if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
+           !conn->smp_chan) {
+               BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
+               kfree_skb(skb);
+               return -ENOTSUPP;
+       }
+
        switch (code) {
        case SMP_CMD_PAIRING_REQ:
                reason = smp_cmd_pairing_req(conn, skb);
index b29dacf..e6e1cbe 100644 (file)
@@ -1781,10 +1781,13 @@ static ssize_t pktgen_thread_write(struct file *file,
                        return -EFAULT;
                i += len;
                mutex_lock(&pktgen_thread_lock);
-               pktgen_add_device(t, f);
+               ret = pktgen_add_device(t, f);
                mutex_unlock(&pktgen_thread_lock);
-               ret = count;
-               sprintf(pg_result, "OK: add_device=%s", f);
+               if (!ret) {
+                       ret = count;
+                       sprintf(pg_result, "OK: add_device=%s", f);
+               } else
+                       sprintf(pg_result, "ERROR: can not add device %s", f);
                goto out;
        }
 
index a9a2ae3..32443eb 100644 (file)
@@ -683,7 +683,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->network_header     = old->network_header;
        new->mac_header         = old->mac_header;
        new->inner_transport_header = old->inner_transport_header;
-       new->inner_network_header = old->inner_transport_header;
+       new->inner_network_header = old->inner_network_header;
        skb_dst_copy(new, old);
        new->rxhash             = old->rxhash;
        new->ooo_okay           = old->ooo_okay;
index 291f2ed..cdf2e70 100644 (file)
@@ -310,6 +310,12 @@ void tcp_slow_start(struct tcp_sock *tp)
 {
        int cnt; /* increase in packets */
        unsigned int delta = 0;
+       u32 snd_cwnd = tp->snd_cwnd;
+
+       if (unlikely(!snd_cwnd)) {
+               pr_err_once("snd_cwnd is nul, please report this bug.\n");
+               snd_cwnd = 1U;
+       }
 
        /* RFC3465: ABC Slow start
         * Increase only after a full MSS of bytes is acked
@@ -324,7 +330,7 @@ void tcp_slow_start(struct tcp_sock *tp)
        if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh)
                cnt = sysctl_tcp_max_ssthresh >> 1;     /* limited slow start */
        else
-               cnt = tp->snd_cwnd;                     /* exponential increase */
+               cnt = snd_cwnd;                         /* exponential increase */
 
        /* RFC3465: ABC
         * We MAY increase by 2 if discovered delayed ack
@@ -334,11 +340,11 @@ void tcp_slow_start(struct tcp_sock *tp)
        tp->bytes_acked = 0;
 
        tp->snd_cwnd_cnt += cnt;
-       while (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
-               tp->snd_cwnd_cnt -= tp->snd_cwnd;
+       while (tp->snd_cwnd_cnt >= snd_cwnd) {
+               tp->snd_cwnd_cnt -= snd_cwnd;
                delta++;
        }
-       tp->snd_cwnd = min(tp->snd_cwnd + delta, tp->snd_cwnd_clamp);
+       tp->snd_cwnd = min(snd_cwnd + delta, tp->snd_cwnd_clamp);
 }
 EXPORT_SYMBOL_GPL(tcp_slow_start);
 
index 18f97ca..ad70a96 100644 (file)
@@ -3504,6 +3504,11 @@ static bool tcp_process_frto(struct sock *sk, int flag)
                }
        } else {
                if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) {
+                       if (!tcp_packets_in_flight(tp)) {
+                               tcp_enter_frto_loss(sk, 2, flag);
+                               return true;
+                       }
+
                        /* Prevent sending of new data. */
                        tp->snd_cwnd = min(tp->snd_cwnd,
                                           tcp_packets_in_flight(tp));
@@ -5649,8 +5654,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
         * the remote receives only the retransmitted (regular) SYNs: either
         * the original SYN-data or the corresponding SYN-ACK is lost.
         */
-       syn_drop = (cookie->len <= 0 && data &&
-                   inet_csk(sk)->icsk_retransmits);
+       syn_drop = (cookie->len <= 0 && data && tp->total_retrans);
 
        tcp_fastopen_cache_set(sk, mss, cookie, syn_drop);
 
index 70b09ef..eadb693 100644 (file)
@@ -496,6 +496,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
                 * errors returned from accept().
                 */
                inet_csk_reqsk_queue_drop(sk, req, prev);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
                goto out;
 
        case TCP_SYN_SENT:
@@ -1500,8 +1501,10 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
         * clogging syn queue with openreqs with exponentially increasing
         * timeout.
         */
-       if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
+       if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) {
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
                goto drop;
+       }
 
        req = inet_reqsk_alloc(&tcp_request_sock_ops);
        if (!req)
@@ -1666,6 +1669,7 @@ drop_and_release:
 drop_and_free:
        reqsk_free(req);
 drop:
+       NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
        return 0;
 }
 EXPORT_SYMBOL(tcp_v4_conn_request);
index 420e563..1b5d8cb 100644 (file)
@@ -1660,6 +1660,7 @@ static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
        if (dev->addr_len != IEEE802154_ADDR_LEN)
                return -1;
        memcpy(eui, dev->dev_addr, 8);
+       eui[0] ^= 2;
        return 0;
 }
 
index 8edf260..7a778b9 100644 (file)
@@ -380,7 +380,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                if (skb->protocol == htons(ETH_P_IPV6)) {
                        sin->sin6_addr = ipv6_hdr(skb)->saddr;
                        if (np->rxopt.all)
-                               datagram_recv_ctl(sk, msg, skb);
+                               ip6_datagram_recv_ctl(sk, msg, skb);
                        if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
                                sin->sin6_scope_id = IP6CB(skb)->iif;
                } else {
@@ -468,7 +468,8 @@ out:
 }
 
 
-int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
+int ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
+                         struct sk_buff *skb)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct inet6_skb_parm *opt = IP6CB(skb);
@@ -597,11 +598,12 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
        }
        return 0;
 }
+EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl);
 
-int datagram_send_ctl(struct net *net, struct sock *sk,
-                     struct msghdr *msg, struct flowi6 *fl6,
-                     struct ipv6_txoptions *opt,
-                     int *hlimit, int *tclass, int *dontfrag)
+int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
+                         struct msghdr *msg, struct flowi6 *fl6,
+                         struct ipv6_txoptions *opt,
+                         int *hlimit, int *tclass, int *dontfrag)
 {
        struct in6_pktinfo *src_info;
        struct cmsghdr *cmsg;
@@ -871,4 +873,4 @@ int datagram_send_ctl(struct net *net, struct sock *sk,
 exit_f:
        return err;
 }
-EXPORT_SYMBOL_GPL(datagram_send_ctl);
+EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl);
index 29124b7..d6de4b4 100644 (file)
@@ -365,8 +365,8 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
                msg.msg_control = (void*)(fl->opt+1);
                memset(&flowi6, 0, sizeof(flowi6));
 
-               err = datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt, &junk,
-                                       &junk, &junk);
+               err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt,
+                                           &junk, &junk, &junk);
                if (err)
                        goto done;
                err = -EINVAL;
index c727e47..131dd09 100644 (file)
@@ -960,7 +960,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
        int ret;
 
        if (!ip6_tnl_xmit_ctl(t))
-               return -1;
+               goto tx_err;
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
index ee94d31..d1e2e8e 100644 (file)
@@ -476,8 +476,8 @@ sticky_done:
                msg.msg_controllen = optlen;
                msg.msg_control = (void*)(opt+1);
 
-               retv = datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk, &junk,
-                                        &junk);
+               retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk,
+                                            &junk, &junk);
                if (retv)
                        goto done;
 update:
@@ -1002,7 +1002,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                release_sock(sk);
 
                if (skb) {
-                       int err = datagram_recv_ctl(sk, &msg, skb);
+                       int err = ip6_datagram_recv_ctl(sk, &msg, skb);
                        kfree_skb(skb);
                        if (err)
                                return err;
index 6cd29b1..70fa814 100644 (file)
@@ -507,7 +507,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
        sock_recv_ts_and_drops(msg, sk, skb);
 
        if (np->rxopt.all)
-               datagram_recv_ctl(sk, msg, skb);
+               ip6_datagram_recv_ctl(sk, msg, skb);
 
        err = copied;
        if (flags & MSG_TRUNC)
@@ -822,8 +822,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(struct ipv6_txoptions);
 
-               err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-                                       &hlimit, &tclass, &dontfrag);
+               err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
+                                           &hlimit, &tclass, &dontfrag);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
index e229a3b..363d8b7 100644 (file)
@@ -928,7 +928,7 @@ restart:
        dst_hold(&rt->dst);
        read_unlock_bh(&table->tb6_lock);
 
-       if (!rt->n && !(rt->rt6i_flags & RTF_NONEXTHOP))
+       if (!rt->n && !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL)))
                nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
        else if (!(rt->dst.flags & DST_HOST))
                nrt = rt6_alloc_clone(rt, &fl6->daddr);
index 93825dd..4f43537 100644 (file)
@@ -423,6 +423,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                }
 
                inet_csk_reqsk_queue_drop(sk, req, prev);
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
                goto out;
 
        case TCP_SYN_SENT:
@@ -958,8 +959,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
                        goto drop;
        }
 
-       if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
+       if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) {
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
                goto drop;
+       }
 
        req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
        if (req == NULL)
@@ -1108,6 +1111,7 @@ drop_and_release:
 drop_and_free:
        reqsk_free(req);
 drop:
+       NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
        return 0; /* don't send reset */
 }
 
index dfaa29b..fb08329 100644 (file)
@@ -443,7 +443,7 @@ try_again:
                        ip_cmsg_recv(msg, skb);
        } else {
                if (np->rxopt.all)
-                       datagram_recv_ctl(sk, msg, skb);
+                       ip6_datagram_recv_ctl(sk, msg, skb);
        }
 
        err = copied;
@@ -1153,8 +1153,8 @@ do_udp_sendmsg:
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(*opt);
 
-               err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-                                       &hlimit, &tclass, &dontfrag);
+               err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
+                                           &hlimit, &tclass, &dontfrag);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
index 1a9f372..2ac884d 100644 (file)
@@ -168,6 +168,51 @@ l2tp_session_id_hash_2(struct l2tp_net *pn, u32 session_id)
 
 }
 
+/* Lookup the tunnel socket, possibly involving the fs code if the socket is
+ * owned by userspace.  A struct sock returned from this function must be
+ * released using l2tp_tunnel_sock_put once you're done with it.
+ */
+struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel)
+{
+       int err = 0;
+       struct socket *sock = NULL;
+       struct sock *sk = NULL;
+
+       if (!tunnel)
+               goto out;
+
+       if (tunnel->fd >= 0) {
+               /* Socket is owned by userspace, who might be in the process
+                * of closing it.  Look the socket up using the fd to ensure
+                * consistency.
+                */
+               sock = sockfd_lookup(tunnel->fd, &err);
+               if (sock)
+                       sk = sock->sk;
+       } else {
+               /* Socket is owned by kernelspace */
+               sk = tunnel->sock;
+       }
+
+out:
+       return sk;
+}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_lookup);
+
+/* Drop a reference to a tunnel socket obtained via. l2tp_tunnel_sock_put */
+void l2tp_tunnel_sock_put(struct sock *sk)
+{
+       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+       if (tunnel) {
+               if (tunnel->fd >= 0) {
+                       /* Socket is owned by userspace */
+                       sockfd_put(sk->sk_socket);
+               }
+               sock_put(sk);
+       }
+}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_put);
+
 /* Lookup a session by id in the global session list
  */
 static struct l2tp_session *l2tp_session_find_2(struct net *net, u32 session_id)
@@ -1123,8 +1168,6 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
        struct udphdr *uh;
        struct inet_sock *inet;
        __wsum csum;
-       int old_headroom;
-       int new_headroom;
        int headroom;
        int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
        int udp_len;
@@ -1136,16 +1179,12 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
         */
        headroom = NET_SKB_PAD + sizeof(struct iphdr) +
                uhlen + hdr_len;
-       old_headroom = skb_headroom(skb);
        if (skb_cow_head(skb, headroom)) {
                kfree_skb(skb);
                return NET_XMIT_DROP;
        }
 
-       new_headroom = skb_headroom(skb);
        skb_orphan(skb);
-       skb->truesize += new_headroom - old_headroom;
-
        /* Setup L2TP header */
        session->build_header(session, __skb_push(skb, hdr_len));
 
@@ -1607,6 +1646,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
        tunnel->old_sk_destruct = sk->sk_destruct;
        sk->sk_destruct = &l2tp_tunnel_destruct;
        tunnel->sock = sk;
+       tunnel->fd = fd;
        lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock");
 
        sk->sk_allocation = GFP_ATOMIC;
@@ -1642,24 +1682,32 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
  */
 int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
 {
-       int err = 0;
-       struct socket *sock = tunnel->sock ? tunnel->sock->sk_socket : NULL;
+       int err = -EBADF;
+       struct socket *sock = NULL;
+       struct sock *sk = NULL;
+
+       sk = l2tp_tunnel_sock_lookup(tunnel);
+       if (!sk)
+               goto out;
+
+       sock = sk->sk_socket;
+       BUG_ON(!sock);
 
        /* Force the tunnel socket to close. This will eventually
         * cause the tunnel to be deleted via the normal socket close
         * mechanisms when userspace closes the tunnel socket.
         */
-       if (sock != NULL) {
-               err = inet_shutdown(sock, 2);
+       err = inet_shutdown(sock, 2);
 
-               /* If the tunnel's socket was created by the kernel,
-                * close the socket here since the socket was not
-                * created by userspace.
-                */
-               if (sock->file == NULL)
-                       err = inet_release(sock);
-       }
+       /* If the tunnel's socket was created by the kernel,
+        * close the socket here since the socket was not
+        * created by userspace.
+        */
+       if (sock->file == NULL)
+               err = inet_release(sock);
 
+       l2tp_tunnel_sock_put(sk);
+out:
        return err;
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
index 56d583e..e62204c 100644 (file)
@@ -188,7 +188,8 @@ struct l2tp_tunnel {
        int (*recv_payload_hook)(struct sk_buff *skb);
        void (*old_sk_destruct)(struct sock *);
        struct sock             *sock;          /* Parent socket */
-       int                     fd;
+       int                     fd;             /* Parent fd, if tunnel socket
+                                                * was created by userspace */
 
        uint8_t                 priv[0];        /* private data */
 };
@@ -228,6 +229,8 @@ out:
        return tunnel;
 }
 
+extern struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel);
+extern void l2tp_tunnel_sock_put(struct sock *sk);
 extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id);
 extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth);
 extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname);
index 9275471..8ee4a86 100644 (file)
@@ -554,8 +554,8 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk,
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(struct ipv6_txoptions);
 
-               err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-                                       &hlimit, &tclass, &dontfrag);
+               err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
+                                           &hlimit, &tclass, &dontfrag);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
@@ -646,7 +646,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
                            struct msghdr *msg, size_t len, int noblock,
                            int flags, int *addr_len)
 {
-       struct inet_sock *inet = inet_sk(sk);
+       struct ipv6_pinfo *np = inet6_sk(sk);
        struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name;
        size_t copied = 0;
        int err = -EOPNOTSUPP;
@@ -688,8 +688,8 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
                        lsa->l2tp_scope_id = IP6CB(skb)->iif;
        }
 
-       if (inet->cmsg_flags)
-               ip_cmsg_recv(msg, skb);
+       if (np->rxopt.all)
+               ip6_datagram_recv_ctl(sk, msg, skb);
 
        if (flags & MSG_TRUNC)
                copied = skb->len;
index 286366e..716605c 100644 (file)
@@ -388,8 +388,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        struct l2tp_session *session;
        struct l2tp_tunnel *tunnel;
        struct pppol2tp_session *ps;
-       int old_headroom;
-       int new_headroom;
        int uhlen, headroom;
 
        if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
@@ -408,7 +406,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        if (tunnel == NULL)
                goto abort_put_sess;
 
-       old_headroom = skb_headroom(skb);
        uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
        headroom = NET_SKB_PAD +
                   sizeof(struct iphdr) + /* IP header */
@@ -418,9 +415,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        if (skb_cow_head(skb, headroom))
                goto abort_put_sess_tun;
 
-       new_headroom = skb_headroom(skb);
-       skb->truesize += new_headroom - old_headroom;
-
        /* Setup PPP header */
        __skb_push(skb, sizeof(ppph));
        skb->data[0] = ppph[0];
index a9327e2..670cbc3 100644 (file)
 /* Must be called with rcu_read_lock. */
 static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 {
-       if (unlikely(!vport)) {
-               kfree_skb(skb);
-               return;
-       }
+       if (unlikely(!vport))
+               goto error;
+
+       if (unlikely(skb_warn_if_lro(skb)))
+               goto error;
 
        /* Make our own copy of the packet.  Otherwise we will mangle the
         * packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
@@ -50,6 +51,10 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 
        skb_push(skb, ETH_HLEN);
        ovs_vport_receive(vport, skb);
+       return;
+
+error:
+       kfree_skb(skb);
 }
 
 /* Called with rcu_read_lock and bottom-halves disabled. */
@@ -169,9 +174,6 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
                goto error;
        }
 
-       if (unlikely(skb_warn_if_lro(skb)))
-               goto error;
-
        skb->dev = netdev_vport->dev;
        len = skb->len;
        dev_queue_xmit(skb);
index e639645..c111bd0 100644 (file)
@@ -2361,13 +2361,15 @@ static int packet_release(struct socket *sock)
 
        packet_flush_mclist(sk);
 
-       memset(&req_u, 0, sizeof(req_u));
-
-       if (po->rx_ring.pg_vec)
+       if (po->rx_ring.pg_vec) {
+               memset(&req_u, 0, sizeof(req_u));
                packet_set_ring(sk, &req_u, 1, 0);
+       }
 
-       if (po->tx_ring.pg_vec)
+       if (po->tx_ring.pg_vec) {
+               memset(&req_u, 0, sizeof(req_u));
                packet_set_ring(sk, &req_u, 1, 1);
+       }
 
        fanout_release(sk);
 
index 298c0dd..3d2acc7 100644 (file)
@@ -438,18 +438,18 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                if (q->rate) {
                        struct sk_buff_head *list = &sch->q;
 
-                       delay += packet_len_2_sched_time(skb->len, q);
-
                        if (!skb_queue_empty(list)) {
                                /*
-                                * Last packet in queue is reference point (now).
-                                * First packet in queue is already in flight,
-                                * calculate this time bonus and substract
+                                * Last packet in queue is reference point (now),
+                                * calculate this time bonus and subtract
                                 * from delay.
                                 */
-                               delay -= now - netem_skb_cb(skb_peek(list))->time_to_send;
+                               delay -= netem_skb_cb(skb_peek_tail(list))->time_to_send - now;
+                               delay = max_t(psched_tdiff_t, 0, delay);
                                now = netem_skb_cb(skb_peek_tail(list))->time_to_send;
                        }
+
+                       delay += packet_len_2_sched_time(skb->len, q);
                }
 
                cb->time_to_send = now + delay;
index 159b9bc..d8420ae 100644 (file)
@@ -71,7 +71,7 @@ void sctp_auth_key_put(struct sctp_auth_bytes *key)
                return;
 
        if (atomic_dec_and_test(&key->refcnt)) {
-               kfree(key);
+               kzfree(key);
                SCTP_DBG_OBJCNT_DEC(keys);
        }
 }
index 17a001b..1a9c5fb 100644 (file)
@@ -249,6 +249,8 @@ void sctp_endpoint_free(struct sctp_endpoint *ep)
 /* Final destructor for endpoint.  */
 static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
 {
+       int i;
+
        SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
 
        /* Free up the HMAC transform. */
@@ -271,6 +273,9 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
        sctp_inq_free(&ep->base.inqueue);
        sctp_bind_addr_free(&ep->base.bind_addr);
 
+       for (i = 0; i < SCTP_HOW_MANY_SECRETS; ++i)
+               memset(&ep->secret_key[i], 0, SCTP_SECRET_SIZE);
+
        /* Remove and free the port */
        if (sctp_sk(ep->base.sk)->bind_hash)
                sctp_put_port(ep->base.sk);
index 9e65758..cedd9bf 100644 (file)
@@ -3390,7 +3390,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
 
        ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey);
 out:
-       kfree(authkey);
+       kzfree(authkey);
        return ret;
 }
 
index 0a148c9..0f679df 100644 (file)
@@ -465,7 +465,7 @@ static int svc_udp_get_dest_address4(struct svc_rqst *rqstp,
 }
 
 /*
- * See net/ipv6/datagram.c : datagram_recv_ctl
+ * See net/ipv6/datagram.c : ip6_datagram_recv_ctl
  */
 static int svc_udp_get_dest_address6(struct svc_rqst *rqstp,
                                     struct cmsghdr *cmh)
index 01592d7..45f1618 100644 (file)
@@ -1358,7 +1358,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
                                                  &iwe, IW_EV_UINT_LEN);
        }
 
-       buf = kmalloc(30, GFP_ATOMIC);
+       buf = kmalloc(31, GFP_ATOMIC);
        if (buf) {
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;
index bbbd276..7203e66 100644 (file)
@@ -19,6 +19,7 @@ bpf-direct-objs := bpf-direct.o
 
 # Try to match the kernel target.
 ifndef CONFIG_64BIT
+ifndef CROSS_COMPILE
 
 # s390 has -m31 flag to build 31 bit binaries
 ifndef CONFIG_S390
@@ -35,6 +36,7 @@ HOSTLOADLIBES_bpf-direct += $(MFLAG)
 HOSTLOADLIBES_bpf-fancy += $(MFLAG)
 HOSTLOADLIBES_dropper += $(MFLAG)
 endif
+endif
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
index 4d2c7df..2bb08a9 100755 (executable)
@@ -230,12 +230,12 @@ our $Inline       = qr{inline|__always_inline|noinline};
 our $Member    = qr{->$Ident|\.$Ident|\[[^]]*\]};
 our $Lval      = qr{$Ident(?:$Member)*};
 
-our $Float_hex = qr{(?i:0x[0-9a-f]+p-?[0-9]+[fl]?)};
-our $Float_dec = qr{(?i:((?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?))};
-our $Float_int = qr{(?i:[0-9]+e-?[0-9]+[fl]?)};
+our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
+our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
+our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
 our $Float     = qr{$Float_hex|$Float_dec|$Float_int};
-our $Constant  = qr{(?:$Float|(?i:(?:0x[0-9a-f]+|[0-9]+)[ul]*))};
-our $Assignment        = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
+our $Constant  = qr{$Float|(?i)(?:0x[0-9a-f]+|[0-9]+)[ul]*};
+our $Assignment        = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
 our $Compare    = qr{<=|>=|==|!=|<|>};
 our $Operators = qr{
                        <=|>=|==|!=|
index a210c8d..3b98159 100644 (file)
@@ -108,13 +108,18 @@ if SND_IMX_SOC
 config SND_SOC_IMX_SSI
        tristate
 
-config SND_SOC_IMX_PCM_FIQ
+config SND_SOC_IMX_PCM
        tristate
+
+config SND_SOC_IMX_PCM_FIQ
+       bool
        select FIQ
+       select SND_SOC_IMX_PCM
 
 config SND_SOC_IMX_PCM_DMA
-       tristate
+       bool
        select SND_SOC_DMAENGINE_PCM
+       select SND_SOC_IMX_PCM
 
 config SND_SOC_IMX_AUDMUX
        tristate
index ec14579..afd3479 100644 (file)
@@ -41,10 +41,7 @@ endif
 obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
 obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
 
-obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += snd-soc-imx-pcm-fiq.o
-snd-soc-imx-pcm-fiq-y := imx-pcm-fiq.o imx-pcm.o
-obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += snd-soc-imx-pcm-dma.o
-snd-soc-imx-pcm-dma-y := imx-pcm-dma.o imx-pcm.o
+obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
 
 # i.MX Machine Support
 snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
index bf363d8..500f8ce 100644 (file)
@@ -154,26 +154,7 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
        .pcm_free       = imx_pcm_free,
 };
 
-static int imx_soc_platform_probe(struct platform_device *pdev)
+int imx_pcm_dma_init(struct platform_device *pdev)
 {
        return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
 }
-
-static int imx_soc_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_platform(&pdev->dev);
-       return 0;
-}
-
-static struct platform_driver imx_pcm_driver = {
-       .driver = {
-                       .name = "imx-pcm-audio",
-                       .owner = THIS_MODULE,
-       },
-       .probe = imx_soc_platform_probe,
-       .remove = imx_soc_platform_remove,
-};
-
-module_platform_driver(imx_pcm_driver);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-pcm-audio");
index 5ec362a..920f945 100644 (file)
@@ -281,7 +281,7 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = {
        .pcm_free       = imx_pcm_fiq_free,
 };
 
-static int imx_soc_platform_probe(struct platform_device *pdev)
+int imx_pcm_fiq_init(struct platform_device *pdev)
 {
        struct imx_ssi *ssi = platform_get_drvdata(pdev);
        int ret;
@@ -314,23 +314,3 @@ failed_register:
 
        return ret;
 }
-
-static int imx_soc_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_platform(&pdev->dev);
-       return 0;
-}
-
-static struct platform_driver imx_pcm_driver = {
-       .driver = {
-                       .name = "imx-fiq-pcm-audio",
-                       .owner = THIS_MODULE,
-       },
-
-       .probe = imx_soc_platform_probe,
-       .remove = imx_soc_platform_remove,
-};
-
-module_platform_driver(imx_pcm_driver);
-
-MODULE_LICENSE("GPL");
index 0c9f188..0d0625b 100644 (file)
@@ -31,6 +31,7 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
                        runtime->dma_bytes);
        return ret;
 }
+EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
 
 static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
 {
@@ -79,6 +80,7 @@ int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(imx_pcm_new);
 
 void imx_pcm_free(struct snd_pcm *pcm)
 {
@@ -100,6 +102,39 @@ void imx_pcm_free(struct snd_pcm *pcm)
                buf->area = NULL;
        }
 }
+EXPORT_SYMBOL_GPL(imx_pcm_free);
+
+static int imx_pcm_probe(struct platform_device *pdev)
+{
+       if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0)
+               return imx_pcm_fiq_init(pdev);
+
+       return imx_pcm_dma_init(pdev);
+}
+
+static int imx_pcm_remove(struct platform_device *pdev)
+{
+       snd_soc_unregister_platform(&pdev->dev);
+       return 0;
+}
+
+static struct platform_device_id imx_pcm_devtype[] = {
+       { .name = "imx-pcm-audio", },
+       { .name = "imx-fiq-pcm-audio", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, imx_pcm_devtype);
+
+static struct platform_driver imx_pcm_driver = {
+       .driver = {
+                       .name = "imx-pcm",
+                       .owner = THIS_MODULE,
+       },
+       .id_table = imx_pcm_devtype,
+       .probe = imx_pcm_probe,
+       .remove = imx_pcm_remove,
+};
+module_platform_driver(imx_pcm_driver);
 
 MODULE_DESCRIPTION("Freescale i.MX PCM driver");
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
index 83c0ed7..5ae13a1 100644 (file)
@@ -30,4 +30,22 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
 int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
 void imx_pcm_free(struct snd_pcm *pcm);
 
+#ifdef CONFIG_SND_SOC_IMX_PCM_DMA
+int imx_pcm_dma_init(struct platform_device *pdev);
+#else
+static inline int imx_pcm_dma_init(struct platform_device *pdev)
+{
+       return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_SND_SOC_IMX_PCM_FIQ
+int imx_pcm_fiq_init(struct platform_device *pdev);
+#else
+static inline int imx_pcm_fiq_init(struct platform_device *pdev)
+{
+       return -ENODEV;
+}
+#endif
+
 #endif /* _IMX_PCM_H */
index 6b9cf7a..bafeb8d 100644 (file)
@@ -13,6 +13,6 @@ clean :
        rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~
 
 install :
-       install acpidump /usr/bin/acpidump
+       install acpidump /usr/sbin/acpidump
        install acpidump.8 /usr/share/man/man8
 
diff --git a/tools/vm/.gitignore b/tools/vm/.gitignore
new file mode 100644 (file)
index 0000000..44f095f
--- /dev/null
@@ -0,0 +1,2 @@
+slabinfo
+page-types