Merge branch 'pdc' into release
Len Brown [Thu, 24 Dec 2009 06:17:21 +0000 (01:17 -0500)]
438 files changed:
Documentation/ABI/testing/sysfs-bus-usb
Documentation/driver-model/driver.txt
Documentation/filesystems/sysfs.txt
Documentation/power/runtime_pm.txt
Documentation/powerpc/dts-bindings/fsl/mpic.txt [new file with mode: 0644]
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/stable_kernel_rules.txt
Documentation/trace/events-kmem.txt
Documentation/usb/power-management.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/bug.h
arch/alpha/include/asm/perf_event.h [new file with mode: 0644]
arch/alpha/include/asm/unistd.h
arch/alpha/kernel/systbls.S
arch/powerpc/boot/dts/katmai.dts
arch/powerpc/boot/dts/mpc8315erdb.dts
arch/powerpc/boot/dts/mpc8349emitx.dts
arch/powerpc/boot/dts/warp.dts
arch/powerpc/boot/ugecon.c
arch/powerpc/configs/g5_defconfig
arch/powerpc/configs/iseries_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/ppc64e_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/bug.h
arch/powerpc/include/asm/gpio.h
arch/powerpc/kernel/align.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/platforms/83xx/suspend.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/embedded6xx/flipper-pic.c
arch/powerpc/platforms/embedded6xx/hlwd-pic.c
arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/iseries/viopath.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/cmm.c
arch/powerpc/platforms/pseries/dlpar.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/sysdev/cpm2_pic.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/mpc8xxx_gpio.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/mpic_msi.c
arch/powerpc/sysdev/mpic_u3msi.c
arch/s390/crypto/aes_s390.c
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/hypfs_vm.c
arch/s390/include/asm/unistd.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/ipl.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/traps.c
arch/x86/Kconfig
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/msr.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/stacktrace.h
arch/x86/kernel/apic/apic_flat_64.c
arch/x86/kernel/apic/bigsmp_32.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/x2apic_cluster.c
arch/x86/kernel/apic/x2apic_phys.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/dumpstack.c
arch/x86/kernel/dumpstack.h
arch/x86/kernel/dumpstack_32.c
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/e820.c
arch/x86/kernel/microcode_core.c
arch/x86/kernel/msr.c
arch/x86/kernel/stacktrace.c
arch/x86/kernel/tsc.c
arch/x86/kernel/uv_irq.c
arch/x86/lib/Makefile
arch/x86/lib/msr-smp.c [new file with mode: 0644]
arch/x86/lib/msr.c
arch/x86/mm/srat_32.c
arch/x86/mm/srat_64.c
arch/x86/oprofile/backtrace.c
arch/x86/tools/chkobjdump.awk
arch/x86/tools/gen-insn-attr-x86.awk
drivers/acpi/blacklist.c
drivers/acpi/bus.c
drivers/acpi/ec.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_bf54x.c
drivers/ata/pata_cmd64x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_octeon_cf.c
drivers/ata/sata_mv.c
drivers/base/bus.c
drivers/base/core.c
drivers/base/devtmpfs.c
drivers/base/driver.c
drivers/base/memory.c
drivers/base/platform.c
drivers/base/power/main.c
drivers/base/power/runtime.c
drivers/bluetooth/btusb.c
drivers/char/nozomi.c
drivers/char/sonypi.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_ioc32.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/i2c/ch7006_drv.c
drivers/gpu/drm/i2c/ch7006_mode.c
drivers/gpu/drm/i810/i810_dma.c
drivers/gpu/drm/i810/i810_drv.c
drivers/gpu/drm/i830/i830_dma.c
drivers/gpu/drm/i830/i830_drv.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_ioc32.c
drivers/gpu/drm/mga/mga_drv.c
drivers/gpu/drm/mga/mga_ioc32.c
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bios.h
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_grctx.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nouveau_grctx.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/nouveau_ioc32.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv04_crtc.c
drivers/gpu/drm/nouveau/nv04_dac.c
drivers/gpu/drm/nouveau/nv04_dfp.c
drivers/gpu/drm/nouveau/nv04_display.c
drivers/gpu/drm/nouveau/nv04_graph.c
drivers/gpu/drm/nouveau/nv10_graph.c
drivers/gpu/drm/nouveau/nv17_tv.c
drivers/gpu/drm/nouveau/nv40_graph.c
drivers/gpu/drm/nouveau/nv40_grctx.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nv50_crtc.c
drivers/gpu/drm/nouveau/nv50_cursor.c
drivers/gpu/drm/nouveau/nv50_dac.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_fifo.c
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/r128/r128_drv.c
drivers/gpu/drm/r128/r128_ioc32.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atom.h
drivers/gpu/drm/radeon/atombios.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100_track.h
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300_cmdbuf.c
drivers/gpu/drm/radeon/r300_reg.h
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_clocks.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_fence.c
drivers/gpu/drm/radeon/radeon_ioc32.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_test.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/savage/savage_drv.c
drivers/gpu/drm/sis/sis_drv.c
drivers/gpu/drm/tdfx/tdfx_drv.c
drivers/gpu/drm/via/via_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
drivers/infiniband/hw/cxgb3/cxio_hal.h
drivers/infiniband/hw/cxgb3/cxio_resource.c
drivers/isdn/mISDN/l1oip_core.c
drivers/media/video/cx23885/cx23888-ir.c
drivers/media/video/meye.c
drivers/media/video/meye.h
drivers/net/bnx2.c
drivers/net/can/at91_can.c
drivers/net/davinci_emac.c
drivers/net/e100.c
drivers/net/e1000e/82571.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/netxen/netxen_nic_main.c
drivers/net/phy/broadcom.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/main.c
drivers/platform/x86/fujitsu-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_diag.c
drivers/s390/char/fs3270.c
drivers/s390/char/tape_34xx.c
drivers/s390/char/tape_3590.c
drivers/s390/char/tape_block.c
drivers/s390/char/tape_char.c
drivers/s390/char/tape_class.c
drivers/s390/char/tape_core.c
drivers/s390/char/tape_proc.c
drivers/s390/char/tape_std.c
drivers/s390/cio/ccwreq.c
drivers/s390/cio/device.c
drivers/s390/cio/device_pgid.c
drivers/s390/cio/fcx.c
drivers/s390/cio/io_sch.h
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_perf.c
drivers/s390/cio/qdio_perf.h
drivers/s390/cio/qdio_setup.c
drivers/scsi/libiscsi.c
drivers/scsi/libiscsi_tcp.c
drivers/scsi/libsrp.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/batman-adv/Kconfig
drivers/staging/batman-adv/send.c
drivers/staging/comedi/comedi.h
drivers/staging/comedi/drivers/jr3_pci.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/dst/Kconfig [deleted file]
drivers/staging/dst/Makefile [deleted file]
drivers/staging/dst/crypto.c [deleted file]
drivers/staging/dst/dcore.c [deleted file]
drivers/staging/dst/export.c [deleted file]
drivers/staging/dst/state.c [deleted file]
drivers/staging/dst/thread_pool.c [deleted file]
drivers/staging/dst/trans.c [deleted file]
drivers/staging/panel/Kconfig
drivers/staging/panel/panel.c
drivers/staging/pohmelfs/dir.c
drivers/staging/ramzswap/TODO
drivers/staging/ramzswap/ramzswap_drv.c
drivers/staging/rtl8187se/ieee80211/ieee80211.h
drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8187se/r8180_wx.c
drivers/staging/rtl8192e/ieee80211.h
drivers/staging/rtl8192e/ieee80211/ieee80211.h
drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
drivers/staging/rtl8192e/r8192E_core.c
drivers/staging/rtl8192su/ieee80211/ieee80211.h
drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
drivers/staging/rtl8192su/r8192U_core.c
drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
drivers/staging/sm7xx/Kconfig [new file with mode: 0644]
drivers/staging/sm7xx/Makefile [new file with mode: 0644]
drivers/staging/sm7xx/TODO [new file with mode: 0644]
drivers/staging/sm7xx/smtc2d.c [new file with mode: 0644]
drivers/staging/sm7xx/smtc2d.h [new file with mode: 0644]
drivers/staging/sm7xx/smtcfb.c [new file with mode: 0644]
drivers/staging/sm7xx/smtcfb.h [new file with mode: 0644]
drivers/staging/vt6655/Kconfig
drivers/staging/vt6656/Kconfig
drivers/staging/wlan-ng/prism2fw.c
drivers/usb/Makefile
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/sysfs.c
drivers/usb/core/usb.c
drivers/usb/early/ehci-dbgp.c
drivers/usb/gadget/audio.c
drivers/usb/gadget/f_audio.c
drivers/usb/gadget/u_audio.c
drivers/usb/gadget/u_audio.h
drivers/usb/host/fhci-sched.c
drivers/usb/host/fhci-tds.c
drivers/usb/host/fhci.h
drivers/usb/misc/appledisplay.c
drivers/usb/misc/emi62.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/blackfin.h
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_gadget_ep0.c
drivers/usb/otg/isp1301_omap.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/ftdi_sio_ids.h [new file with mode: 0644]
drivers/usb/serial/generic.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/usb-serial.c
drivers/watchdog/Kconfig
drivers/watchdog/geodewdt.c
fs/anon_inodes.c
fs/compat_ioctl.c
fs/eventfd.c
fs/eventpoll.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext3/resize.c
fs/ext3/super.c
fs/ext4/ext4.h
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/super.c
fs/file_table.c
fs/internal.h
fs/jbd/journal.c
fs/jbd2/journal.c
fs/jfs/super.c
fs/namei.c
fs/nfsd/nfsfh.c
fs/ocfs2/alloc.c
fs/ocfs2/alloc.h
fs/ocfs2/namei.c
fs/ocfs2/refcounttree.c
fs/open.c
fs/proc/array.c
fs/quota/dquot.c
fs/quota/quota_v2.c
fs/signalfd.c
fs/stat.c
fs/super.c
fs/sysfs/bin.c
fs/timerfd.c
include/drm/drmP.h
include/linux/decompress/mm.h
include/linux/device.h
include/linux/dst.h [deleted file]
include/linux/elf.h
include/linux/ext3_fs_sb.h
include/linux/ext3_jbd.h
include/linux/fs.h
include/linux/kfifo.h
include/linux/memory.h
include/linux/mm.h
include/linux/namei.h
include/linux/perf_counter.h [deleted file]
include/linux/quota.h
include/linux/rcutiny.h
include/linux/rcutree.h
include/linux/sched.h
include/linux/sysfs.h
include/linux/usb/serial.h
include/scsi/libiscsi.h
include/scsi/libiscsi_tcp.h
include/scsi/libsrp.h
init/initramfs.c
init/main.c
kernel/audit_tree.c
kernel/auditsc.c
kernel/cpu.c
kernel/kfifo.c
kernel/kthread.c
kernel/perf_event.c
kernel/resource.c
kernel/sched.c
kernel/sched_clock.c
kernel/sched_fair.c
kernel/sched_rt.c
kernel/signal.c
kernel/sys.c
kernel/time.c
kernel/time/clockevents.c
kernel/time/timekeeping.c
kernel/timer.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_sysprof.c
lib/decompress_bunzip2.c
lib/string.c
mm/page_alloc.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap.c
net/dccp/probe.c
net/ipv6/reassembly.c
net/ipv6/route.c
security/tomoyo/file.c
sound/arm/aaci.c
sound/arm/aaci.h
sound/core/Kconfig
sound/core/pcm_lib.c
sound/core/pcm_timer.c
sound/isa/msnd/msnd_midi.c
sound/isa/sb/emu8000.c
sound/mips/sgio2audio.c
sound/oss/pss.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm9712.c
sound/soc/imx/mx27vis_wm8974.c
sound/soc/sh/fsi.c
sound/usb/usbaudio.c
tools/perf/Makefile
tools/perf/builtin-probe.c
tools/perf/builtin-report.c
tools/perf/util/event.h
tools/perf/util/probe-event.c
tools/perf/util/probe-finder.h
virt/kvm/kvm_main.c

index deb6b48..a07c0f3 100644 (file)
@@ -21,25 +21,27 @@ Contact:    Alan Stern <stern@rowland.harvard.edu>
 Description:
                Each USB device directory will contain a file named
                power/level.  This file holds a power-level setting for
-               the device, one of "on", "auto", or "suspend".
+               the device, either "on" or "auto".
 
                "on" means that the device is not allowed to autosuspend,
                although normal suspends for system sleep will still
                be honored.  "auto" means the device will autosuspend
                and autoresume in the usual manner, according to the
-               capabilities of its driver.  "suspend" means the device
-               is forced into a suspended state and it will not autoresume
-               in response to I/O requests.  However remote-wakeup requests
-               from the device may still be enabled (the remote-wakeup
-               setting is controlled separately by the power/wakeup
-               attribute).
+               capabilities of its driver.
 
                During normal use, devices should be left in the "auto"
-               level.  The other levels are meant for administrative uses.
+               level.  The "on" level is meant for administrative uses.
                If you want to suspend a device immediately but leave it
                free to wake up in response to I/O requests, you should
                write "0" to power/autosuspend.
 
+               Device not capable of proper suspend and resume should be
+               left in the "on" level.  Although the USB spec requires
+               devices to support suspend/resume, many of them do not.
+               In fact so many don't that by default, the USB core
+               initializes all non-hub devices in the "on" level.  Some
+               drivers may change this setting when they are bound.
+
 What:          /sys/bus/usb/devices/.../power/persist
 Date:          May 2007
 KernelVersion: 2.6.23
index 60120fb..d2cd6fb 100644 (file)
@@ -226,5 +226,5 @@ struct driver_attribute driver_attr_debug;
 This can then be used to add and remove the attribute from the
 driver's directory using:
 
-int driver_create_file(struct device_driver *, struct driver_attribute *);
-void driver_remove_file(struct device_driver *, struct driver_attribute *);
+int driver_create_file(struct device_driver *, const struct driver_attribute *);
+void driver_remove_file(struct device_driver *, const struct driver_attribute *);
index b245d52..931c806 100644 (file)
@@ -91,8 +91,8 @@ struct device_attribute {
                         const char *buf, size_t count);
 };
 
-int device_create_file(struct device *, struct device_attribute *);
-void device_remove_file(struct device *, struct device_attribute *);
+int device_create_file(struct device *, const struct device_attribute *);
+void device_remove_file(struct device *, const struct device_attribute *);
 
 It also defines this helper for defining device attributes: 
 
@@ -316,8 +316,8 @@ DEVICE_ATTR(_name, _mode, _show, _store);
 
 Creation/Removal:
 
-int device_create_file(struct device *device, struct device_attribute * attr);
-void device_remove_file(struct device * dev, struct device_attribute * attr);
+int device_create_file(struct device *dev, const struct device_attribute * attr);
+void device_remove_file(struct device *dev, const struct device_attribute * attr);
 
 
 - bus drivers (include/linux/device.h)
@@ -358,7 +358,7 @@ DRIVER_ATTR(_name, _mode, _show, _store)
 
 Creation/Removal:
 
-int driver_create_file(struct device_driver *, struct driver_attribute *);
-void driver_remove_file(struct device_driver *, struct driver_attribute *);
+int driver_create_file(struct device_driver *, const struct driver_attribute *);
+void driver_remove_file(struct device_driver *, const struct driver_attribute *);
 
 
index 4a3109b..356fd86 100644 (file)
@@ -42,80 +42,81 @@ struct dev_pm_ops {
        ...
 };
 
-The ->runtime_suspend() callback is executed by the PM core for the bus type of
-the device being suspended.  The bus type's callback is then _entirely_
-_responsible_ for handling the device as appropriate, which may, but need not
-include executing the device driver's own ->runtime_suspend() callback (from the
+The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are
+executed by the PM core for either the bus type, or device type (if the bus
+type's callback is not defined), or device class (if the bus type's and device
+type's callbacks are not defined) of given device.  The bus type, device type
+and device class callbacks are referred to as subsystem-level callbacks in what
+follows.
+
+The subsystem-level suspend callback is _entirely_ _responsible_ for handling
+the suspend of the device as appropriate, which may, but need not include
+executing the device driver's own ->runtime_suspend() callback (from the
 PM core's point of view it is not necessary to implement a ->runtime_suspend()
-callback in a device driver as long as the bus type's ->runtime_suspend() knows
-what to do to handle the device).
+callback in a device driver as long as the subsystem-level suspend callback
+knows what to do to handle the device).
 
-  * Once the bus type's ->runtime_suspend() callback has completed successfully
+  * Once the subsystem-level suspend callback has completed successfully
     for given device, the PM core regards the device as suspended, which need
     not mean that the device has been put into a low power state.  It is
     supposed to mean, however, that the device will not process data and will
-    not communicate with the CPU(s) and RAM until its bus type's
-    ->runtime_resume() callback is executed for it.  The run-time PM status of
-    a device after successful execution of its bus type's ->runtime_suspend()
-    callback is 'suspended'.
-
-  * If the bus type's ->runtime_suspend() callback returns -EBUSY or -EAGAIN,
-    the device's run-time PM status is supposed to be 'active', which means that
-    the device _must_ be fully operational afterwards.
-
-  * If the bus type's ->runtime_suspend() callback returns an error code
-    different from -EBUSY or -EAGAIN, the PM core regards this as a fatal
-    error and will refuse to run the helper functions described in Section 4
-    for the device, until the status of it is directly set either to 'active'
-    or to 'suspended' (the PM core provides special helper functions for this
-    purpose).
-
-In particular, if the driver requires remote wakeup capability for proper
-functioning and device_run_wake() returns 'false' for the device, then
-->runtime_suspend() should return -EBUSY.  On the other hand, if
-device_run_wake() returns 'true' for the device and the device is put
-into a low power state during the execution of its bus type's
-->runtime_suspend(), it is expected that remote wake-up (i.e. hardware mechanism
-allowing the device to request a change of its power state, such as PCI PME)
-will be enabled for the device.  Generally, remote wake-up should be enabled
-for all input devices put into a low power state at run time.
-
-The ->runtime_resume() callback is executed by the PM core for the bus type of
-the device being woken up.  The bus type's callback is then _entirely_
-_responsible_ for handling the device as appropriate, which may, but need not
-include executing the device driver's own ->runtime_resume() callback (from the
-PM core's point of view it is not necessary to implement a ->runtime_resume()
-callback in a device driver as long as the bus type's ->runtime_resume() knows
-what to do to handle the device).
-
-  * Once the bus type's ->runtime_resume() callback has completed successfully,
-    the PM core regards the device as fully operational, which means that the
-    device _must_ be able to complete I/O operations as needed.  The run-time
-    PM status of the device is then 'active'.
-
-  * If the bus type's ->runtime_resume() callback returns an error code, the PM
-    core regards this as a fatal error and will refuse to run the helper
-    functions described in Section 4 for the device, until its status is
-    directly set either to 'active' or to 'suspended' (the PM core provides
-    special helper functions for this purpose).
-
-The ->runtime_idle() callback is executed by the PM core for the bus type of
-given device whenever the device appears to be idle, which is indicated to the
-PM core by two counters, the device's usage counter and the counter of 'active'
-children of the device.
+    not communicate with the CPU(s) and RAM until the subsystem-level resume
+    callback is executed for it.  The run-time PM status of a device after
+    successful execution of the subsystem-level suspend callback is 'suspended'.
+
+  * If the subsystem-level suspend callback returns -EBUSY or -EAGAIN,
+    the device's run-time PM status is 'active', which means that the device
+    _must_ be fully operational afterwards.
+
+  * If the subsystem-level suspend callback returns an error code different
+    from -EBUSY or -EAGAIN, the PM core regards this as a fatal error and will
+    refuse to run the helper functions described in Section 4 for the device,
+    until the status of it is directly set either to 'active', or to 'suspended'
+    (the PM core provides special helper functions for this purpose).
+
+In particular, if the driver requires remote wake-up capability (i.e. hardware
+mechanism allowing the device to request a change of its power state, such as
+PCI PME) for proper functioning and device_run_wake() returns 'false' for the
+device, then ->runtime_suspend() should return -EBUSY.  On the other hand, if
+device_run_wake() returns 'true' for the device and the device is put into a low
+power state during the execution of the subsystem-level suspend callback, it is
+expected that remote wake-up will be enabled for the device.  Generally, remote
+wake-up should be enabled for all input devices put into a low power state at
+run time.
+
+The subsystem-level resume callback is _entirely_ _responsible_ for handling the
+resume of the device as appropriate, which may, but need not include executing
+the device driver's own ->runtime_resume() callback (from the PM core's point of
+view it is not necessary to implement a ->runtime_resume() callback in a device
+driver as long as the subsystem-level resume callback knows what to do to handle
+the device).
+
+  * Once the subsystem-level resume callback has completed successfully, the PM
+    core regards the device as fully operational, which means that the device
+    _must_ be able to complete I/O operations as needed.  The run-time PM status
+    of the device is then 'active'.
+
+  * If the subsystem-level resume callback returns an error code, the PM core
+    regards this as a fatal error and will refuse to run the helper functions
+    described in Section 4 for the device, until its status is directly set
+    either to 'active' or to 'suspended' (the PM core provides special helper
+    functions for this purpose).
+
+The subsystem-level idle callback is executed by the PM core whenever the device
+appears to be idle, which is indicated to the PM core by two counters, the
+device's usage counter and the counter of 'active' children of the device.
 
   * If any of these counters is decreased using a helper function provided by
     the PM core and it turns out to be equal to zero, the other counter is
     checked.  If that counter also is equal to zero, the PM core executes the
-    device bus type's ->runtime_idle() callback (with the device as an
-    argument).
+    subsystem-level idle callback with the device as an argument.
 
-The action performed by a bus type's ->runtime_idle() callback is totally
-dependent on the bus type in question, but the expected and recommended action
-is to check if the device can be suspended (i.e. if all of the conditions
-necessary for suspending the device are satisfied) and to queue up a suspend
-request for the device in that case.  The value returned by this callback is
-ignored by the PM core.
+The action performed by a subsystem-level idle callback is totally dependent on
+the subsystem in question, but the expected and recommended action is to check
+if the device can be suspended (i.e. if all of the conditions necessary for
+suspending the device are satisfied) and to queue up a suspend request for the
+device in that case.  The value returned by this callback is ignored by the PM
+core.
 
 The helper functions provided by the PM core, described in Section 4, guarantee
 that the following constraints are met with respect to the bus type's run-time
@@ -238,41 +239,41 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
       removing the device from device hierarchy
 
   int pm_runtime_idle(struct device *dev);
-    - execute ->runtime_idle() for the device's bus type; returns 0 on success
-      or error code on failure, where -EINPROGRESS means that ->runtime_idle()
-      is already being executed
+    - execute the subsystem-level idle callback for the device; returns 0 on
+      success or error code on failure, where -EINPROGRESS means that
+      ->runtime_idle() is already being executed
 
   int pm_runtime_suspend(struct device *dev);
-    - execute ->runtime_suspend() for the device's bus type; returns 0 on
+    - execute the subsystem-level suspend callback for the device; returns 0 on
       success, 1 if the device's run-time PM status was already 'suspended', or
       error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt
       to suspend the device again in future
 
   int pm_runtime_resume(struct device *dev);
-    - execute ->runtime_resume() for the device's bus type; returns 0 on
+    - execute the subsystem-leve resume callback for the device; returns 0 on
       success, 1 if the device's run-time PM status was already 'active' or
       error code on failure, where -EAGAIN means it may be safe to attempt to
       resume the device again in future, but 'power.runtime_error' should be
       checked additionally
 
   int pm_request_idle(struct device *dev);
-    - submit a request to execute ->runtime_idle() for the device's bus type
-      (the request is represented by a work item in pm_wq); returns 0 on success
-      or error code if the request has not been queued up
+    - submit a request to execute the subsystem-level idle callback for the
+      device (the request is represented by a work item in pm_wq); returns 0 on
+      success or error code if the request has not been queued up
 
   int pm_schedule_suspend(struct device *dev, unsigned int delay);
-    - schedule the execution of ->runtime_suspend() for the device's bus type
-      in future, where 'delay' is the time to wait before queuing up a suspend
-      work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is
-      queued up immediately); returns 0 on success, 1 if the device's PM
+    - schedule the execution of the subsystem-level suspend callback for the
+      device in future, where 'delay' is the time to wait before queuing up a
+      suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work
+      item is queued up immediately); returns 0 on success, 1 if the device's PM
       run-time status was already 'suspended', or error code if the request
       hasn't been scheduled (or queued up if 'delay' is 0); if the execution of
       ->runtime_suspend() is already scheduled and not yet expired, the new
       value of 'delay' will be used as the time to wait
 
   int pm_request_resume(struct device *dev);
-    - submit a request to execute ->runtime_resume() for the device's bus type
-      (the request is represented by a work item in pm_wq); returns 0 on
+    - submit a request to execute the subsystem-level resume callback for the
+      device (the request is represented by a work item in pm_wq); returns 0 on
       success, 1 if the device's run-time PM status was already 'active', or
       error code if the request hasn't been queued up
 
@@ -303,12 +304,12 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
       run-time PM callbacks described in Section 2
 
   int pm_runtime_disable(struct device *dev);
-    - prevent the run-time PM helper functions from running the device bus
-      type's run-time PM callbacks, make sure that all of the pending run-time
-      PM operations on the device are either completed or canceled; returns
-      1 if there was a resume request pending and it was necessary to execute
-      ->runtime_resume() for the device's bus type to satisfy that request,
-      otherwise 0 is returned
+    - prevent the run-time PM helper functions from running subsystem-level
+      run-time PM callbacks for the device, make sure that all of the pending
+      run-time PM operations on the device are either completed or canceled;
+      returns 1 if there was a resume request pending and it was necessary to
+      execute the subsystem-level resume callback for the device to satisfy that
+      request, otherwise 0 is returned
 
   void pm_suspend_ignore_children(struct device *dev, bool enable);
     - set/unset the power.ignore_children flag of the device
@@ -378,5 +379,55 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts,
 they will fail returning -EAGAIN, because the device's usage counter is
 incremented by the core before executing ->probe() and ->remove().  Still, it
 may be desirable to suspend the device as soon as ->probe() or ->remove() has
-finished, so the PM core uses pm_runtime_idle_sync() to invoke the device bus
-type's ->runtime_idle() callback at that time.
+finished, so the PM core uses pm_runtime_idle_sync() to invoke the
+subsystem-level idle callback for the device at that time.
+
+6. Run-time PM and System Sleep
+
+Run-time PM and system sleep (i.e., system suspend and hibernation, also known
+as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of
+ways.  If a device is active when a system sleep starts, everything is
+straightforward.  But what should happen if the device is already suspended?
+
+The device may have different wake-up settings for run-time PM and system sleep.
+For example, remote wake-up may be enabled for run-time suspend but disallowed
+for system sleep (device_may_wakeup(dev) returns 'false').  When this happens,
+the subsystem-level system suspend callback is responsible for changing the
+device's wake-up setting (it may leave that to the device driver's system
+suspend routine).  It may be necessary to resume the device and suspend it again
+in order to do so.  The same is true if the driver uses different power levels
+or other settings for run-time suspend and system sleep.
+
+During system resume, devices generally should be brought back to full power,
+even if they were suspended before the system sleep began.  There are several
+reasons for this, including:
+
+  * The device might need to switch power levels, wake-up settings, etc.
+
+  * Remote wake-up events might have been lost by the firmware.
+
+  * The device's children may need the device to be at full power in order
+    to resume themselves.
+
+  * The driver's idea of the device state may not agree with the device's
+    physical state.  This can happen during resume from hibernation.
+
+  * The device might need to be reset.
+
+  * Even though the device was suspended, if its usage counter was > 0 then most
+    likely it would need a run-time resume in the near future anyway.
+
+  * Always going back to full power is simplest.
+
+If the device was suspended before the sleep began, then its run-time PM status
+will have to be updated to reflect the actual post-system sleep status.  The way
+to do this is:
+
+       pm_runtime_disable(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+
+The PM core always increments the run-time usage counter before calling the
+->prepare() callback and decrements it after calling the ->complete() callback.
+Hence disabling run-time PM temporarily like this will not cause any run-time
+suspend callbacks to be lost.
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpic.txt b/Documentation/powerpc/dts-bindings/fsl/mpic.txt
new file mode 100644 (file)
index 0000000..71e39cf
--- /dev/null
@@ -0,0 +1,42 @@
+* OpenPIC and its interrupt numbers on Freescale's e500/e600 cores
+
+The OpenPIC specification does not specify which interrupt source has to
+become which interrupt number. This is up to the software implementation
+of the interrupt controller. The only requirement is that every
+interrupt source has to have an unique interrupt number / vector number.
+To accomplish this the current implementation assigns the number zero to
+the first source, the number one to the second source and so on until
+all interrupt sources have their unique number.
+Usually the assigned vector number equals the interrupt number mentioned
+in the documentation for a given core / CPU. This is however not true
+for the e500 cores (MPC85XX CPUs) where the documentation distinguishes
+between internal and external interrupt sources and starts counting at
+zero for both of them.
+
+So what to write for external interrupt source X or internal interrupt
+source Y into the device tree? Here is an example:
+
+The memory map for the interrupt controller in the MPC8544[0] shows,
+that the first interrupt source starts at 0x5_0000 (PIC Register Address
+Map-Interrupt Source Configuration Registers). This source becomes the
+number zero therefore:
+ External interrupt 0 = interrupt number 0
+ External interrupt 1 = interrupt number 1
+ External interrupt 2 = interrupt number 2
+ ...
+Every interrupt number allocates 0x20 bytes register space. So to get
+its number it is sufficient to shift the lower 16bits to right by five.
+So for the external interrupt 10 we have:
+  0x0140 >> 5 = 10
+
+After the external sources, the internal sources follow. The in core I2C
+controller on the MPC8544 for instance has the internal source number
+27. Oo obtain its interrupt number we take the lower 16bits of its memory
+address (0x5_0560) and shift it right:
+ 0x0560 >> 5 = 43
+
+Therefore the I2C device node for the MPC8544 CPU has to have the
+interrupt number 43 specified in the device tree.
+
+[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual
+    MPC8544ERM Rev. 1 10/2007
index e93afff..e72cee9 100644 (file)
@@ -403,4 +403,5 @@ STAC9872
 Cirrus Logic CS4206/4207
 ========================
   mbp55                MacBook Pro 5,5
+  imac27       IMac 27 Inch
   auto         BIOS setup (default)
index a452227..5effa5b 100644 (file)
@@ -26,13 +26,33 @@ Procedure for submitting patches to the -stable tree:
 
  - Send the patch, after verifying that it follows the above rules, to
    stable@kernel.org.
+ - To have the patch automatically included in the stable tree, add the
+   the tag
+     Cc: stable@kernel.org
+   in the sign-off area. Once the patch is merged it will be applied to
+   the stable tree without anything else needing to be done by the author
+   or subsystem maintainer.
+ - If the patch requires other patches as prerequisites which can be
+   cherry-picked than this can be specified in the following format in
+   the sign-off area:
+
+     Cc: <stable@kernel.org> # .32.x: a1f84a3: sched: Check for idle
+     Cc: <stable@kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
+     Cc: <stable@kernel.org> # .32.x: fd21073: sched: Fix affinity logic
+     Cc: <stable@kernel.org> # .32.x
+    Signed-off-by: Ingo Molnar <mingo@elte.hu>
+
+   The tag sequence has the meaning of:
+     git cherry-pick a1f84a3
+     git cherry-pick 1b9508f
+     git cherry-pick fd21073
+     git cherry-pick <this commit>
+
  - The sender will receive an ACK when the patch has been accepted into the
    queue, or a NAK if the patch is rejected.  This response might take a few
    days, according to the developer's schedules.
  - If accepted, the patch will be added to the -stable queue, for review by
    other developers and by the relevant subsystem maintainer.
- - If the stable@kernel.org address is added to a patch, when it goes into
-   Linus's tree it will automatically be emailed to the stable team.
  - Security patches should not be sent to this alias, but instead to the
    documented security@kernel.org address.
 
index 6ef2a86..aa82ee4 100644 (file)
@@ -1,7 +1,7 @@
                        Subsystem Trace Points: kmem
 
-The tracing system kmem captures events related to object and page allocation
-within the kernel. Broadly speaking there are four major subheadings.
+The kmem tracing system captures events related to object and page allocation
+within the kernel. Broadly speaking there are five major subheadings.
 
   o Slab allocation of small objects of unknown type (kmalloc)
   o Slab allocation of small objects of known type
@@ -9,7 +9,7 @@ within the kernel. Broadly speaking there are four major subheadings.
   o Per-CPU Allocator Activity
   o External Fragmentation
 
-This document will describe what each of the tracepoints are and why they
+This document describes what each of the tracepoints is and why they
 might be useful.
 
 1. Slab allocation of small objects of unknown type
@@ -34,7 +34,7 @@ kmem_cache_free               call_site=%lx ptr=%p
 These events are similar in usage to the kmalloc-related events except that
 it is likely easier to pin the event down to a specific cache. At the time
 of writing, no information is available on what slab is being allocated from,
-but the call_site can usually be used to extrapolate that information
+but the call_site can usually be used to extrapolate that information.
 
 3. Page allocation
 ==================
@@ -80,9 +80,9 @@ event indicating whether it is for a percpu_refill or not.
 When the per-CPU list is too full, a number of pages are freed, each one
 which triggers a mm_page_pcpu_drain event.
 
-The individual nature of the events are so that pages can be tracked
+The individual nature of the events is so that pages can be tracked
 between allocation and freeing. A number of drain or refill pages that occur
-consecutively imply the zone->lock being taken once. Large amounts of PCP
+consecutively imply the zone->lock being taken once. Large amounts of per-CPU
 refills and drains could imply an imbalance between CPUs where too much work
 is being concentrated in one place. It could also indicate that the per-CPU
 lists should be a larger size. Finally, large amounts of refills on one CPU
@@ -102,6 +102,6 @@ is important.
 
 Large numbers of this event implies that memory is fragmenting and
 high-order allocations will start failing at some time in the future. One
-means of reducing the occurange of this event is to increase the size of
+means of reducing the occurrence of this event is to increase the size of
 min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where
 pageblock_size is usually the size of the default hugepage size.
index c7c1dc2..3bf6818 100644 (file)
@@ -71,12 +71,10 @@ being accessed through sysfs, then it definitely is idle.
        Forms of dynamic PM
        -------------------
 
-Dynamic suspends can occur in two ways: manual and automatic.
-"Manual" means that the user has told the kernel to suspend a device,
-whereas "automatic" means that the kernel has decided all by itself to
-suspend a device.  Automatic suspend is called "autosuspend" for
-short.  In general, a device won't be autosuspended unless it has been
-idle for some minimum period of time, the so-called idle-delay time.
+Dynamic suspends occur when the kernel decides to suspend an idle
+device.  This is called "autosuspend" for short.  In general, a device
+won't be autosuspended unless it has been idle for some minimum period
+of time, the so-called idle-delay time.
 
 Of course, nothing the kernel does on its own initiative should
 prevent the computer or its devices from working properly.  If a
@@ -96,10 +94,11 @@ idle.
 We can categorize power management events in two broad classes:
 external and internal.  External events are those triggered by some
 agent outside the USB stack: system suspend/resume (triggered by
-userspace), manual dynamic suspend/resume (also triggered by
-userspace), and remote wakeup (triggered by the device).  Internal
-events are those triggered within the USB stack: autosuspend and
-autoresume.
+userspace), manual dynamic resume (also triggered by userspace), and
+remote wakeup (triggered by the device).  Internal events are those
+triggered within the USB stack: autosuspend and autoresume.  Note that
+all dynamic suspend events are internal; external agents are not
+allowed to issue dynamic suspends.
 
 
        The user interface for dynamic PM
@@ -145,9 +144,9 @@ relevant attribute files are: wakeup, level, and autosuspend.
                number of seconds the device should remain idle before
                the kernel will autosuspend it (the idle-delay time).
                The default is 2.  0 means to autosuspend as soon as
-               the device becomes idle, and -1 means never to
-               autosuspend.  You can write a number to the file to
-               change the autosuspend idle-delay time.
+               the device becomes idle, and negative values mean
+               never to autosuspend.  You can write a number to the
+               file to change the autosuspend idle-delay time.
 
 Writing "-1" to power/autosuspend and writing "on" to power/level do
 essentially the same thing -- they both prevent the device from being
@@ -377,9 +376,9 @@ the device hasn't been idle for long enough, a delayed workqueue
 routine is automatically set up to carry out the operation when the
 autosuspend idle-delay has expired.
 
-Autoresume attempts also can fail.  This will happen if power/level is
-set to "suspend" or if the device doesn't manage to resume properly.
-Unlike autosuspend, there's no delay for an autoresume.
+Autoresume attempts also can fail, although failure would mean that
+the device is no longer present or operating properly.  Unlike
+autosuspend, there's no delay for an autoresume.
 
 
        Other parts of the driver interface
@@ -527,13 +526,3 @@ succeed, it may still remain active and thus cause the system to
 resume as soon as the system suspend is complete.  Or the remote
 wakeup may fail and get lost.  Which outcome occurs depends on timing
 and on the hardware and firmware design.
-
-More interestingly, a device might undergo a manual resume or
-autoresume during system suspend.  With current kernels this shouldn't
-happen, because manual resumes must be initiated by userspace and
-autoresumes happen in response to I/O requests, but all user processes
-and I/O should be quiescent during a system suspend -- thanks to the
-freezer.  However there are plans to do away with the freezer, which
-would mean these things would become possible.  If and when this comes
-about, the USB core will carefully arrange matters so that either type
-of resume will block until the entire system has resumed.
index efd2ef2..745643b 100644 (file)
@@ -1402,6 +1402,8 @@ L:        linux-usb@vger.kernel.org
 S:     Supported
 F:     Documentation/usb/WUSB-Design-overview.txt
 F:     Documentation/usb/wusb-cbaf
+F:     drivers/usb/host/hwa-hc.c
+F:     drivers/usb/host/whci/
 F:     drivers/usb/wusbcore/
 F:     include/linux/usb/wusb*
 
@@ -3677,7 +3679,7 @@ F:        include/linux/isicom.h
 MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
 M:     Felipe Balbi <felipe.balbi@nokia.com>
 L:     linux-usb@vger.kernel.org
-T:     git git://gitorious.org/musb/mainline.git
+T:     git git://gitorious.org/usb/usb.git
 S:     Maintained
 F:     drivers/usb/musb/
 
@@ -5430,7 +5432,10 @@ ULTRA-WIDEBAND (UWB) SUBSYSTEM:
 M:     David Vrabel <david.vrabel@csr.com>
 L:     linux-usb@vger.kernel.org
 S:     Supported
-F:     drivers/uwb/*
+F:     drivers/uwb/
+X:     drivers/uwb/wlp/
+X:     drivers/uwb/i1480/i1480u-wlp/
+X:     drivers/uwb/i1480/i1480-wlp.h
 F:     include/linux/uwb.h
 F:     include/linux/uwb/
 
@@ -5943,9 +5948,12 @@ W:       http://linuxwimax.org
 
 WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM
 M:     David Vrabel <david.vrabel@csr.com>
+L:     netdev@vger.kernel.org
 S:     Maintained
 F:     include/linux/wlp.h
 F:     drivers/uwb/wlp/
+F:     drivers/uwb/i1480/i1480u-wlp/
+F:     drivers/uwb/i1480/i1480-wlp.h
 
 WISTRON LAPTOP BUTTON DRIVER
 M:     Miloslav Trmac <mitr@volny.cz>
index 0ac5812..e6b06cb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,13 @@ NAME = Man-Eating Seals of Antiquity
 # o  print "Entering directory ...";
 MAKEFLAGS += -rR --no-print-directory
 
+# Avoid funny character set dependencies
+unexport LC_ALL
+LC_CTYPE=C
+LC_COLLATE=C
+LC_NUMERIC=C
+export LC_CTYPE LC_COLLATE LC_NUMERIC
+
 # We are using a recursive build, so we need to do a little thinking
 # to get the ordering right.
 #
index d828758..9d055b4 100644 (file)
@@ -135,9 +135,7 @@ config HAVE_DEFAULT_NO_SPIN_MUTEXES
 
 config HAVE_HW_BREAKPOINT
        bool
-       depends on HAVE_PERF_EVENTS
-       select ANON_INODES
-       select PERF_EVENTS
+       depends on PERF_EVENTS
 
 config HAVE_USER_RETURN_NOTIFIER
        bool
index 4434481..bd7261e 100644 (file)
@@ -9,6 +9,7 @@ config ALPHA
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_SYSCALL_WRAPPERS
+       select HAVE_PERF_EVENTS
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
index 1720c8a..f091682 100644 (file)
@@ -13,7 +13,8 @@
                "call_pal %0  # bugchk\n\t"                             \
                ".long %1\n\t.8byte %2"                                 \
                : : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__));     \
-       for ( ; ; ); } while (0)
+       unreachable();                                                  \
+  } while (0)
 
 #define HAVE_ARCH_BUG
 #endif
diff --git a/arch/alpha/include/asm/perf_event.h b/arch/alpha/include/asm/perf_event.h
new file mode 100644 (file)
index 0000000..3bef852
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __ASM_ALPHA_PERF_EVENT_H
+#define __ASM_ALPHA_PERF_EVENT_H
+
+/* Alpha only supports software events through this interface. */
+static inline void set_perf_event_pending(void) { }
+
+#define PERF_EVENT_INDEX_OFFSET 0
+
+#endif /* __ASM_ALPHA_PERF_EVENT_H */
index 7f23665..804e531 100644 (file)
 #define __IGNORE_pause
 #define __IGNORE_time
 #define __IGNORE_utime
+#define __IGNORE_umount2
 
 /*
  * Linux-specific system calls begin at 300
 #define __NR_timerfd                   477
 #define __NR_eventfd                   478
 #define __NR_recvmmsg                  479
+#define __NR_fallocate                 480
+#define __NR_timerfd_create            481
+#define __NR_timerfd_settime           482
+#define __NR_timerfd_gettime           483
+#define __NR_signalfd4                 484
+#define __NR_eventfd2                  485
+#define __NR_epoll_create1             486
+#define __NR_dup3                      487
+#define __NR_pipe2                     488
+#define __NR_inotify_init1             489
+#define __NR_preadv                    490
+#define __NR_pwritev                   491
+#define __NR_rt_tgsigqueueinfo         492
+#define __NR_perf_event_open           493
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS                    480
+#define NR_SYSCALLS                    494
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index cda6b8b..09acb78 100644 (file)
@@ -495,9 +495,23 @@ sys_call_table:
        .quad sys_epoll_pwait
        .quad sys_utimensat                     /* 475 */
        .quad sys_signalfd
-       .quad sys_ni_syscall
+       .quad sys_ni_syscall                    /* sys_timerfd */
        .quad sys_eventfd
        .quad sys_recvmmsg
+       .quad sys_fallocate                             /* 480 */
+       .quad sys_timerfd_create
+       .quad sys_timerfd_settime
+       .quad sys_timerfd_gettime
+       .quad sys_signalfd4
+       .quad sys_eventfd2                              /* 485 */
+       .quad sys_epoll_create1
+       .quad sys_dup3
+       .quad sys_pipe2
+       .quad sys_inotify_init1
+       .quad sys_preadv                                /* 490 */
+       .quad sys_pwritev
+       .quad sys_rt_tgsigqueueinfo
+       .quad sys_perf_event_open
 
        .size sys_call_table, . - sys_call_table
        .type sys_call_table, @object
index 51eb6ed..8f345de 100644 (file)
                dcr-reg = <0x00c 0x002>;
        };
 
+       MQ0: mq {
+               compatible = "ibm,mq-440spe";
+               dcr-reg = <0x040 0x020>;
+       };
+
        plb {
                compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4";
                #address-cells = <2>;
                #size-cells = <1>;
                /*        addr-child     addr-parent    size */
-               ranges = <0x4 0xe0000000 0x4 0xe0000000 0x20000000
+               ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000
+                         0x4 0x00200000 0x4 0x00200000 0x00000400
+                         0x4 0xe0000000 0x4 0xe0000000 0x20000000
                          0xc 0x00000000 0xc 0x00000000 0x20000000
                          0xd 0x00000000 0xd 0x00000000 0x80000000
                          0xd 0x80000000 0xd 0x80000000 0x80000000
                                0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */
                                0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
                };
+
+               I2O: i2o@400100000 {
+                       compatible = "ibm,i2o-440spe";
+                       reg = <0x00000004 0x00100000 0x100>;
+                       dcr-reg = <0x060 0x020>;
+               };
+
+               DMA0: dma0@400100100 {
+                       compatible = "ibm,dma-440spe";
+                       cell-index = <0>;
+                       reg = <0x00000004 0x00100100 0x100>;
+                       dcr-reg = <0x060 0x020>;
+                       interrupt-parent = <&DMA0>;
+                       interrupts = <0 1>;
+                       #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <
+                               0 &UIC0 0x14 4
+                               1 &UIC1 0x16 4>;
+               };
+
+               DMA1: dma1@400100200 {
+                       compatible = "ibm,dma-440spe";
+                       cell-index = <1>;
+                       reg = <0x00000004 0x00100200 0x100>;
+                       dcr-reg = <0x060 0x020>;
+                       interrupt-parent = <&DMA1>;
+                       interrupts = <0 1>;
+                       #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <
+                               0 &UIC0 0x16 4
+                               1 &UIC1 0x16 4>;
+               };
+
+               xor-accel@400200000 {
+                       compatible = "amcc,xor-accelerator";
+                       reg = <0x00000004 0x00200000 0x400>;
+                       interrupt-parent = <&UIC1>;
+                       interrupts = <0x1f 4>;
+               };
        };
 
        chosen {
index 32e10f5..8a3a4f3 100644 (file)
                        interrupt-parent = <&ipic>;
                        tbi-handle = <&tbi0>;
                        phy-handle = < &phy0 >;
+                       fsl,magic-packet;
 
                        mdio@520 {
                                #address-cells = <1>;
                        interrupt-parent = <&ipic>;
                        tbi-handle = <&tbi1>;
                        phy-handle = < &phy1 >;
+                       fsl,magic-packet;
 
                        mdio@520 {
                                #address-cells = <1>;
                        interrupt-parent = <&ipic>;
                };
 
+               gtm1: timer@500 {
+                       compatible = "fsl,mpc8315-gtm", "fsl,gtm";
+                       reg = <0x500 0x100>;
+                       interrupts = <90 8 78 8 84 8 72 8>;
+                       interrupt-parent = <&ipic>;
+                       clock-frequency = <133333333>;
+               };
+
+               timer@600 {
+                       compatible = "fsl,mpc8315-gtm", "fsl,gtm";
+                       reg = <0x600 0x100>;
+                       interrupts = <91 8 79 8 85 8 73 8>;
+                       interrupt-parent = <&ipic>;
+                       clock-frequency = <133333333>;
+               };
+
                /* IPIC
                 * interrupts cell = <intr #, sense>
                 * sense values match linux IORESOURCE_IRQ_* defines:
                                      0x59 0x8>;
                        interrupt-parent = < &ipic >;
                };
+
+               pmc: power@b00 {
+                       compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc",
+                                    "fsl,mpc8349-pmc";
+                       reg = <0xb00 0x100 0xa00 0x100>;
+                       interrupts = <80 8>;
+                       interrupt-parent = <&ipic>;
+                       fsl,mpc8313-wakeup-timer = <&gtm1>;
+               };
        };
 
        pci0: pci@e0008500 {
index feeeb7f..b53d1df 100644 (file)
                        reg = <0x200 0x100>;
                };
 
+               gpio1: gpio-controller@c00 {
+                       #gpio-cells = <2>;
+                       compatible = "fsl,mpc8349-gpio";
+                       reg = <0xc00 0x100>;
+                       interrupts = <74 0x8>;
+                       interrupt-parent = <&ipic>;
+                       gpio-controller;
+               };
+
+               gpio2: gpio-controller@d00 {
+                       #gpio-cells = <2>;
+                       compatible = "fsl,mpc8349-gpio";
+                       reg = <0xd00 0x100>;
+                       interrupts = <75 0x8>;
+                       interrupt-parent = <&ipic>;
+                       gpio-controller;
+               };
+
                i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        interrupts = <14 0x8>;
                        interrupt-parent = <&ipic>;
                        dfsrr;
+
+                       eeprom: at24@50 {
+                               compatible = "st-micro,24c256";
+                               reg = <0x50>;
+                       };
+
                };
 
                i2c@3100 {
                                interrupt-parent = <&ipic>;
                        };
 
+                       pcf1: iexp@38 {
+                               #gpio-cells = <2>;
+                               compatible = "ti,pcf8574a";
+                               reg = <0x38>;
+                               gpio-controller;
+                       };
+
+                       pcf2: iexp@39 {
+                               #gpio-cells = <2>;
+                               compatible = "ti,pcf8574a";
+                               reg = <0x39>;
+                               gpio-controller;
+                       };
+
+                       spd: at24@51 {
+                               compatible = "at24,spd";
+                               reg = <0x51>;
+                       };
+
                        mcu_pio: mcu@a {
                                #gpio-cells = <2>;
                                compatible = "fsl,mc9s08qg8-mpc8349emitx",
                        reg = <0x700 0x100>;
                        device_type = "ipic";
                };
+
+               gpio-leds {
+                       compatible = "gpio-leds";
+
+                       green {
+                               label = "Green";
+                               gpios = <&pcf1 0 1>;
+                               linux,default-trigger = "heartbeat";
+                       };
+
+                       yellow {
+                               label = "Yellow";
+                               gpios = <&pcf1 1 1>;
+                               /* linux,default-trigger = "heartbeat"; */
+                               default-state = "on";
+                       };
+               };
+
        };
 
        pci0: pci@e0008500 {
                compatible = "fsl,mpc8349e-localbus",
                             "fsl,pq2pro-localbus";
                reg = <0xe0005000 0xd8>;
-               ranges = <0x3 0x0 0xf0000000 0x210>;
+               ranges = <0x0 0x0 0xfe000000 0x1000000  /* flash */
+                         0x1 0x0 0xf8000000 0x20000    /* VSC 7385 */
+                         0x2 0x0 0xf9000000 0x200000   /* exp slot */
+                         0x3 0x0 0xf0000000 0x210>;    /* CF slot */
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0x0      0x0 0x800000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
+
+               flash@0,800000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "cfi-flash";
+                       reg = <0x0 0x800000 0x800000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
 
                pata@3,0 {
                        compatible = "fsl,mpc8349emitx-pata", "ata-generic";
index 31605ee..e576ee8 100644 (file)
 
                                fpga@2,4000 {
                                        compatible = "pika,fpga-sd";
-                                       reg = <0x00000002 0x00004000 0x00000A00>;
+                                       reg = <0x00000002 0x00004000 0x00004000>;
                                };
 
                                nor@0,0 {
index 50609ea..8f2a6b3 100644 (file)
@@ -86,7 +86,7 @@ static void ug_putc(char ch)
 
        while (!ug_is_txfifo_ready() && count--)
                barrier();
-       if (count)
+       if (count >= 0)
                ug_raw_putc(ch);
 }
 
index fc90592..826a65d 100644 (file)
@@ -757,7 +757,7 @@ CONFIG_SUNGEM=y
 # CONFIG_B44 is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
-CONFIG_ACENIC=y
+CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
@@ -794,8 +794,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
index f925c55..76982c5 100644 (file)
@@ -714,8 +714,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
index 2524018..7b3804a 100644 (file)
@@ -304,11 +304,11 @@ CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
+CONFIG_HZ=100
 CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
@@ -980,7 +980,7 @@ CONFIG_E100=y
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
-CONFIG_ACENIC=y
+CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
@@ -1023,8 +1023,8 @@ CONFIG_PASEMI_MAC=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
@@ -1863,7 +1863,7 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
+CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
index 18af460..8195f16 100644 (file)
@@ -1008,8 +1008,8 @@ CONFIG_IXGB=m
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 CONFIG_WLAN=y
index c568329..ca9ff9a 100644 (file)
@@ -230,11 +230,11 @@ CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
+CONFIG_HZ=100
 CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
@@ -796,7 +796,7 @@ CONFIG_E100=y
 # CONFIG_NET_POCKET is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
-CONFIG_ACENIC=y
+CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
@@ -834,8 +834,8 @@ CONFIG_S2IO=m
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
@@ -1494,7 +1494,7 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
+CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
index 64e1fdc..2c15212 100644 (file)
@@ -68,7 +68,7 @@
                _EMIT_BUG_ENTRY                                 \
                : : "i" (__FILE__), "i" (__LINE__),             \
                    "i" (0), "i"  (sizeof(struct bug_entry)));  \
-       for(;;) ;                                               \
+       unreachable();                                          \
 } while (0)
 
 #define BUG_ON(x) do {                                         \
index ea04632..38762ed 100644 (file)
@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
        return __gpio_cansleep(gpio);
 }
 
-/*
- * Not implemented, yet.
- */
 static inline int gpio_to_irq(unsigned int gpio)
 {
-       return -ENOSYS;
+       return __gpio_to_irq(gpio);
 }
 
 static inline int irq_to_gpio(unsigned int irq)
index 3839839..b876e98 100644 (file)
@@ -642,10 +642,14 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
  */
 static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
                       unsigned int areg, struct pt_regs *regs,
-                      unsigned int flags, unsigned int length)
+                      unsigned int flags, unsigned int length,
+                      unsigned int elsize)
 {
        char *ptr;
+       unsigned long *lptr;
        int ret = 0;
+       int sw = 0;
+       int i, j;
 
        flush_vsx_to_thread(current);
 
@@ -654,19 +658,35 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
        else
                ptr = (char *) &current->thread.vr[reg - 32];
 
-       if (flags & ST)
-               ret = __copy_to_user(addr, ptr, length);
-        else {
-               if (flags & SPLT){
-                       ret = __copy_from_user(ptr, addr, length);
-                       ptr += length;
+       lptr = (unsigned long *) ptr;
+
+       if (flags & SW)
+               sw = elsize-1;
+
+       for (j = 0; j < length; j += elsize) {
+               for (i = 0; i < elsize; ++i) {
+                       if (flags & ST)
+                               ret |= __put_user(ptr[i^sw], addr + i);
+                       else
+                               ret |= __get_user(ptr[i^sw], addr + i);
                }
-               ret |= __copy_from_user(ptr, addr, length);
+               ptr  += elsize;
+               addr += elsize;
        }
-       if (flags & U)
-               regs->gpr[areg] = regs->dar;
-       if (ret)
+
+       if (!ret) {
+               if (flags & U)
+                       regs->gpr[areg] = regs->dar;
+
+               /* Splat load copies the same data to top and bottom 8 bytes */
+               if (flags & SPLT)
+                       lptr[1] = lptr[0];
+               /* For 8 byte loads, zero the top 8 bytes */
+               else if (!(flags & ST) && (8 == length))
+                       lptr[1] = 0;
+       } else
                return -EFAULT;
+
        return 1;
 }
 #endif
@@ -767,16 +787,25 @@ int fix_alignment(struct pt_regs *regs)
 
 #ifdef CONFIG_VSX
        if ((instruction & 0xfc00003e) == 0x7c000018) {
-               /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */
+               unsigned int elsize;
+
+               /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */
                reg |= (instruction & 0x1) << 5;
                /* Simple inline decoder instead of a table */
+               /* VSX has only 8 and 16 byte memory accesses */
+               nb = 8;
                if (instruction & 0x200)
                        nb = 16;
-               else if (instruction & 0x080)
-                       nb = 8;
-               else
-                       nb = 4;
+
+               /* Vector stores in little-endian mode swap individual
+                  elements, so process them separately */
+               elsize = 4;
+               if (instruction & 0x80)
+                       elsize = 8;
+
                flags = 0;
+               if (regs->msr & MSR_LE)
+                       flags |= SW;
                if (instruction & 0x100)
                        flags |= ST;
                if (instruction & 0x040)
@@ -787,7 +816,7 @@ int fix_alignment(struct pt_regs *regs)
                        nb = 8;
                }
                PPC_WARN_ALIGNMENT(vsx, regs);
-               return emulate_vsx(addr, reg, areg, regs, flags, nb);
+               return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize);
        }
 #endif
        /* A size of 0 indicates an instruction we don't support, with
index 50f867d..3ecdcec 100644 (file)
@@ -340,7 +340,7 @@ static int __init htab_dt_scan_page_sizes(unsigned long node,
                        else
                                def->tlbiel = 0;
 
-                       DBG(" %d: shift=%02x, sllp=%04x, avpnm=%08x, "
+                       DBG(" %d: shift=%02x, sllp=%04lx, avpnm=%08lx, "
                            "tlbiel=%d, penc=%d\n",
                            idx, shift, def->sllp, def->avpnm, def->tlbiel,
                            def->penc);
@@ -663,7 +663,7 @@ static void __init htab_initialize(void)
                base = (unsigned long)__va(lmb.memory.region[i].base);
                size = lmb.memory.region[i].size;
 
-               DBG("creating mapping for region: %lx..%lx (prot: %x)\n",
+               DBG("creating mapping for region: %lx..%lx (prot: %lx)\n",
                    base, size, prot);
 
 #ifdef CONFIG_U3_DART
@@ -879,7 +879,7 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
  */
 int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
 {
-       void *pgdir;
+       pgd_t *pgdir;
        unsigned long vsid;
        struct mm_struct *mm;
        pte_t *ptep;
@@ -1025,7 +1025,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        else
 #endif /* CONFIG_PPC_HAS_HASH_64K */
        {
-               int spp = subpage_protection(pgdir, ea);
+               int spp = subpage_protection(mm, ea);
                if (access & spp)
                        rc = -2;
                else
@@ -1115,7 +1115,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
 {
        unsigned long hash, index, shift, hidx, slot;
 
-       DBG_LOW("flush_hash_page(va=%016x)\n", va);
+       DBG_LOW("flush_hash_page(va=%016lx)\n", va);
        pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
                hash = hpt_hash(va, shift, ssize);
                hidx = __rpte_to_hidx(pte, index);
@@ -1123,7 +1123,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
                        hash = ~hash;
                slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
                slot += hidx & _PTEIDX_GROUP_IX;
-               DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx);
+               DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
                ppc_md.hpte_invalidate(slot, va, psize, ssize, local);
        } pte_iterate_hashed_end();
 }
index be4f34c..1044a63 100644 (file)
@@ -353,7 +353,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
                read_lock(&tasklist_lock);
                for_each_process(p) {
                        if (p->mm)
-                               cpu_mask_clear_cpu(cpu, mm_cpumask(p->mm));
+                               cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
                }
                read_unlock(&tasklist_lock);
        break;
index 177e403..573b3bd 100644 (file)
@@ -382,7 +382,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
                return 0;
        if (!get_pteptr(&init_mm, address, &kpte, &kpmd))
                return -EINVAL;
-       set_pte_at(&init_mm, address, kpte, mk_pte(page, prot));
+       __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0);
        wmb();
 #ifdef CONFIG_PPC_STD_MMU
        flush_hash_pages(0, address, pmd_val(*kpmd), 1);
index d306f07..4380534 100644 (file)
@@ -32,6 +32,7 @@
 #define PMCCR1_NEXT_STATE       0x0C /* Next state for power management */
 #define PMCCR1_NEXT_STATE_SHIFT 2
 #define PMCCR1_CURR_STATE       0x03 /* Current state for power management*/
+#define IMMR_SYSCR_OFFSET       0x100
 #define IMMR_RCW_OFFSET         0x900
 #define RCW_PCI_HOST            0x80000000
 
@@ -78,6 +79,22 @@ struct mpc83xx_clock {
        u32 sccr;
 };
 
+struct mpc83xx_syscr {
+       __be32 sgprl;
+       __be32 sgprh;
+       __be32 spridr;
+       __be32 :32;
+       __be32 spcr;
+       __be32 sicrl;
+       __be32 sicrh;
+};
+
+struct mpc83xx_saved {
+       u32 sicrl;
+       u32 sicrh;
+       u32 sccr;
+};
+
 struct pmc_type {
        int has_deep_sleep;
 };
@@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping;
 static int pmc_irq;
 static struct mpc83xx_pmc __iomem *pmc_regs;
 static struct mpc83xx_clock __iomem *clock_regs;
+static struct mpc83xx_syscr __iomem *syscr_regs;
+static struct mpc83xx_saved saved_regs;
 static int is_pci_agent, wake_from_pci;
 static phys_addr_t immrbase;
 static int pci_pm_state;
@@ -137,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id)
        return ret;
 }
 
+static void mpc83xx_suspend_restore_regs(void)
+{
+       out_be32(&syscr_regs->sicrl, saved_regs.sicrl);
+       out_be32(&syscr_regs->sicrh, saved_regs.sicrh);
+       out_be32(&clock_regs->sccr, saved_regs.sccr);
+}
+
+static void mpc83xx_suspend_save_regs(void)
+{
+       saved_regs.sicrl = in_be32(&syscr_regs->sicrl);
+       saved_regs.sicrh = in_be32(&syscr_regs->sicrh);
+       saved_regs.sccr = in_be32(&clock_regs->sccr);
+}
+
 static int mpc83xx_suspend_enter(suspend_state_t state)
 {
        int ret = -EAGAIN;
@@ -166,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
         */
 
        if (deep_sleeping) {
+               mpc83xx_suspend_save_regs();
+
                out_be32(&pmc_regs->mask, PMCER_ALL);
 
                out_be32(&pmc_regs->config1,
@@ -179,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
                         in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
 
                out_be32(&pmc_regs->mask, PMCER_PMCI);
+
+               mpc83xx_suspend_restore_regs();
        } else {
                out_be32(&pmc_regs->mask, PMCER_PMCI);
 
@@ -194,7 +231,7 @@ out:
        return ret;
 }
 
-static void mpc83xx_suspend_finish(void)
+static void mpc83xx_suspend_end(void)
 {
        deep_sleeping = 0;
 }
@@ -278,7 +315,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = {
        .valid = mpc83xx_suspend_valid,
        .begin = mpc83xx_suspend_begin,
        .enter = mpc83xx_suspend_enter,
-       .finish = mpc83xx_suspend_finish,
+       .end = mpc83xx_suspend_end,
 };
 
 static int pmc_probe(struct of_device *ofdev,
@@ -333,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev,
                goto out_pmc;
        }
 
+       if (has_deep_sleep) {
+               syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET,
+                                    sizeof(*syscr_regs));
+               if (!syscr_regs) {
+                       ret = -ENOMEM;
+                       goto out_syscr;
+               }
+       }
+
        if (is_pci_agent)
                mpc83xx_set_agent();
 
        suspend_set_ops(&mpc83xx_suspend_ops);
        return 0;
 
+out_syscr:
+       iounmap(clock_regs);
 out_pmc:
        iounmap(pmc_regs);
 out:
index c5028a2..21f61b8 100644 (file)
@@ -86,7 +86,7 @@ static int mpc8568_fixup_125_clock(struct phy_device *phydev)
        scr = phy_read(phydev, MV88E1111_SCR);
 
        if (scr < 0)
-               return err;
+               return scr;
 
        err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);
 
index d596328..c278bd3 100644 (file)
@@ -102,7 +102,7 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq,
                           irq_hw_number_t hwirq)
 {
        set_irq_chip_data(virq, h->host_data);
-       get_irq_desc(virq)->status |= IRQ_LEVEL;
+       irq_to_desc(virq)->status |= IRQ_LEVEL;
        set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq);
        return 0;
 }
index dd20bff..a771f91 100644 (file)
@@ -95,7 +95,7 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
                           irq_hw_number_t hwirq)
 {
        set_irq_chip_data(virq, h->host_data);
-       get_irq_desc(virq)->status |= IRQ_LEVEL;
+       irq_to_desc(virq)->status |= IRQ_LEVEL;
        set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq);
        return 0;
 }
@@ -132,9 +132,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
        struct irq_host *irq_host = get_irq_data(cascade_virq);
        unsigned int virq;
 
-       spin_lock(&desc->lock);
+       raw_spin_lock(&desc->lock);
        desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
-       spin_unlock(&desc->lock);
+       raw_spin_unlock(&desc->lock);
 
        virq = __hlwd_pic_get_irq(irq_host);
        if (virq != NO_IRQ)
@@ -142,11 +142,11 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
        else
                pr_err("spurious interrupt!\n");
 
-       spin_lock(&desc->lock);
+       raw_spin_lock(&desc->lock);
        desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
        if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
                desc->chip->unmask(cascade_virq);
-       spin_unlock(&desc->lock);
+       raw_spin_unlock(&desc->lock);
 }
 
 /*
index edc956c..20a8ed9 100644 (file)
@@ -120,7 +120,7 @@ static void ug_putc(char ch)
 
        while (!ug_is_txfifo_ready() && count--)
                barrier();
-       if (count)
+       if (count >= 0)
                ug_raw_putc(ch);
 }
 
index 0d9343d..6617915 100644 (file)
@@ -855,59 +855,58 @@ static int mf_get_boot_rtc(struct rtc_time *tm)
 }
 
 #ifdef CONFIG_PROC_FS
-
-static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
-               int count, int *eof, void *data)
+static int mf_cmdline_proc_show(struct seq_file *m, void *v)
 {
-       int len;
-       char *p;
+       char *page, *p;
        struct vsp_cmd_data vsp_cmd;
        int rc;
        dma_addr_t dma_addr;
 
        /* The HV appears to return no more than 256 bytes of command line */
-       if (off >= 256)
-               return 0;
-       if ((off + count) > 256)
-               count = 256 - off;
+       page = kmalloc(256, GFP_KERNEL);
+       if (!page)
+               return -ENOMEM;
 
-       dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE);
-       if (dma_addr == DMA_ERROR_CODE)
+       dma_addr = iseries_hv_map(page, 256, DMA_FROM_DEVICE);
+       if (dma_addr == DMA_ERROR_CODE) {
+               kfree(page);
                return -ENOMEM;
-       memset(page, 0, off + count);
+       }
+       memset(page, 0, 256);
        memset(&vsp_cmd, 0, sizeof(vsp_cmd));
        vsp_cmd.cmd = 33;
        vsp_cmd.sub_data.kern.token = dma_addr;
        vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
-       vsp_cmd.sub_data.kern.side = (u64)data;
-       vsp_cmd.sub_data.kern.length = off + count;
+       vsp_cmd.sub_data.kern.side = (u64)m->private;
+       vsp_cmd.sub_data.kern.length = 256;
        mb();
        rc = signal_vsp_instruction(&vsp_cmd);
-       iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE);
-       if (rc)
+       iseries_hv_unmap(dma_addr, 256, DMA_FROM_DEVICE);
+       if (rc) {
+               kfree(page);
                return rc;
-       if (vsp_cmd.result_code != 0)
+       }
+       if (vsp_cmd.result_code != 0) {
+               kfree(page);
                return -ENOMEM;
+       }
        p = page;
-       len = 0;
-       while (len < (off + count)) {
-               if ((*p == '\0') || (*p == '\n')) {
-                       if (*p == '\0')
-                               *p = '\n';
-                       p++;
-                       len++;
-                       *eof = 1;
+       while (p - page < 256) {
+               if (*p == '\0' || *p == '\n') {
+                       *p = '\n';
                        break;
                }
                p++;
-               len++;
-       }
 
-       if (len < off) {
-               *eof = 1;
-               len = 0;
        }
-       return len;
+       seq_write(m, page, p - page);
+       kfree(page);
+       return 0;
+}
+
+static int mf_cmdline_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mf_cmdline_proc_show, PDE(inode)->data);
 }
 
 #if 0
@@ -962,10 +961,8 @@ static int proc_mf_dump_vmlinux(char *page, char **start, off_t off,
 }
 #endif
 
-static int proc_mf_dump_side(char *page, char **start, off_t off,
-               int count, int *eof, void *data)
+static int mf_side_proc_show(struct seq_file *m, void *v)
 {
-       int len;
        char mf_current_side = ' ';
        struct vsp_cmd_data vsp_cmd;
 
@@ -989,21 +986,17 @@ static int proc_mf_dump_side(char *page, char **start, off_t off,
                }
        }
 
-       len = sprintf(page, "%c\n", mf_current_side);
+       seq_printf(m, "%c\n", mf_current_side);
+       return 0;
+}
 
-       if (len <= (off + count))
-               *eof = 1;
-       *start = page + off;
-       len -= off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
-       return len;
+static int mf_side_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mf_side_proc_show, NULL);
 }
 
-static int proc_mf_change_side(struct file *file, const char __user *buffer,
-               unsigned long count, void *data)
+static ssize_t mf_side_proc_write(struct file *file, const char __user *buffer,
+                                 size_t count, loff_t *pos)
 {
        char side;
        u64 newSide;
@@ -1041,6 +1034,15 @@ static int proc_mf_change_side(struct file *file, const char __user *buffer,
        return count;
 }
 
+static const struct file_operations mf_side_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = mf_side_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = mf_side_proc_write,
+};
+
 #if 0
 static void mf_getSrcHistory(char *buffer, int size)
 {
@@ -1087,8 +1089,7 @@ static void mf_getSrcHistory(char *buffer, int size)
 }
 #endif
 
-static int proc_mf_dump_src(char *page, char **start, off_t off,
-               int count, int *eof, void *data)
+static int mf_src_proc_show(struct seq_file *m, void *v)
 {
 #if 0
        int len;
@@ -1109,8 +1110,13 @@ static int proc_mf_dump_src(char *page, char **start, off_t off,
 #endif
 }
 
-static int proc_mf_change_src(struct file *file, const char __user *buffer,
-               unsigned long count, void *data)
+static int mf_src_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mf_src_proc_show, NULL);
+}
+
+static ssize_t mf_src_proc_write(struct file *file, const char __user *buffer,
+                                size_t count, loff_t *pos)
 {
        char stkbuf[10];
 
@@ -1135,9 +1141,19 @@ static int proc_mf_change_src(struct file *file, const char __user *buffer,
        return count;
 }
 
-static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
-               unsigned long count, void *data)
+static const struct file_operations mf_src_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = mf_src_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = mf_src_proc_write,
+};
+
+static ssize_t mf_cmdline_proc_write(struct file *file, const char __user *buffer,
+                                    size_t count, loff_t *pos)
 {
+       void *data = PDE(file->f_path.dentry->d_inode)->data;
        struct vsp_cmd_data vsp_cmd;
        dma_addr_t dma_addr;
        char *page;
@@ -1172,6 +1188,15 @@ out:
        return ret;
 }
 
+static const struct file_operations mf_cmdline_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = mf_cmdline_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = mf_cmdline_proc_write,
+};
+
 static ssize_t proc_mf_change_vmlinux(struct file *file,
                                      const char __user *buf,
                                      size_t count, loff_t *ppos)
@@ -1246,12 +1271,10 @@ static int __init mf_proc_init(void)
                if (!mf)
                        return 1;
 
-               ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf);
+               ent = proc_create_data("cmdline", S_IRUSR|S_IWUSR, mf,
+                                      &mf_cmdline_proc_fops, (void *)(long)i);
                if (!ent)
                        return 1;
-               ent->data = (void *)(long)i;
-               ent->read_proc = proc_mf_dump_cmdline;
-               ent->write_proc = proc_mf_change_cmdline;
 
                if (i == 3)     /* no vmlinux entry for 'D' */
                        continue;
@@ -1263,19 +1286,15 @@ static int __init mf_proc_init(void)
                        return 1;
        }
 
-       ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+       ent = proc_create("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
+                         &mf_side_proc_fops);
        if (!ent)
                return 1;
-       ent->data = (void *)0;
-       ent->read_proc = proc_mf_dump_side;
-       ent->write_proc = proc_mf_change_side;
 
-       ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+       ent = proc_create("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
+                         &mf_src_proc_fops);
        if (!ent)
                return 1;
-       ent->data = (void *)0;
-       ent->read_proc = proc_mf_dump_src;
-       ent->write_proc = proc_mf_change_src;
 
        return 0;
 }
index 49ff4dc..5aea94f 100644 (file)
@@ -116,7 +116,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
        u16 vlanMap;
        dma_addr_t handle;
        HvLpEvent_Rc hvrc;
-       DECLARE_COMPLETION(done);
+       DECLARE_COMPLETION_ONSTACK(done);
        struct device_node *node;
        const char *sysid;
 
index 27554c8..c667f0f 100644 (file)
@@ -2,6 +2,8 @@ config PPC_PSERIES
        depends on PPC64 && PPC_BOOK3S
        bool "IBM pSeries & new (POWER5-based) iSeries"
        select MPIC
+       select PCI_MSI
+       select XICS
        select PPC_I8259
        select PPC_RTAS
        select PPC_RTAS_DAEMON
index bcdcf0c..a277f2e 100644 (file)
 #include <asm/mmu.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
+#include <linux/memory.h>
 
 #include "plpar_wrappers.h"
 
 #define CMM_DRIVER_VERSION     "1.0.0"
 #define CMM_DEFAULT_DELAY      1
+#define CMM_HOTPLUG_DELAY      5
 #define CMM_DEBUG                      0
 #define CMM_DISABLE            0
 #define CMM_OOM_KB             1024
 #define CMM_MIN_MEM_MB         256
 #define KB2PAGES(_p)           ((_p)>>(PAGE_SHIFT-10))
 #define PAGES2KB(_p)           ((_p)<<(PAGE_SHIFT-10))
+/*
+ * The priority level tries to ensure that this notifier is called as
+ * late as possible to reduce thrashing in the shared memory pool.
+ */
+#define CMM_MEM_HOTPLUG_PRI    1
+#define CMM_MEM_ISOLATE_PRI    15
 
 static unsigned int delay = CMM_DEFAULT_DELAY;
+static unsigned int hotplug_delay = CMM_HOTPLUG_DELAY;
 static unsigned int oom_kb = CMM_OOM_KB;
 static unsigned int cmm_debug = CMM_DEBUG;
 static unsigned int cmm_disabled = CMM_DISABLE;
@@ -65,6 +74,10 @@ MODULE_VERSION(CMM_DRIVER_VERSION);
 module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. "
                 "[Default=" __stringify(CMM_DEFAULT_DELAY) "]");
+module_param_named(hotplug_delay, hotplug_delay, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(delay, "Delay (in seconds) after memory hotplug remove "
+                "before loaning resumes. "
+                "[Default=" __stringify(CMM_HOTPLUG_DELAY) "]");
 module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. "
                 "[Default=" __stringify(CMM_OOM_KB) "]");
@@ -92,6 +105,9 @@ static unsigned long oom_freed_pages;
 static struct cmm_page_array *cmm_page_list;
 static DEFINE_SPINLOCK(cmm_lock);
 
+static DEFINE_MUTEX(hotplug_mutex);
+static int hotplug_occurred; /* protected by the hotplug mutex */
+
 static struct task_struct *cmm_thread_ptr;
 
 /**
@@ -110,6 +126,17 @@ static long cmm_alloc_pages(long nr)
        cmm_dbg("Begin request for %ld pages\n", nr);
 
        while (nr) {
+               /* Exit if a hotplug operation is in progress or occurred */
+               if (mutex_trylock(&hotplug_mutex)) {
+                       if (hotplug_occurred) {
+                               mutex_unlock(&hotplug_mutex);
+                               break;
+                       }
+                       mutex_unlock(&hotplug_mutex);
+               } else {
+                       break;
+               }
+
                addr = __get_free_page(GFP_NOIO | __GFP_NOWARN |
                                       __GFP_NORETRY | __GFP_NOMEMALLOC);
                if (!addr)
@@ -119,8 +146,9 @@ static long cmm_alloc_pages(long nr)
                if (!pa || pa->index >= CMM_NR_PAGES) {
                        /* Need a new page for the page list. */
                        spin_unlock(&cmm_lock);
-                       npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN |
-                                                                      __GFP_NORETRY | __GFP_NOMEMALLOC);
+                       npa = (struct cmm_page_array *)__get_free_page(
+                                       GFP_NOIO | __GFP_NOWARN |
+                                       __GFP_NORETRY | __GFP_NOMEMALLOC);
                        if (!npa) {
                                pr_info("%s: Can not allocate new page list\n", __func__);
                                free_page(addr);
@@ -282,9 +310,28 @@ static int cmm_thread(void *dummy)
        while (1) {
                timeleft = msleep_interruptible(delay * 1000);
 
-               if (kthread_should_stop() || timeleft) {
-                       loaned_pages_target = loaned_pages;
+               if (kthread_should_stop() || timeleft)
                        break;
+
+               if (mutex_trylock(&hotplug_mutex)) {
+                       if (hotplug_occurred) {
+                               hotplug_occurred = 0;
+                               mutex_unlock(&hotplug_mutex);
+                               cmm_dbg("Hotplug operation has occurred, "
+                                               "loaning activity suspended "
+                                               "for %d seconds.\n",
+                                               hotplug_delay);
+                               timeleft = msleep_interruptible(hotplug_delay *
+                                               1000);
+                               if (kthread_should_stop() || timeleft)
+                                       break;
+                               continue;
+                       }
+                       mutex_unlock(&hotplug_mutex);
+               } else {
+                       cmm_dbg("Hotplug operation in progress, activity "
+                                       "suspended\n");
+                       continue;
                }
 
                cmm_get_mpp();
@@ -414,6 +461,193 @@ static struct notifier_block cmm_reboot_nb = {
 };
 
 /**
+ * cmm_count_pages - Count the number of pages loaned in a particular range.
+ *
+ * @arg: memory_isolate_notify structure with address range and count
+ *
+ * Return value:
+ *      0 on success
+ **/
+static unsigned long cmm_count_pages(void *arg)
+{
+       struct memory_isolate_notify *marg = arg;
+       struct cmm_page_array *pa;
+       unsigned long start = (unsigned long)pfn_to_kaddr(marg->start_pfn);
+       unsigned long end = start + (marg->nr_pages << PAGE_SHIFT);
+       unsigned long idx;
+
+       spin_lock(&cmm_lock);
+       pa = cmm_page_list;
+       while (pa) {
+               if ((unsigned long)pa >= start && (unsigned long)pa < end)
+                       marg->pages_found++;
+               for (idx = 0; idx < pa->index; idx++)
+                       if (pa->page[idx] >= start && pa->page[idx] < end)
+                               marg->pages_found++;
+               pa = pa->next;
+       }
+       spin_unlock(&cmm_lock);
+       return 0;
+}
+
+/**
+ * cmm_memory_isolate_cb - Handle memory isolation notifier calls
+ * @self:      notifier block struct
+ * @action:    action to take
+ * @arg:       struct memory_isolate_notify data for handler
+ *
+ * Return value:
+ *     NOTIFY_OK or notifier error based on subfunction return value
+ **/
+static int cmm_memory_isolate_cb(struct notifier_block *self,
+                                unsigned long action, void *arg)
+{
+       int ret = 0;
+
+       if (action == MEM_ISOLATE_COUNT)
+               ret = cmm_count_pages(arg);
+
+       if (ret)
+               ret = notifier_from_errno(ret);
+       else
+               ret = NOTIFY_OK;
+
+       return ret;
+}
+
+static struct notifier_block cmm_mem_isolate_nb = {
+       .notifier_call = cmm_memory_isolate_cb,
+       .priority = CMM_MEM_ISOLATE_PRI
+};
+
+/**
+ * cmm_mem_going_offline - Unloan pages where memory is to be removed
+ * @arg: memory_notify structure with page range to be offlined
+ *
+ * Return value:
+ *     0 on success
+ **/
+static int cmm_mem_going_offline(void *arg)
+{
+       struct memory_notify *marg = arg;
+       unsigned long start_page = (unsigned long)pfn_to_kaddr(marg->start_pfn);
+       unsigned long end_page = start_page + (marg->nr_pages << PAGE_SHIFT);
+       struct cmm_page_array *pa_curr, *pa_last, *npa;
+       unsigned long idx;
+       unsigned long freed = 0;
+
+       cmm_dbg("Memory going offline, searching 0x%lx (%ld pages).\n",
+                       start_page, marg->nr_pages);
+       spin_lock(&cmm_lock);
+
+       /* Search the page list for pages in the range to be offlined */
+       pa_last = pa_curr = cmm_page_list;
+       while (pa_curr) {
+               for (idx = (pa_curr->index - 1); (idx + 1) > 0; idx--) {
+                       if ((pa_curr->page[idx] < start_page) ||
+                           (pa_curr->page[idx] >= end_page))
+                               continue;
+
+                       plpar_page_set_active(__pa(pa_curr->page[idx]));
+                       free_page(pa_curr->page[idx]);
+                       freed++;
+                       loaned_pages--;
+                       totalram_pages++;
+                       pa_curr->page[idx] = pa_last->page[--pa_last->index];
+                       if (pa_last->index == 0) {
+                               if (pa_curr == pa_last)
+                                       pa_curr = pa_last->next;
+                               pa_last = pa_last->next;
+                               free_page((unsigned long)cmm_page_list);
+                               cmm_page_list = pa_last;
+                               continue;
+                       }
+               }
+               pa_curr = pa_curr->next;
+       }
+
+       /* Search for page list structures in the range to be offlined */
+       pa_last = NULL;
+       pa_curr = cmm_page_list;
+       while (pa_curr) {
+               if (((unsigned long)pa_curr >= start_page) &&
+                               ((unsigned long)pa_curr < end_page)) {
+                       npa = (struct cmm_page_array *)__get_free_page(
+                                       GFP_NOIO | __GFP_NOWARN |
+                                       __GFP_NORETRY | __GFP_NOMEMALLOC);
+                       if (!npa) {
+                               spin_unlock(&cmm_lock);
+                               cmm_dbg("Failed to allocate memory for list "
+                                               "management. Memory hotplug "
+                                               "failed.\n");
+                               return ENOMEM;
+                       }
+                       memcpy(npa, pa_curr, PAGE_SIZE);
+                       if (pa_curr == cmm_page_list)
+                               cmm_page_list = npa;
+                       if (pa_last)
+                               pa_last->next = npa;
+                       free_page((unsigned long) pa_curr);
+                       freed++;
+                       pa_curr = npa;
+               }
+
+               pa_last = pa_curr;
+               pa_curr = pa_curr->next;
+       }
+
+       spin_unlock(&cmm_lock);
+       cmm_dbg("Released %ld pages in the search range.\n", freed);
+
+       return 0;
+}
+
+/**
+ * cmm_memory_cb - Handle memory hotplug notifier calls
+ * @self:      notifier block struct
+ * @action:    action to take
+ * @arg:       struct memory_notify data for handler
+ *
+ * Return value:
+ *     NOTIFY_OK or notifier error based on subfunction return value
+ *
+ **/
+static int cmm_memory_cb(struct notifier_block *self,
+                       unsigned long action, void *arg)
+{
+       int ret = 0;
+
+       switch (action) {
+       case MEM_GOING_OFFLINE:
+               mutex_lock(&hotplug_mutex);
+               hotplug_occurred = 1;
+               ret = cmm_mem_going_offline(arg);
+               break;
+       case MEM_OFFLINE:
+       case MEM_CANCEL_OFFLINE:
+               mutex_unlock(&hotplug_mutex);
+               cmm_dbg("Memory offline operation complete.\n");
+               break;
+       case MEM_GOING_ONLINE:
+       case MEM_ONLINE:
+       case MEM_CANCEL_ONLINE:
+               break;
+       }
+
+       if (ret)
+               ret = notifier_from_errno(ret);
+       else
+               ret = NOTIFY_OK;
+
+       return ret;
+}
+
+static struct notifier_block cmm_mem_nb = {
+       .notifier_call = cmm_memory_cb,
+       .priority = CMM_MEM_HOTPLUG_PRI
+};
+
+/**
  * cmm_init - Module initialization
  *
  * Return value:
@@ -435,18 +669,24 @@ static int cmm_init(void)
        if ((rc = cmm_sysfs_register(&cmm_sysdev)))
                goto out_reboot_notifier;
 
+       if (register_memory_notifier(&cmm_mem_nb) ||
+           register_memory_isolate_notifier(&cmm_mem_isolate_nb))
+               goto out_unregister_notifier;
+
        if (cmm_disabled)
                return rc;
 
        cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
        if (IS_ERR(cmm_thread_ptr)) {
                rc = PTR_ERR(cmm_thread_ptr);
-               goto out_unregister_sysfs;
+               goto out_unregister_notifier;
        }
 
        return rc;
 
-out_unregister_sysfs:
+out_unregister_notifier:
+       unregister_memory_notifier(&cmm_mem_nb);
+       unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
        cmm_unregister_sysfs(&cmm_sysdev);
 out_reboot_notifier:
        unregister_reboot_notifier(&cmm_reboot_nb);
@@ -467,6 +707,8 @@ static void cmm_exit(void)
                kthread_stop(cmm_thread_ptr);
        unregister_oom_notifier(&cmm_oom_nb);
        unregister_reboot_notifier(&cmm_reboot_nb);
+       unregister_memory_notifier(&cmm_mem_nb);
+       unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
        cmm_free_pages(loaned_pages);
        cmm_unregister_sysfs(&cmm_sysdev);
 }
index 12df9e8..67b7a10 100644 (file)
@@ -346,12 +346,14 @@ int dlpar_release_drc(u32 drc_index)
 
 static DEFINE_MUTEX(pseries_cpu_hotplug_mutex);
 
-void cpu_hotplug_driver_lock()
+void cpu_hotplug_driver_lock(void)
+__acquires(pseries_cpu_hotplug_mutex)
 {
        mutex_lock(&pseries_cpu_hotplug_mutex);
 }
 
-void cpu_hotplug_driver_unlock()
+void cpu_hotplug_driver_unlock(void)
+__releases(pseries_cpu_hotplug_mutex)
 {
        mutex_unlock(&pseries_cpu_hotplug_mutex);
 }
index 8868c01..b488663 100644 (file)
@@ -144,8 +144,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr)
                hcpuid = get_hard_smp_processor_id(nr);
                rc = plpar_hcall_norets(H_PROD, hcpuid);
                if (rc != H_SUCCESS)
-                       panic("Error: Prod to wake up processor %d Ret= %ld\n",
-                               nr, rc);
+                       printk(KERN_ERR "Error: Prod to wake up processor %d\
+                                               Ret= %ld\n", nr, rc);
        }
 }
 
index 971483f..1709ac5 100644 (file)
@@ -143,13 +143,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
        struct irq_desc *desc = irq_to_desc(virq);
        unsigned int vold, vnew, edibit;
 
-       if (flow_type == IRQ_TYPE_NONE)
-               flow_type = IRQ_TYPE_LEVEL_LOW;
-
-       if (flow_type & IRQ_TYPE_EDGE_RISING) {
-               printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n",
-                       flow_type);
-               return -EINVAL;
+       /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
+        * IRQ_TYPE_EDGE_BOTH (default).  All others are IRQ_TYPE_EDGE_FALLING
+        * or IRQ_TYPE_LEVEL_LOW (default)
+        */
+       if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) {
+               if (flow_type == IRQ_TYPE_NONE)
+                       flow_type = IRQ_TYPE_EDGE_BOTH;
+
+               if (flow_type != IRQ_TYPE_EDGE_BOTH &&
+                   flow_type != IRQ_TYPE_EDGE_FALLING)
+                       goto err_sense;
+       } else {
+               if (flow_type == IRQ_TYPE_NONE)
+                       flow_type = IRQ_TYPE_LEVEL_LOW;
+
+               if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
+                       goto err_sense;
        }
 
        desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
@@ -181,6 +191,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
        if (vold != vnew)
                out_be32(&cpm2_intctl->ic_siexr, vnew);
        return 0;
+
+err_sense:
+       pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
+       return -EINVAL;
 }
 
 static struct irq_chip cpm2_pic = {
index 4e3a3e3..e1a028c 100644 (file)
@@ -464,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
 {
        struct pci_controller *hose = pci_bus_to_host(bus);
        struct mpc83xx_pcie_priv *pcie = hose->dn->data;
-       u8 bus_no = bus->number - hose->first_busno;
-       u32 dev_base = bus_no << 24 | devfn << 16;
+       u32 dev_base = bus->number << 24 | devfn << 16;
        int ret;
 
        ret = mpc83xx_pcie_exclude_device(bus, devfn);
@@ -515,12 +514,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
 static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
+       struct pci_controller *hose = pci_bus_to_host(bus);
        void __iomem *cfg_addr;
 
        cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
        if (!cfg_addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
+       /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
+       if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
+               val &= 0xffffff00;
+
        switch (len) {
        case 1:
                out_8(cfg_addr, val);
index 103eace..ee1c0e1 100644 (file)
@@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
        mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
 }
 
+/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
+ * defined as output cannot be determined by reading GPDAT register,
+ * so we use shadow data register instead. The status of input pins
+ * is determined by reading GPDAT register.
+ */
+static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+       u32 val;
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+       val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
+
+       return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
+}
+
 static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
        struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
@@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        gc->ngpio = MPC8XXX_GPIO_PINS;
        gc->direction_input = mpc8xxx_gpio_dir_in;
        gc->direction_output = mpc8xxx_gpio_dir_out;
-       gc->get = mpc8xxx_gpio_get;
+       if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
+               gc->get = mpc8572_gpio_get;
+       else
+               gc->get = mpc8xxx_gpio_get;
        gc->set = mpc8xxx_gpio_set;
 
        ret = of_mm_gpiochip_add(np, mm_gc);
index aa9d06e..470dc6c 100644 (file)
@@ -567,13 +567,11 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
 #endif /* CONFIG_MPIC_U3_HT_IRQS */
 
 #ifdef CONFIG_SMP
-static int irq_choose_cpu(unsigned int virt_irq)
+static int irq_choose_cpu(const cpumask_t *mask)
 {
-       cpumask_t mask;
        int cpuid;
 
-       cpumask_copy(&mask, irq_to_desc(virt_irq)->affinity);
-       if (cpus_equal(mask, CPU_MASK_ALL)) {
+       if (cpumask_equal(mask, cpu_all_mask)) {
                static int irq_rover;
                static DEFINE_SPINLOCK(irq_rover_lock);
                unsigned long flags;
@@ -594,20 +592,15 @@ static int irq_choose_cpu(unsigned int virt_irq)
 
                spin_unlock_irqrestore(&irq_rover_lock, flags);
        } else {
-               cpumask_t tmp;
-
-               cpus_and(tmp, cpu_online_map, mask);
-
-               if (cpus_empty(tmp))
+               cpuid = cpumask_first_and(mask, cpu_online_mask);
+               if (cpuid >= nr_cpu_ids)
                        goto do_round_robin;
-
-               cpuid = first_cpu(tmp);
        }
 
        return get_hard_smp_processor_id(cpuid);
 }
 #else
-static int irq_choose_cpu(unsigned int virt_irq)
+static int irq_choose_cpu(const cpumask_t *mask)
 {
        return hard_smp_processor_id();
 }
@@ -816,7 +809,7 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
        unsigned int src = mpic_irq_to_hw(irq);
 
        if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
-               int cpuid = irq_choose_cpu(irq);
+               int cpuid = irq_choose_cpu(cpumask);
 
                mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
        } else {
index 1d44eee..0f67cd7 100644 (file)
@@ -39,7 +39,12 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
 
        pr_debug("mpic: found U3, guessing msi allocator setup\n");
 
-       /* Reserve source numbers we know are reserved in the HW */
+       /* Reserve source numbers we know are reserved in the HW.
+        *
+        * This is a bit of a mix of U3 and U4 reserves but that's going
+        * to work fine, we have plenty enugh numbers left so let's just
+        * mark anything we don't like reserved.
+        */
        for (i = 0;   i < 8;   i++)
                msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
 
@@ -49,6 +54,10 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
        for (i = 100; i < 105; i++)
                msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
 
+       for (i = 124; i < mpic->irq_count; i++)
+               msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
+
+
        np = NULL;
        while ((np = of_find_all_nodes(np))) {
                pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
index d3caf23..bcbfe79 100644 (file)
@@ -64,12 +64,12 @@ static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
        return addr;
 }
 
-static u64 find_ht_magic_addr(struct pci_dev *pdev)
+static u64 find_ht_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
 {
        struct pci_bus *bus;
        unsigned int pos;
 
-       for (bus = pdev->bus; bus; bus = bus->parent) {
+       for (bus = pdev->bus; bus && bus->self; bus = bus->parent) {
                pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING);
                if (pos)
                        return read_ht_magic_addr(bus->self, pos);
@@ -78,13 +78,41 @@ static u64 find_ht_magic_addr(struct pci_dev *pdev)
        return 0;
 }
 
+static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
+{
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+
+       /* U4 PCIe MSIs need to write to the special register in
+        * the bridge that generates interrupts. There should be
+        * theorically a register at 0xf8005000 where you just write
+        * the MSI number and that triggers the right interrupt, but
+        * unfortunately, this is busted in HW, the bridge endian swaps
+        * the value and hits the wrong nibble in the register.
+        *
+        * So instead we use another register set which is used normally
+        * for converting HT interrupts to MPIC interrupts, which decodes
+        * the interrupt number as part of the low address bits
+        *
+        * This will not work if we ever use more than one legacy MSI in
+        * a block but we never do. For one MSI or multiple MSI-X where
+        * each interrupt address can be specified separately, it works
+        * just fine.
+        */
+       if (of_device_is_compatible(hose->dn, "u4-pcie") ||
+           of_device_is_compatible(hose->dn, "U4-pcie"))
+               return 0xf8004000 | (hwirq << 4);
+
+       return 0;
+}
+
 static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
 {
        if (type == PCI_CAP_ID_MSIX)
                pr_debug("u3msi: MSI-X untested, trying anyway.\n");
 
        /* If we can't find a magic address then MSI ain't gonna work */
-       if (find_ht_magic_addr(pdev) == 0) {
+       if (find_ht_magic_addr(pdev, 0) == 0 &&
+           find_u4_magic_addr(pdev, 0) == 0) {
                pr_debug("u3msi: no magic address found for %s\n",
                         pci_name(pdev));
                return -ENXIO;
@@ -118,10 +146,6 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
        u64 addr;
        int hwirq;
 
-       addr = find_ht_magic_addr(pdev);
-       msg.address_lo = addr & 0xFFFFFFFF;
-       msg.address_hi = addr >> 32;
-
        list_for_each_entry(entry, &pdev->msi_list, list) {
                hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
                if (hwirq < 0) {
@@ -129,6 +153,12 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                        return hwirq;
                }
 
+               addr = find_ht_magic_addr(pdev, hwirq);
+               if (addr == 0)
+                       addr = find_u4_magic_addr(pdev, hwirq);
+               msg.address_lo = addr & 0xFFFFFFFF;
+               msg.address_hi = addr >> 32;
+
                virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
                if (virq == NO_IRQ) {
                        pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq);
@@ -143,6 +173,8 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
                          virq, hwirq, (unsigned long)addr);
 
+               printk("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
+                         virq, hwirq, (unsigned long)addr);
                msg.data = hwirq;
                write_msi_msg(virq, &msg);
 
index 6118890..6be4503 100644 (file)
@@ -174,7 +174,7 @@ static int fallback_init_cip(struct crypto_tfm *tfm)
        if (IS_ERR(sctx->fallback.cip)) {
                pr_err("Allocating AES fallback algorithm %s failed\n",
                       name);
-               return PTR_ERR(sctx->fallback.blk);
+               return PTR_ERR(sctx->fallback.cip);
        }
 
        return 0;
index 77df726..2b92d50 100644 (file)
@@ -164,7 +164,7 @@ static inline void part_hdr__part_name(enum diag204_format type, void *hdr,
                       LPAR_NAME_LEN);
        EBCASC(name, LPAR_NAME_LEN);
        name[LPAR_NAME_LEN] = 0;
-       strstrip(name);
+       strim(name);
 }
 
 struct cpu_info {
@@ -523,7 +523,7 @@ static int diag224_idx2name(int index, char *name)
        memcpy(name, diag224_cpu_names + ((index + 1) * CPU_NAME_LEN),
                CPU_NAME_LEN);
        name[CPU_NAME_LEN] = 0;
-       strstrip(name);
+       strim(name);
        return 0;
 }
 
index d01fc8f..f0b0d31 100644 (file)
@@ -124,7 +124,7 @@ static int hpyfs_vm_create_guest(struct super_block *sb,
        /* guest dir */
        memcpy(guest_name, data->guest_name, NAME_LEN);
        EBCASC(guest_name, NAME_LEN);
-       strstrip(guest_name);
+       strim(guest_name);
        guest_dir = hypfs_mkdir(sb, systems_dir, guest_name);
        if (IS_ERR(guest_dir))
                return PTR_ERR(guest_dir);
index cb5232d..192a720 100644 (file)
 #define        __NR_pwritev            329
 #define __NR_rt_tgsigqueueinfo 330
 #define __NR_perf_event_open   331
-#define NR_syscalls 332
+#define __NR_recvmmsg          332
+#define NR_syscalls 333
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 30de2d0..faeaccc 100644 (file)
@@ -1853,3 +1853,12 @@ sys32_execve_wrapper:
        llgtr   %r3,%r3                 # compat_uptr_t *
        llgtr   %r4,%r4                 # compat_uptr_t *
        jg      sys32_execve            # branch to system call
+
+       .globl  compat_sys_recvmmsg_wrapper
+compat_sys_recvmmsg_wrapper:
+       lgfr    %r2,%r2                 # int
+       llgtr   %r3,%r3                 # struct compat_mmsghdr *
+       llgfr   %r4,%r4                 # unsigned int
+       llgfr   %r5,%r5                 # unsigned int
+       llgtr   %r6,%r6                 # struct compat_timespec *
+       jg      compat_sys_recvmmsg
index 4890ac6..4d73296 100644 (file)
@@ -221,7 +221,7 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,        \
                const char *buf, size_t len)                            \
 {                                                                      \
        strncpy(_value, buf, sizeof(_value) - 1);                       \
-       strstrip(_value);                                               \
+       strim(_value);                                                  \
        return len;                                                     \
 }                                                                      \
 static struct kobj_attribute sys_##_prefix##_##_name##_attr =          \
@@ -472,7 +472,7 @@ static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
                return sprintf(page, "#unknown#\n");
        memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
        EBCASC(loadparm, LOADPARM_LEN);
-       strstrip(loadparm);
+       strim(loadparm);
        return sprintf(page, "%s\n", loadparm);
 }
 
@@ -776,7 +776,7 @@ static void reipl_get_ascii_loadparm(char *loadparm,
        memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN);
        EBCASC(loadparm, LOADPARM_LEN);
        loadparm[LOADPARM_LEN] = 0;
-       strstrip(loadparm);
+       strim(loadparm);
 }
 
 static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb,
index 653c6a1..13815d3 100644 (file)
@@ -959,7 +959,7 @@ static const struct user_regset s390_compat_regsets[] = {
                .set = s390_fpregs_set,
        },
        [REGSET_GENERAL_EXTENDED] = {
-               .core_note_type = NT_PRXSTATUS,
+               .core_note_type = NT_S390_HIGH_GPRS,
                .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
                .size = sizeof(compat_long_t),
                .align = sizeof(compat_long_t),
index 30eca07..4f292c9 100644 (file)
@@ -340,3 +340,4 @@ SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
 SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
 SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */
 SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper)
+SYSCALL(sys_recvmmsg,sys_recvmmsg,compat_sys_recvmmsg_wrapper)
index c2e42cc..6e7ad63 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -382,7 +382,7 @@ void __kprobes do_single_step(struct pt_regs *regs)
                                        SIGTRAP) == NOTIFY_STOP){
                return;
        }
-       if ((current->ptrace & PT_PTRACED) != 0)
+       if (tracehook_consider_fatal_signal(current, SIGTRAP))
                force_sig(SIGTRAP, current);
 }
 
@@ -483,7 +483,7 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
                if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
                        return;
                if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
-                       if (current->ptrace & PT_PTRACED)
+                       if (tracehook_consider_fatal_signal(current, SIGTRAP))
                                force_sig(SIGTRAP, current);
                        else
                                signal = SIGILL;
index 3b2a5ac..55298e8 100644 (file)
@@ -50,6 +50,8 @@ config X86
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_LZMA
        select HAVE_HW_BREAKPOINT
+       select PERF_EVENTS
+       select ANON_INODES
        select HAVE_ARCH_KMEMCHECK
        select HAVE_USER_RETURN_NOTIFIER
 
index 613700f..637e1ec 100644 (file)
 #define X86_FEATURE_SSE5       (6*32+11) /* SSE-5 */
 #define X86_FEATURE_SKINIT     (6*32+12) /* SKINIT/STGI instructions */
 #define X86_FEATURE_WDT                (6*32+13) /* Watchdog timer */
+#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */
 
 /*
  * Auxiliary flags: Linux defined - For features scattered in various
index 08c48a8..eeac829 100644 (file)
@@ -103,7 +103,8 @@ extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
 extern void send_cleanup_vector(struct irq_cfg *);
 
 struct irq_desc;
-extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *);
+extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *,
+                                     unsigned int *dest_id);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
 extern void setup_ioapic_dest(void);
 
index 4ffe09b..1cd58cd 100644 (file)
@@ -12,6 +12,7 @@
 #define MSR_FS_BASE            0xc0000100 /* 64bit FS base */
 #define MSR_GS_BASE            0xc0000101 /* 64bit GS base */
 #define MSR_KERNEL_GS_BASE     0xc0000102 /* SwapGS GS shadow */
+#define MSR_TSC_AUX            0xc0000103 /* Auxiliary TSC */
 
 /* EFER bits: */
 #define _EFER_SCE              0  /* SYSCALL/SYSRET */
 #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
 #define FAM10H_MMIO_CONF_BASE_MASK     0xfffffff
 #define FAM10H_MMIO_CONF_BASE_SHIFT    20
+#define MSR_FAM10H_NODE_ID             0xc001100c
 
 /* K8 MSRs */
 #define MSR_K8_TOP_MEM1                        0xc001001a
index 2d228fc..c5bc4c2 100644 (file)
@@ -27,6 +27,18 @@ struct msr {
        };
 };
 
+struct msr_info {
+       u32 msr_no;
+       struct msr reg;
+       struct msr *msrs;
+       int err;
+};
+
+struct msr_regs_info {
+       u32 *regs;
+       int err;
+};
+
 static inline unsigned long long native_read_tscp(unsigned int *aux)
 {
        unsigned long low, high;
@@ -240,9 +252,9 @@ do {                                                            \
 #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val),                \
                                             (u32)((val) >> 32))
 
-#define write_tsc(val1, val2) wrmsr(0x10, (val1), (val2))
+#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
 
-#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
+#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
 
 struct msr *msrs_alloc(void);
 void msrs_free(struct msr *msrs);
index 6f8ec1c..fc801ba 100644 (file)
@@ -181,7 +181,7 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
                                unsigned int *ecx, unsigned int *edx)
 {
        /* ecx is often an input as well as an output. */
-       asm("cpuid"
+       asm volatile("cpuid"
            : "=a" (*eax),
              "=b" (*ebx),
              "=c" (*ecx),
index cf86a5e..35e8912 100644 (file)
@@ -5,6 +5,29 @@ extern int kstack_depth_to_print;
 
 int x86_is_stack_id(int id, char *name);
 
+struct thread_info;
+struct stacktrace_ops;
+
+typedef unsigned long (*walk_stack_t)(struct thread_info *tinfo,
+                                     unsigned long *stack,
+                                     unsigned long bp,
+                                     const struct stacktrace_ops *ops,
+                                     void *data,
+                                     unsigned long *end,
+                                     int *graph);
+
+extern unsigned long
+print_context_stack(struct thread_info *tinfo,
+                   unsigned long *stack, unsigned long bp,
+                   const struct stacktrace_ops *ops, void *data,
+                   unsigned long *end, int *graph);
+
+extern unsigned long
+print_context_stack_bp(struct thread_info *tinfo,
+                      unsigned long *stack, unsigned long bp,
+                      const struct stacktrace_ops *ops, void *data,
+                      unsigned long *end, int *graph);
+
 /* Generic stack tracer with callbacks */
 
 struct stacktrace_ops {
@@ -14,6 +37,7 @@ struct stacktrace_ops {
        void (*address)(void *data, unsigned long address, int reliable);
        /* On negative return stop dumping */
        int (*stack)(void *data, char *name);
+       walk_stack_t    walk_stack;
 };
 
 void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
index d0c99ab..eacbd2b 100644 (file)
@@ -306,10 +306,7 @@ physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                if (cpumask_test_cpu(cpu, cpu_online_mask))
                        break;
        }
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 struct apic apic_physflat =  {
index 38dcecf..cb804c5 100644 (file)
@@ -131,10 +131,7 @@ static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                if (cpumask_test_cpu(cpu, cpu_online_mask))
                        break;
        }
-       if (cpu < nr_cpu_ids)
-               return bigsmp_cpu_to_logical_apicid(cpu);
-
-       return BAD_APICID;
+       return bigsmp_cpu_to_logical_apicid(cpu);
 }
 
 static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
index 11a5851..de00c46 100644 (file)
@@ -2276,26 +2276,28 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
 
 /*
  * Either sets desc->affinity to a valid value, and returns
- * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
+ * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
  * leaves desc->affinity untouched.
  */
 unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
+set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask,
+                 unsigned int *dest_id)
 {
        struct irq_cfg *cfg;
        unsigned int irq;
 
        if (!cpumask_intersects(mask, cpu_online_mask))
-               return BAD_APICID;
+               return -1;
 
        irq = desc->irq;
        cfg = desc->chip_data;
        if (assign_irq_vector(irq, cfg, mask))
-               return BAD_APICID;
+               return -1;
 
        cpumask_copy(desc->affinity, mask);
 
-       return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+       *dest_id = apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+       return 0;
 }
 
 static int
@@ -2311,12 +2313,11 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
        cfg = desc->chip_data;
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       dest = set_desc_affinity(desc, mask);
-       if (dest != BAD_APICID) {
+       ret = set_desc_affinity(desc, mask, &dest);
+       if (!ret) {
                /* Only the high 8 bits are valid. */
                dest = SET_APIC_LOGICAL_ID(dest);
                __target_IO_APIC_irq(irq, dest, cfg);
-               ret = 0;
        }
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -3351,8 +3352,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
        struct msi_msg msg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
@@ -3384,8 +3384,7 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
        if (get_irte(irq, &irte))
                return -1;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        irte.vector = cfg->vector;
@@ -3567,8 +3566,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
        struct msi_msg msg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
@@ -3623,8 +3621,7 @@ static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
        struct msi_msg msg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
@@ -3730,8 +3727,7 @@ static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
        struct irq_cfg *cfg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
index a5371ec..cf69c59 100644 (file)
@@ -148,10 +148,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                        break;
        }
 
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_logical_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_logical_apicid, cpu);
 }
 
 static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x)
index a8989aa..8972f38 100644 (file)
@@ -146,10 +146,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                        break;
        }
 
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 static unsigned int x2apic_phys_get_apic_id(unsigned long x)
index b684bb3..d56b0ef 100644 (file)
@@ -225,10 +225,7 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                if (cpumask_test_cpu(cpu, cpu_online_mask))
                        break;
        }
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 static unsigned int x2apic_get_apic_id(unsigned long x)
index 8dc3ea1..e485825 100644 (file)
@@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int apicid)
 
 /*
  * Fixup core topology information for AMD multi-node processors.
- * Assumption 1: Number of cores in each internal node is the same.
- * Assumption 2: Mixed systems with both single-node and dual-node
- *               processors are not supported.
+ * Assumption: Number of cores in each internal node is the same.
  */
 #ifdef CONFIG_X86_HT
 static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
 {
-#ifdef CONFIG_PCI
-       u32 t, cpn;
-       u8 n, n_id;
+       unsigned long long value;
+       u32 nodes, cores_per_node;
        int cpu = smp_processor_id();
 
+       if (!cpu_has(c, X86_FEATURE_NODEID_MSR))
+               return;
+
        /* fixup topology information only once for a core */
        if (cpu_has(c, X86_FEATURE_AMD_DCM))
                return;
 
-       /* check for multi-node processor on boot cpu */
-       t = read_pci_config(0, 24, 3, 0xe8);
-       if (!(t & (1 << 29)))
+       rdmsrl(MSR_FAM10H_NODE_ID, value);
+
+       nodes = ((value >> 3) & 7) + 1;
+       if (nodes == 1)
                return;
 
        set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+       cores_per_node = c->x86_max_cores / nodes;
 
-       /* cores per node: each internal node has half the number of cores */
-       cpn = c->x86_max_cores >> 1;
+       /* store NodeID, use llc_shared_map to store sibling info */
+       per_cpu(cpu_llc_id, cpu) = value & 7;
 
-       /* even-numbered NB_id of this dual-node processor */
-       n = c->phys_proc_id << 1;
-
-       /*
-        * determine internal node id and assign cores fifty-fifty to
-        * each node of the dual-node processor
-        */
-       t = read_pci_config(0, 24 + n, 3, 0xe8);
-       n = (t>>30) & 0x3;
-       if (n == 0) {
-               if (c->cpu_core_id < cpn)
-                       n_id = 0;
-               else
-                       n_id = 1;
-       } else {
-               if (c->cpu_core_id < cpn)
-                       n_id = 1;
-               else
-                       n_id = 0;
-       }
-
-       /* compute entire NodeID, use llc_shared_map to store sibling info */
-       per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;
-
-       /* fixup core id to be in range from 0 to cpn */
-       c->cpu_core_id = c->cpu_core_id % cpn;
-#endif
+       /* fixup core id to be in range from 0 to (cores_per_node - 1) */
+       c->cpu_core_id = c->cpu_core_id % cores_per_node;
 }
 #endif
 
index 9c31e8b..879666f 100644 (file)
@@ -70,7 +70,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
        if (c->x86_power & (1 << 8)) {
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
                set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-               set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
                sched_clock_stable = 1;
        }
 
index 45506d5..c223b7e 100644 (file)
@@ -2336,6 +2336,7 @@ static const struct stacktrace_ops backtrace_ops = {
        .warning_symbol         = backtrace_warning_symbol,
        .stack                  = backtrace_stack,
        .address                = backtrace_address,
+       .walk_stack             = print_context_stack_bp,
 };
 
 #include "../dumpstack.h"
index 7ef24a7..cb27fd6 100644 (file)
@@ -187,7 +187,8 @@ static int __init cpuid_init(void)
        int i, err = 0;
        i = 0;
 
-       if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
+       if (__register_chrdev(CPUID_MAJOR, 0, NR_CPUS,
+                             "cpu/cpuid", &cpuid_fops)) {
                printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
                       CPUID_MAJOR);
                err = -EBUSY;
@@ -216,7 +217,7 @@ out_class:
        }
        class_destroy(cpuid_class);
 out_chrdev:
-       unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+       __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
 out:
        return err;
 }
index 0a0aa1c..c56bc28 100644 (file)
@@ -109,6 +109,30 @@ print_context_stack(struct thread_info *tinfo,
        }
        return bp;
 }
+EXPORT_SYMBOL_GPL(print_context_stack);
+
+unsigned long
+print_context_stack_bp(struct thread_info *tinfo,
+                      unsigned long *stack, unsigned long bp,
+                      const struct stacktrace_ops *ops, void *data,
+                      unsigned long *end, int *graph)
+{
+       struct stack_frame *frame = (struct stack_frame *)bp;
+       unsigned long *ret_addr = &frame->return_address;
+
+       while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
+               unsigned long addr = *ret_addr;
+
+               if (__kernel_text_address(addr)) {
+                       ops->address(data, addr, 1);
+                       frame = frame->next_frame;
+                       ret_addr = &frame->return_address;
+                       print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
+               }
+       }
+       return (unsigned long)frame;
+}
+EXPORT_SYMBOL_GPL(print_context_stack_bp);
 
 
 static void
@@ -141,10 +165,11 @@ static void print_trace_address(void *data, unsigned long addr, int reliable)
 }
 
 static const struct stacktrace_ops print_trace_ops = {
-       .warning = print_trace_warning,
-       .warning_symbol = print_trace_warning_symbol,
-       .stack = print_trace_stack,
-       .address = print_trace_address,
+       .warning                = print_trace_warning,
+       .warning_symbol         = print_trace_warning_symbol,
+       .stack                  = print_trace_stack,
+       .address                = print_trace_address,
+       .walk_stack             = print_context_stack,
 };
 
 void
index 81086c2..4fd1420 100644 (file)
 #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
 #endif
 
-extern unsigned long
-print_context_stack(struct thread_info *tinfo,
-               unsigned long *stack, unsigned long bp,
-               const struct stacktrace_ops *ops, void *data,
-               unsigned long *end, int *graph);
-
 extern void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp, char *log_lvl);
index e0ed4c7..ae775ca 100644 (file)
@@ -58,7 +58,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 
                context = (struct thread_info *)
                        ((unsigned long)stack & (~(THREAD_SIZE - 1)));
-               bp = print_context_stack(context, stack, bp, ops, data, NULL, &graph);
+               bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
 
                stack = (unsigned long *)context->previous_esp;
                if (!stack)
index b13af53..0ad9597 100644 (file)
@@ -188,8 +188,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
                        if (ops->stack(data, id) < 0)
                                break;
 
-                       bp = print_context_stack(tinfo, stack, bp, ops,
-                                                data, estack_end, &graph);
+                       bp = ops->walk_stack(tinfo, stack, bp, ops,
+                                            data, estack_end, &graph);
                        ops->stack(data, "<EOE>");
                        /*
                         * We link to the next stack via the
index f50447d..05ed7ab 100644 (file)
@@ -724,7 +724,7 @@ core_initcall(e820_mark_nvs_memory);
 /*
  * Early reserved memory areas.
  */
-#define MAX_EARLY_RES 20
+#define MAX_EARLY_RES 32
 
 struct early_res {
        u64 start, end;
index 844c02c..0c86324 100644 (file)
@@ -394,7 +394,7 @@ static enum ucode_state microcode_update_cpu(int cpu)
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
        enum ucode_state ustate;
 
-       if (uci->valid && uci->mc)
+       if (uci->valid)
                ustate = microcode_resume_cpu(cpu);
        else
                ustate = microcode_init_cpu(cpu);
index 572b07e..4bd93c9 100644 (file)
@@ -246,7 +246,7 @@ static int __init msr_init(void)
        int i, err = 0;
        i = 0;
 
-       if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
+       if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
                printk(KERN_ERR "msr: unable to get major %d for msr\n",
                       MSR_MAJOR);
                err = -EBUSY;
@@ -274,7 +274,7 @@ out_class:
                msr_device_destroy(i);
        class_destroy(msr_class);
 out_chrdev:
-       unregister_chrdev(MSR_MAJOR, "cpu/msr");
+       __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
 out:
        return err;
 }
index c3eb207..922eefb 100644 (file)
@@ -53,17 +53,19 @@ save_stack_address_nosched(void *data, unsigned long addr, int reliable)
 }
 
 static const struct stacktrace_ops save_stack_ops = {
-       .warning = save_stack_warning,
-       .warning_symbol = save_stack_warning_symbol,
-       .stack = save_stack_stack,
-       .address = save_stack_address,
+       .warning        = save_stack_warning,
+       .warning_symbol = save_stack_warning_symbol,
+       .stack          = save_stack_stack,
+       .address        = save_stack_address,
+       .walk_stack     = print_context_stack,
 };
 
 static const struct stacktrace_ops save_stack_ops_nosched = {
-       .warning = save_stack_warning,
-       .warning_symbol = save_stack_warning_symbol,
-       .stack = save_stack_stack,
-       .address = save_stack_address_nosched,
+       .warning        = save_stack_warning,
+       .warning_symbol = save_stack_warning_symbol,
+       .stack          = save_stack_stack,
+       .address        = save_stack_address_nosched,
+       .walk_stack     = print_context_stack,
 };
 
 /*
index cd982f4..597683a 100644 (file)
@@ -763,6 +763,7 @@ void mark_tsc_unstable(char *reason)
 {
        if (!tsc_unstable) {
                tsc_unstable = 1;
+               sched_clock_stable = 0;
                printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
                /* Change only the rating, when not registered */
                if (clocksource_tsc.mult)
index 61d805d..ece73d8 100644 (file)
@@ -215,8 +215,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
        unsigned long mmr_offset;
        unsigned mmr_pnode;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        mmr_value = 0;
index 45b20e4..cffd754 100644 (file)
@@ -14,7 +14,7 @@ $(obj)/inat.o: $(obj)/inat-tables.c
 
 clean-files := inat-tables.c
 
-obj-$(CONFIG_SMP) := msr.o
+obj-$(CONFIG_SMP) += msr-smp.o
 
 lib-y := delay.o
 lib-y += thunk_$(BITS).o
@@ -22,7 +22,7 @@ lib-y += usercopy_$(BITS).o getuser.o putuser.o
 lib-y += memcpy_$(BITS).o
 lib-$(CONFIG_KPROBES) += insn.o inat.o
 
-obj-y += msr-reg.o msr-reg-export.o
+obj-y += msr.o msr-reg.o msr-reg-export.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c
new file mode 100644 (file)
index 0000000..a6b1b86
--- /dev/null
@@ -0,0 +1,204 @@
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/smp.h>
+#include <asm/msr.h>
+
+static void __rdmsr_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+       struct msr *reg;
+       int this_cpu = raw_smp_processor_id();
+
+       if (rv->msrs)
+               reg = per_cpu_ptr(rv->msrs, this_cpu);
+       else
+               reg = &rv->reg;
+
+       rdmsr(rv->msr_no, reg->l, reg->h);
+}
+
+static void __wrmsr_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+       struct msr *reg;
+       int this_cpu = raw_smp_processor_id();
+
+       if (rv->msrs)
+               reg = per_cpu_ptr(rv->msrs, this_cpu);
+       else
+               reg = &rv->reg;
+
+       wrmsr(rv->msr_no, reg->l, reg->h);
+}
+
+int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
+       *l = rv.reg.l;
+       *h = rv.reg.h;
+
+       return err;
+}
+EXPORT_SYMBOL(rdmsr_on_cpu);
+
+int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       rv.reg.l = l;
+       rv.reg.h = h;
+       err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
+
+       return err;
+}
+EXPORT_SYMBOL(wrmsr_on_cpu);
+
+static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
+                           struct msr *msrs,
+                           void (*msr_func) (void *info))
+{
+       struct msr_info rv;
+       int this_cpu;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msrs   = msrs;
+       rv.msr_no = msr_no;
+
+       this_cpu = get_cpu();
+
+       if (cpumask_test_cpu(this_cpu, mask))
+               msr_func(&rv);
+
+       smp_call_function_many(mask, msr_func, &rv, 1);
+       put_cpu();
+}
+
+/* rdmsr on a bunch of CPUs
+ *
+ * @mask:       which CPUs
+ * @msr_no:     which MSR
+ * @msrs:       array of MSR values
+ *
+ */
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+{
+       __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
+}
+EXPORT_SYMBOL(rdmsr_on_cpus);
+
+/*
+ * wrmsr on a bunch of CPUs
+ *
+ * @mask:       which CPUs
+ * @msr_no:     which MSR
+ * @msrs:       array of MSR values
+ *
+ */
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+{
+       __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
+}
+EXPORT_SYMBOL(wrmsr_on_cpus);
+
+/* These "safe" variants are slower and should be used when the target MSR
+   may not actually exist. */
+static void __rdmsr_safe_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+
+       rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
+}
+
+static void __wrmsr_safe_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+
+       rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
+}
+
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
+       *l = rv.reg.l;
+       *h = rv.reg.h;
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(rdmsr_safe_on_cpu);
+
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       rv.reg.l = l;
+       rv.reg.h = h;
+       err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(wrmsr_safe_on_cpu);
+
+/*
+ * These variants are significantly slower, but allows control over
+ * the entire 32-bit GPR set.
+ */
+static void __rdmsr_safe_regs_on_cpu(void *info)
+{
+       struct msr_regs_info *rv = info;
+
+       rv->err = rdmsr_safe_regs(rv->regs);
+}
+
+static void __wrmsr_safe_regs_on_cpu(void *info)
+{
+       struct msr_regs_info *rv = info;
+
+       rv->err = wrmsr_safe_regs(rv->regs);
+}
+
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+       int err;
+       struct msr_regs_info rv;
+
+       rv.regs   = regs;
+       rv.err    = -EIO;
+       err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
+
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+       int err;
+       struct msr_regs_info rv;
+
+       rv.regs = regs;
+       rv.err  = -EIO;
+       err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
index 8728341..8f8eebd 100644 (file)
@@ -1,123 +1,7 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
-#include <linux/smp.h>
 #include <asm/msr.h>
 
-struct msr_info {
-       u32 msr_no;
-       struct msr reg;
-       struct msr *msrs;
-       int err;
-};
-
-static void __rdmsr_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-       struct msr *reg;
-       int this_cpu = raw_smp_processor_id();
-
-       if (rv->msrs)
-               reg = per_cpu_ptr(rv->msrs, this_cpu);
-       else
-               reg = &rv->reg;
-
-       rdmsr(rv->msr_no, reg->l, reg->h);
-}
-
-static void __wrmsr_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-       struct msr *reg;
-       int this_cpu = raw_smp_processor_id();
-
-       if (rv->msrs)
-               reg = per_cpu_ptr(rv->msrs, this_cpu);
-       else
-               reg = &rv->reg;
-
-       wrmsr(rv->msr_no, reg->l, reg->h);
-}
-
-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
-       *l = rv.reg.l;
-       *h = rv.reg.h;
-
-       return err;
-}
-EXPORT_SYMBOL(rdmsr_on_cpu);
-
-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       rv.reg.l = l;
-       rv.reg.h = h;
-       err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
-
-       return err;
-}
-EXPORT_SYMBOL(wrmsr_on_cpu);
-
-static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
-                           struct msr *msrs,
-                           void (*msr_func) (void *info))
-{
-       struct msr_info rv;
-       int this_cpu;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msrs   = msrs;
-       rv.msr_no = msr_no;
-
-       this_cpu = get_cpu();
-
-       if (cpumask_test_cpu(this_cpu, mask))
-               msr_func(&rv);
-
-       smp_call_function_many(mask, msr_func, &rv, 1);
-       put_cpu();
-}
-
-/* rdmsr on a bunch of CPUs
- *
- * @mask:       which CPUs
- * @msr_no:     which MSR
- * @msrs:       array of MSR values
- *
- */
-void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
-{
-       __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
-}
-EXPORT_SYMBOL(rdmsr_on_cpus);
-
-/*
- * wrmsr on a bunch of CPUs
- *
- * @mask:       which CPUs
- * @msr_no:     which MSR
- * @msrs:       array of MSR values
- *
- */
-void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
-{
-       __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
-}
-EXPORT_SYMBOL(wrmsr_on_cpus);
-
 struct msr *msrs_alloc(void)
 {
        struct msr *msrs = NULL;
@@ -137,100 +21,3 @@ void msrs_free(struct msr *msrs)
        free_percpu(msrs);
 }
 EXPORT_SYMBOL(msrs_free);
-
-/* These "safe" variants are slower and should be used when the target MSR
-   may not actually exist. */
-static void __rdmsr_safe_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-
-       rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
-}
-
-static void __wrmsr_safe_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-
-       rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
-}
-
-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
-       *l = rv.reg.l;
-       *h = rv.reg.h;
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(rdmsr_safe_on_cpu);
-
-int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       rv.reg.l = l;
-       rv.reg.h = h;
-       err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(wrmsr_safe_on_cpu);
-
-/*
- * These variants are significantly slower, but allows control over
- * the entire 32-bit GPR set.
- */
-struct msr_regs_info {
-       u32 *regs;
-       int err;
-};
-
-static void __rdmsr_safe_regs_on_cpu(void *info)
-{
-       struct msr_regs_info *rv = info;
-
-       rv->err = rdmsr_safe_regs(rv->regs);
-}
-
-static void __wrmsr_safe_regs_on_cpu(void *info)
-{
-       struct msr_regs_info *rv = info;
-
-       rv->err = wrmsr_safe_regs(rv->regs);
-}
-
-int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
-{
-       int err;
-       struct msr_regs_info rv;
-
-       rv.regs   = regs;
-       rv.err    = -EIO;
-       err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
-
-int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
-{
-       int err;
-       struct msr_regs_info rv;
-
-       rv.regs = regs;
-       rv.err  = -EIO;
-       err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
index 6f8aa33..9324f13 100644 (file)
@@ -267,6 +267,8 @@ int __init get_memcfg_from_srat(void)
                e820_register_active_regions(chunk->nid, chunk->start_pfn,
                                             min(chunk->end_pfn, max_pfn));
        }
+       /* for out of order entries in SRAT */
+       sort_node_map();
 
        for_each_online_node(nid) {
                unsigned long start = node_start_pfn[nid];
index d890754..a271241 100644 (file)
@@ -317,7 +317,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
                unsigned long s = nodes[i].start >> PAGE_SHIFT;
                unsigned long e = nodes[i].end >> PAGE_SHIFT;
                pxmram += e - s;
-               pxmram -= absent_pages_in_range(s, e);
+               pxmram -= __absent_pages_in_range(i, s, e);
                if ((long)pxmram < 0)
                        pxmram = 0;
        }
@@ -373,6 +373,8 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
        for_each_node_mask(i, nodes_parsed)
                e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
                                                nodes[i].end >> PAGE_SHIFT);
+       /* for out of order entries in SRAT */
+       sort_node_map();
        if (!nodes_cover_memory(nodes)) {
                bad_srat();
                return -1;
index 044897b..3855096 100644 (file)
@@ -41,10 +41,11 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
 }
 
 static struct stacktrace_ops backtrace_ops = {
-       .warning = backtrace_warning,
-       .warning_symbol = backtrace_warning_symbol,
-       .stack = backtrace_stack,
-       .address = backtrace_address,
+       .warning        = backtrace_warning,
+       .warning_symbol = backtrace_warning_symbol,
+       .stack          = backtrace_stack,
+       .address        = backtrace_address,
+       .walk_stack     = print_context_stack,
 };
 
 struct frame_head {
index 0d13cd9..5bbb5a3 100644 (file)
@@ -9,7 +9,7 @@ BEGIN {
 }
 
 /^GNU/ {
-       split($4, ver, ".");
+       split($3, ver, ".");
        if (ver[1] > od_ver ||
            (ver[1] == od_ver && ver[2] >= od_sver)) {
                exit 1;
index 7a68506..eaf11f5 100644 (file)
@@ -6,8 +6,6 @@
 
 # Awk implementation sanity check
 function check_awk_implement() {
-       if (!match("abc", "[[:lower:]]+"))
-               return "Your awk doesn't support charactor-class."
        if (sprintf("%x", 0) != "0")
                return "Your awk has a printf-format problem."
        return ""
@@ -44,12 +42,12 @@ BEGIN {
        delete gtable
        delete atable
 
-       opnd_expr = "^[[:alpha:]/]"
+       opnd_expr = "^[A-Za-z/]"
        ext_expr = "^\\("
        sep_expr = "^\\|$"
-       group_expr = "^Grp[[:alnum:]]+"
+       group_expr = "^Grp[0-9A-Za-z]+"
 
-       imm_expr = "^[IJAO][[:lower:]]"
+       imm_expr = "^[IJAO][a-z]"
        imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
        imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
        imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
@@ -62,7 +60,7 @@ BEGIN {
        imm_flag["Ob"] = "INAT_MOFFSET"
        imm_flag["Ov"] = "INAT_MOFFSET"
 
-       modrm_expr = "^([CDEGMNPQRSUVW/][[:lower:]]+|NTA|T[012])"
+       modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
        force64_expr = "\\([df]64\\)"
        rex_expr = "^REX(\\.[XRWB]+)*"
        fpu_expr = "^ESC" # TODO
index 23e5a05..2815df6 100644 (file)
@@ -185,6 +185,12 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
        acpi_osi_setup("!Windows 2006");
        return 0;
 }
+static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
+{
+       printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+       acpi_osi_setup("!Windows 2009");
+       return 0;
+}
 
 static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
        {
@@ -211,6 +217,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"),
                },
        },
+       {
+       .callback = dmi_disable_osi_win7,
+       .ident = "ASUS K50IJ",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
+               },
+       },
 
        /*
         * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
index 0bdf24a..cf761b9 100644 (file)
@@ -397,6 +397,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
        union acpi_object *out_obj;
        u8 uuid[16];
        u32 errors;
+       struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
 
        if (!context)
                return AE_ERROR;
@@ -419,16 +420,16 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
        in_params[3].buffer.length      = context->cap.length;
        in_params[3].buffer.pointer     = context->cap.pointer;
 
-       status = acpi_evaluate_object(handle, "_OSC", &input, &context->ret);
+       status = acpi_evaluate_object(handle, "_OSC", &input, &output);
        if (ACPI_FAILURE(status))
                return status;
 
-       /* return buffer should have the same length as cap buffer */
-       if (context->ret.length != context->cap.length)
+       if (!output.length)
                return AE_NULL_OBJECT;
 
-       out_obj = context->ret.pointer;
-       if (out_obj->type != ACPI_TYPE_BUFFER) {
+       out_obj = output.pointer;
+       if (out_obj->type != ACPI_TYPE_BUFFER
+               || out_obj->buffer.length != context->cap.length) {
                acpi_print_osc_error(handle, context,
                        "_OSC evaluation returned wrong type");
                status = AE_TYPE;
@@ -457,11 +458,20 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
                goto out_kfree;
        }
 out_success:
-       return AE_OK;
+       context->ret.length = out_obj->buffer.length;
+       context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL);
+       if (!context->ret.pointer) {
+               status =  AE_NO_MEMORY;
+               goto out_kfree;
+       }
+       memcpy(context->ret.pointer, out_obj->buffer.pointer,
+               context->ret.length);
+       status =  AE_OK;
 
 out_kfree:
-       kfree(context->ret.pointer);
-       context->ret.pointer = NULL;
+       kfree(output.pointer);
+       if (status != AE_OK)
+               context->ret.pointer = NULL;
        return status;
 }
 EXPORT_SYMBOL(acpi_run_osc);
index 75b147f..fd1801b 100644 (file)
@@ -916,6 +916,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id)
 /* MSI EC needs special treatment, enable it */
 static int ec_flag_msi(const struct dmi_system_id *id)
 {
+       printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n");
        EC_FLAGS_MSI = 1;
        EC_FLAGS_VALIDATE_ECDT = 1;
        return 0;
@@ -928,8 +929,13 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
        DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL},
        {
        ec_flag_msi, "MSI hardware", {
-       DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"),
-       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL},
+       DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star")}, NULL},
+       {
+       ec_flag_msi, "MSI hardware", {
+       DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star")}, NULL},
+       {
+       ec_flag_msi, "MSI hardware", {
+       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
        {
        ec_validate_ecdt, "ASUS hardware", {
        DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
index 1683ebd..f4ea5a8 100644 (file)
@@ -3022,7 +3022,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
        case WRITE_16:
                return ata_scsi_rw_xlat;
 
-       case 0x93 /*WRITE_SAME_16*/:
+       case WRITE_SAME_16:
                return ata_scsi_write_same_xlat;
 
        case SYNCHRONIZE_CACHE:
index efa8773..741065c 100644 (file)
@@ -2275,7 +2275,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
        ap = qc->ap;
        /* Drain up to 64K of data before we give up this recovery method */
        for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
-                                               && count < 32768; count++)
+                                               && count < 65536; count += 2)
                ioread16(ap->ioaddr.data_addr);
 
        /* Can become DEBUG later */
index c4b47a3..02c81f1 100644 (file)
@@ -1557,6 +1557,25 @@ static unsigned short atapi_io_port[] = {
        P_ATAPI_DMARQ,
        P_ATAPI_INTRQ,
        P_ATAPI_IORDY,
+       P_ATAPI_D0A,
+       P_ATAPI_D1A,
+       P_ATAPI_D2A,
+       P_ATAPI_D3A,
+       P_ATAPI_D4A,
+       P_ATAPI_D5A,
+       P_ATAPI_D6A,
+       P_ATAPI_D7A,
+       P_ATAPI_D8A,
+       P_ATAPI_D9A,
+       P_ATAPI_D10A,
+       P_ATAPI_D11A,
+       P_ATAPI_D12A,
+       P_ATAPI_D13A,
+       P_ATAPI_D14A,
+       P_ATAPI_D15A,
+       P_ATAPI_A0A,
+       P_ATAPI_A1A,
+       P_ATAPI_A2A,
        0
 };
 
index dadfc35..0efb1f5 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_cmd64x"
-#define DRV_VERSION "0.3.1"
+#define DRV_VERSION "0.2.5"
 
 /*
  * CMD64x specific registers definition.
@@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
                regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
                /* Merge the control bits */
                regU |= 1 << adev->devno; /* UDMA on */
-               if (adev->dma_mode > 2) /* 15nS timing */
+               if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */
                        regU |= 4 << adev->devno;
        } else {
                regU &= ~ (1 << adev->devno);   /* UDMA off */
@@ -254,109 +254,17 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
 }
 
 /**
- *     cmd64x_bmdma_stop       -       DMA stop callback
+ *     cmd646r1_dma_stop       -       DMA stop callback
  *     @qc: Command in progress
  *
- *     Track the completion of live DMA commands and clear the
- *     host->private_data DMA tracking flag as we do.
+ *     Stub for now while investigating the r1 quirk in the old driver.
  */
 
-static void cmd64x_bmdma_stop(struct ata_queued_cmd *qc)
+static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc)
 {
-       struct ata_port *ap = qc->ap;
        ata_bmdma_stop(qc);
-       WARN_ON(ap->host->private_data != ap);
-       ap->host->private_data = NULL;
-}
-
-/**
- *     cmd64x_qc_defer         -       Defer logic for chip limits
- *     @qc: queued command
- *
- *     Decide whether we can issue the command. Called under the host lock.
- */
-
-static int cmd64x_qc_defer(struct ata_queued_cmd *qc)
-{
-       struct ata_host *host = qc->ap->host;
-       struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
-       int rc;
-       int dma = 0;
-
-       /* Apply the ATA rules first */
-       rc = ata_std_qc_defer(qc);
-       if (rc)
-               return rc;
-
-       if (qc->tf.protocol == ATAPI_PROT_DMA ||
-                       qc->tf.protocol == ATA_PROT_DMA)
-               dma = 1;
-
-       /* If the other port is not live then issue the command */
-       if (alt == NULL || !alt->qc_active) {
-               if (dma)
-                       host->private_data = qc->ap;
-               return 0;
-       }
-       /* If there is a live DMA command then wait */
-       if (host->private_data != NULL)
-               return  ATA_DEFER_PORT;
-       if (dma)
-               /* Cannot overlap our DMA command */
-               return ATA_DEFER_PORT;
-       return 0;
 }
 
-/**
- *     cmd64x_interrupt - ATA host interrupt handler
- *     @irq: irq line (unused)
- *     @dev_instance: pointer to our ata_host information structure
- *
- *     Our interrupt handler for PCI IDE devices.  Calls
- *     ata_sff_host_intr() for each port that is flagging an IRQ. We cannot
- *     use the defaults as we need to avoid touching status/altstatus during
- *     a DMA.
- *
- *     LOCKING:
- *     Obtains host lock during operation.
- *
- *     RETURNS:
- *     IRQ_NONE or IRQ_HANDLED.
- */
-irqreturn_t cmd64x_interrupt(int irq, void *dev_instance)
-{
-       struct ata_host *host = dev_instance;
-       struct pci_dev *pdev = to_pci_dev(host->dev);
-       unsigned int i;
-       unsigned int handled = 0;
-       unsigned long flags;
-       static const u8 irq_reg[2] = { CFR, ARTTIM23 };
-       static const u8 irq_mask[2] = { 1 << 2, 1 << 4 };
-
-       /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
-       spin_lock_irqsave(&host->lock, flags);
-
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap;
-               u8 reg;
-
-               pci_read_config_byte(pdev, irq_reg[i], &reg);
-               ap = host->ports[i];
-               if (ap && (reg & irq_mask[i]) &&
-                   !(ap->flags & ATA_FLAG_DISABLED)) {
-                       struct ata_queued_cmd *qc;
-
-                       qc = ata_qc_from_tag(ap, ap->link.active_tag);
-                       if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
-                           (qc->flags & ATA_QCFLAG_ACTIVE))
-                               handled |= ata_sff_host_intr(ap, qc);
-               }
-       }
-
-       spin_unlock_irqrestore(&host->lock, flags);
-
-       return IRQ_RETVAL(handled);
-}
 static struct scsi_host_template cmd64x_sht = {
        ATA_BMDMA_SHT(DRV_NAME),
 };
@@ -365,8 +273,6 @@ static const struct ata_port_operations cmd64x_base_ops = {
        .inherits       = &ata_bmdma_port_ops,
        .set_piomode    = cmd64x_set_piomode,
        .set_dmamode    = cmd64x_set_dmamode,
-       .bmdma_stop     = cmd64x_bmdma_stop,
-       .qc_defer       = cmd64x_qc_defer,
 };
 
 static struct ata_port_operations cmd64x_port_ops = {
@@ -376,6 +282,7 @@ static struct ata_port_operations cmd64x_port_ops = {
 
 static struct ata_port_operations cmd646r1_port_ops = {
        .inherits       = &cmd64x_base_ops,
+       .bmdma_stop     = cmd646r1_bmdma_stop,
        .cable_detect   = ata_cable_40wire,
 };
 
@@ -383,7 +290,6 @@ static struct ata_port_operations cmd648_port_ops = {
        .inherits       = &cmd64x_base_ops,
        .bmdma_stop     = cmd648_bmdma_stop,
        .cable_detect   = cmd648_cable_detect,
-       .qc_defer       = ata_std_qc_defer
 };
 
 static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -432,7 +338,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
        u8 mrdmode;
        int rc;
-       struct ata_host *host;
 
        rc = pcim_enable_device(pdev);
        if (rc)
@@ -450,25 +355,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        ppi[0] = &cmd_info[3];
        }
 
-
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
        pci_read_config_byte(pdev, MRDMODE, &mrdmode);
        mrdmode &= ~ 0x30;      /* IRQ set up */
        mrdmode |= 0x02;        /* Memory read line enable */
        pci_write_config_byte(pdev, MRDMODE, mrdmode);
 
+       /* Force PIO 0 here.. */
+
        /* PPC specific fixup copied from old driver */
 #ifdef CONFIG_PPC
        pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
 #endif
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
-       if (rc)
-               return rc;
-       /* We use this pointer to track the AP which has DMA running */
-       host->private_data = NULL;
 
-       pci_set_master(pdev);
-       return ata_pci_sff_activate_host(host, cmd64x_interrupt, &cmd64x_sht);
+       return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL);
 }
 
 #ifdef CONFIG_PM
index 9a09a1b..dd26bc7 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
- * Portions Copyright (C) 2005-2007    MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2009    MontaVista Software, Inc.
  *
  *
  * TODO
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt3x2n"
-#define DRV_VERSION    "0.3.7"
+#define DRV_VERSION    "0.3.8"
 
 enum {
        HPT_PCI_FAST    =       (1 << 31),
@@ -264,7 +264,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
 
 static void hpt3x2n_set_clock(struct ata_port *ap, int source)
 {
-       void __iomem *bmdma = ap->ioaddr.bmdma_addr;
+       void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8;
 
        /* Tristate the bus */
        iowrite8(0x80, bmdma+0x73);
@@ -274,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
        iowrite8(source, bmdma+0x7B);
        iowrite8(0xC0, bmdma+0x79);
 
-       /* Reset state machines */
-       iowrite8(0x37, bmdma+0x70);
-       iowrite8(0x37, bmdma+0x74);
+       /* Reset state machines, avoid enabling the disabled channels */
+       iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70);
+       iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74);
 
        /* Complete reset */
        iowrite8(0x00, bmdma+0x79);
@@ -286,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
        iowrite8(0x00, bmdma+0x77);
 }
 
-/* Check if our partner interface is busy */
-
-static int hpt3x2n_pair_idle(struct ata_port *ap)
-{
-       struct ata_host *host = ap->host;
-       struct ata_port *pair = host->ports[ap->port_no ^ 1];
-
-       if (pair->hsm_task_state == HSM_ST_IDLE)
-               return 1;
-       return 0;
-}
-
 static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
 {
        long flags = (long)ap->host->private_data;
+
        /* See if we should use the DPLL */
        if (writing)
                return USE_DPLL;        /* Needed for write */
@@ -309,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
        return 0;
 }
 
+static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_port *alt = ap->host->ports[ap->port_no ^ 1];
+       int rc, flags = (long)ap->host->private_data;
+       int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
+
+       /* First apply the usual rules */
+       rc = ata_std_qc_defer(qc);
+       if (rc != 0)
+               return rc;
+
+       if ((flags & USE_DPLL) != dpll && alt->qc_active)
+               return ATA_DEFER_PORT;
+       return 0;
+}
+
 static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
 {
-       struct ata_taskfile *tf = &qc->tf;
        struct ata_port *ap = qc->ap;
        int flags = (long)ap->host->private_data;
+       int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
 
-       if (hpt3x2n_pair_idle(ap)) {
-               int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE));
-               if ((flags & USE_DPLL) != dpll) {
-                       if (dpll == 1)
-                               hpt3x2n_set_clock(ap, 0x21);
-                       else
-                               hpt3x2n_set_clock(ap, 0x23);
-               }
+       if ((flags & USE_DPLL) != dpll) {
+               flags &= ~USE_DPLL;
+               flags |= dpll;
+               ap->host->private_data = (void *)(long)flags;
+
+               hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23);
        }
        return ata_sff_qc_issue(qc);
 }
@@ -339,6 +343,8 @@ static struct ata_port_operations hpt3x2n_port_ops = {
        .inherits       = &ata_bmdma_port_ops,
 
        .bmdma_stop     = hpt3x2n_bmdma_stop,
+
+       .qc_defer       = hpt3x2n_qc_defer,
        .qc_issue       = hpt3x2n_qc_issue,
 
        .cable_detect   = hpt3x2n_cable_detect,
@@ -454,7 +460,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        unsigned int f_low, f_high;
        int adjust;
        unsigned long iobase = pci_resource_start(dev, 4);
-       void *hpriv = NULL;
+       void *hpriv = (void *)USE_DPLL;
        int rc;
 
        rc = pcim_enable_device(dev);
@@ -539,7 +545,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* Set our private data up. We only need a few flags so we use
           it directly */
        if (pci_mhz > 60) {
-               hpriv = (void *)PCI66;
+               hpriv = (void *)(PCI66 | USE_DPLL);
                /*
                 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
                 * the MISC. register to stretch the UltraDMA Tss timing.
index d6f6956..37ef416 100644 (file)
@@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev)
                        return -EINVAL;
 
                cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
-                                          res_cs0->end - res_cs1->start + 1);
+                                          resource_size(res_cs1));
 
                if (!cs1)
                        return -ENOMEM;
index a8a7be0..df8ee32 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/dmapool.h>
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
+#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
@@ -538,6 +539,7 @@ struct mv_port_signal {
 
 struct mv_host_priv {
        u32                     hp_flags;
+       unsigned int            board_idx;
        u32                     main_irq_mask;
        struct mv_port_signal   signal[8];
        const struct mv_hw_ops  *ops;
@@ -548,6 +550,10 @@ struct mv_host_priv {
        u32                     irq_cause_offset;
        u32                     irq_mask_offset;
        u32                     unmask_all_irqs;
+
+#if defined(CONFIG_HAVE_CLK)
+       struct clk              *clk;
+#endif
        /*
         * These consistent DMA memory pools give us guaranteed
         * alignment for hardware-accessed data structures,
@@ -2775,7 +2781,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause)
        struct mv_port_priv *pp;
        int edma_was_enabled;
 
-       if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+       if (ap->flags & ATA_FLAG_DISABLED) {
                mv_unexpected_intr(ap, 0);
                return;
        }
@@ -3393,7 +3399,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
        ZERO(0x024);            /* respq outp */
        ZERO(0x020);            /* respq inp */
        ZERO(0x02c);            /* test control */
-       writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+       writel(0x800, port_mmio + EDMA_IORDY_TMOUT);
 }
 
 #undef ZERO
@@ -3854,7 +3860,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 /**
  *      mv_init_host - Perform some early initialization of the host.
  *     @host: ATA host to initialize
- *      @board_idx: controller index
  *
  *      If possible, do an early global reset of the host.  Then do
  *      our port init and clear/unmask all/relevant host interrupts.
@@ -3862,13 +3867,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_init_host(struct ata_host *host, unsigned int board_idx)
+static int mv_init_host(struct ata_host *host)
 {
        int rc = 0, n_hc, port, hc;
        struct mv_host_priv *hpriv = host->private_data;
        void __iomem *mmio = hpriv->base;
 
-       rc = mv_chip_id(host, board_idx);
+       rc = mv_chip_id(host, hpriv->board_idx);
        if (rc)
                goto done;
 
@@ -3905,14 +3910,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
                void __iomem *port_mmio = mv_port_base(mmio, port);
 
                mv_port_init(&ap->ioaddr, port_mmio);
-
-#ifdef CONFIG_PCI
-               if (!IS_SOC(hpriv)) {
-                       unsigned int offset = port_mmio - mmio;
-                       ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
-                       ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
-               }
-#endif
        }
 
        for (hc = 0; hc < n_hc; hc++) {
@@ -4035,12 +4032,21 @@ static int mv_platform_probe(struct platform_device *pdev)
                return -ENOMEM;
        host->private_data = hpriv;
        hpriv->n_ports = n_ports;
+       hpriv->board_idx = chip_soc;
 
        host->iomap = NULL;
        hpriv->base = devm_ioremap(&pdev->dev, res->start,
                                   resource_size(res));
        hpriv->base -= SATAHC0_REG_BASE;
 
+#if defined(CONFIG_HAVE_CLK)
+       hpriv->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(hpriv->clk))
+               dev_notice(&pdev->dev, "cannot get clkdev\n");
+       else
+               clk_enable(hpriv->clk);
+#endif
+
        /*
         * (Re-)program MBUS remapping windows if we are asked to.
         */
@@ -4049,12 +4055,12 @@ static int mv_platform_probe(struct platform_device *pdev)
 
        rc = mv_create_dma_pools(hpriv, &pdev->dev);
        if (rc)
-               return rc;
+               goto err;
 
        /* initialize adapter */
-       rc = mv_init_host(host, chip_soc);
+       rc = mv_init_host(host);
        if (rc)
-               return rc;
+               goto err;
 
        dev_printk(KERN_INFO, &pdev->dev,
                   "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH,
@@ -4062,6 +4068,15 @@ static int mv_platform_probe(struct platform_device *pdev)
 
        return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt,
                                 IRQF_SHARED, &mv6_sht);
+err:
+#if defined(CONFIG_HAVE_CLK)
+       if (!IS_ERR(hpriv->clk)) {
+               clk_disable(hpriv->clk);
+               clk_put(hpriv->clk);
+       }
+#endif
+
+       return rc;
 }
 
 /*
@@ -4076,14 +4091,66 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct ata_host *host = dev_get_drvdata(dev);
-
+#if defined(CONFIG_HAVE_CLK)
+       struct mv_host_priv *hpriv = host->private_data;
+#endif
        ata_host_detach(host);
+
+#if defined(CONFIG_HAVE_CLK)
+       if (!IS_ERR(hpriv->clk)) {
+               clk_disable(hpriv->clk);
+               clk_put(hpriv->clk);
+       }
+#endif
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       if (host)
+               return ata_host_suspend(host, state);
+       else
+               return 0;
+}
+
+static int mv_platform_resume(struct platform_device *pdev)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       int ret;
+
+       if (host) {
+               struct mv_host_priv *hpriv = host->private_data;
+               const struct mv_sata_platform_data *mv_platform_data = \
+                       pdev->dev.platform_data;
+               /*
+                * (Re-)program MBUS remapping windows if we are asked to.
+                */
+               if (mv_platform_data->dram != NULL)
+                       mv_conf_mbus_windows(hpriv, mv_platform_data->dram);
+
+               /* initialize adapter */
+               ret = mv_init_host(host);
+               if (ret) {
+                       printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+                       return ret;
+               }
+               ata_host_resume(host);
+       }
+
+       return 0;
+}
+#else
+#define mv_platform_suspend NULL
+#define mv_platform_resume NULL
+#endif
+
 static struct platform_driver mv_platform_driver = {
        .probe                  = mv_platform_probe,
        .remove                 = __devexit_p(mv_platform_remove),
+       .suspend                = mv_platform_suspend,
+       .resume                 = mv_platform_resume,
        .driver                 = {
                                   .name = DRV_NAME,
                                   .owner = THIS_MODULE,
@@ -4094,6 +4161,9 @@ static struct platform_driver mv_platform_driver = {
 #ifdef CONFIG_PCI
 static int mv_pci_init_one(struct pci_dev *pdev,
                           const struct pci_device_id *ent);
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev);
+#endif
 
 
 static struct pci_driver mv_pci_driver = {
@@ -4101,6 +4171,11 @@ static struct pci_driver mv_pci_driver = {
        .id_table               = mv_pci_tbl,
        .probe                  = mv_pci_init_one,
        .remove                 = ata_pci_remove_one,
+#ifdef CONFIG_PM
+       .suspend                = ata_pci_device_suspend,
+       .resume                 = mv_pci_device_resume,
+#endif
+
 };
 
 /* move to PCI layer or libata core? */
@@ -4194,7 +4269,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
        struct ata_host *host;
        struct mv_host_priv *hpriv;
-       int n_ports, rc;
+       int n_ports, port, rc;
 
        if (!printed_version++)
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -4208,6 +4283,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
                return -ENOMEM;
        host->private_data = hpriv;
        hpriv->n_ports = n_ports;
+       hpriv->board_idx = board_idx;
 
        /* acquire resources */
        rc = pcim_enable_device(pdev);
@@ -4230,8 +4306,17 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        if (rc)
                return rc;
 
+       for (port = 0; port < host->n_ports; port++) {
+               struct ata_port *ap = host->ports[port];
+               void __iomem *port_mmio = mv_port_base(hpriv->base, port);
+               unsigned int offset = port_mmio - hpriv->base;
+
+               ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
+               ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
+       }
+
        /* initialize adapter */
-       rc = mv_init_host(host, board_idx);
+       rc = mv_init_host(host);
        if (rc)
                return rc;
 
@@ -4247,6 +4332,27 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
                                 IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }
+
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       int rc;
+
+       rc = ata_pci_device_do_resume(pdev);
+       if (rc)
+               return rc;
+
+       /* initialize adapter */
+       rc = mv_init_host(host);
+       if (rc)
+               return rc;
+
+       ata_host_resume(host);
+
+       return 0;
+}
+#endif
 #endif
 
 static int mv_platform_probe(struct platform_device *pdev);
index 63c143e..c0c5a43 100644 (file)
@@ -703,9 +703,9 @@ int bus_add_driver(struct device_driver *drv)
        return 0;
 
 out_unregister:
+       kobject_put(&priv->kobj);
        kfree(drv->p);
        drv->p = NULL;
-       kobject_put(&priv->kobj);
 out_put_bus:
        bus_put(bus);
        return error;
index f1290cb..2820257 100644 (file)
@@ -446,7 +446,8 @@ struct kset *devices_kset;
  * @dev: device.
  * @attr: device attribute descriptor.
  */
-int device_create_file(struct device *dev, struct device_attribute *attr)
+int device_create_file(struct device *dev,
+                      const struct device_attribute *attr)
 {
        int error = 0;
        if (dev)
@@ -459,7 +460,8 @@ int device_create_file(struct device *dev, struct device_attribute *attr)
  * @dev: device.
  * @attr: device attribute descriptor.
  */
-void device_remove_file(struct device *dev, struct device_attribute *attr)
+void device_remove_file(struct device *dev,
+                       const struct device_attribute *attr)
 {
        if (dev)
                sysfs_remove_file(&dev->kobj, &attr->attr);
@@ -470,7 +472,8 @@ void device_remove_file(struct device *dev, struct device_attribute *attr)
  * @dev: device.
  * @attr: device binary attribute descriptor.
  */
-int device_create_bin_file(struct device *dev, struct bin_attribute *attr)
+int device_create_bin_file(struct device *dev,
+                          const struct bin_attribute *attr)
 {
        int error = -EINVAL;
        if (dev)
@@ -484,7 +487,8 @@ EXPORT_SYMBOL_GPL(device_create_bin_file);
  * @dev: device.
  * @attr: device binary attribute descriptor.
  */
-void device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
+void device_remove_bin_file(struct device *dev,
+                           const struct bin_attribute *attr)
 {
        if (dev)
                sysfs_remove_bin_file(&dev->kobj, attr);
@@ -905,8 +909,10 @@ int device_add(struct device *dev)
                dev->init_name = NULL;
        }
 
-       if (!dev_name(dev))
+       if (!dev_name(dev)) {
+               error = -EINVAL;
                goto name_error;
+       }
 
        pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
 
index 50375bb..090dd48 100644 (file)
@@ -32,7 +32,7 @@ static int dev_mount = 1;
 static int dev_mount;
 #endif
 
-static rwlock_t dirlock;
+static DEFINE_MUTEX(dirlock);
 
 static int __init mount_param(char *str)
 {
@@ -93,7 +93,7 @@ static int create_path(const char *nodepath)
 {
        int err;