Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/acme...
Ingo Molnar [Sun, 15 May 2011 17:41:00 +0000 (19:41 +0200)]
420 files changed:
Documentation/DocBook/media-entities.tmpl
Documentation/DocBook/v4l/media-ioc-setup-link.xml
Documentation/DocBook/v4l/pixfmt-y12.xml [new file with mode: 0644]
Documentation/DocBook/v4l/pixfmt.xml
Documentation/DocBook/v4l/subdev-formats.xml
Documentation/cgroups/memory.txt
Documentation/flexible-arrays.txt
Documentation/hwmon/adm1021
Documentation/hwmon/lm90
Documentation/sound/alsa/SB-Live-mixer.txt
Documentation/video4linux/sh_mobile_ceu_camera.txt
Documentation/workqueue.txt
MAINTAINERS
Makefile
arch/arm/configs/at91x40_defconfig [new file with mode: 0644]
arch/arm/include/asm/kprobes.h
arch/arm/kernel/kprobes-decode.c
arch/arm/kernel/kprobes.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/ptrace.c
arch/arm/kernel/smp.c
arch/arm/kernel/sys_oabi-compat.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/board-eb01.c
arch/arm/mach-at91/include/mach/cpu.h
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/board-mityomapl138.c
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/include/mach/debug-macro.S
arch/arm/mach-davinci/include/mach/serial.h
arch/arm/mach-mx3/mach-vpr200.c
arch/arm/mach-mx5/board-mx53_loco.c
arch/arm/mach-mxs/clock-mx28.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/cm2xxx_3xxx.c
arch/arm/mach-omap2/control.c
arch/arm/mach-omap2/omap_hwmod_2420_data.c
arch/arm/mach-omap2/omap_hwmod_2430_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_l3_smx.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/voltage.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-s3c2440/mach-gta02.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mm/proc-xscale.S
arch/arm/plat-mxc/gpio.c
arch/arm/plat-mxc/ssi-fiq.S
arch/m68k/mm/motorola.c
arch/parisc/mm/init.c
arch/powerpc/include/asm/8xx_immap.h
arch/powerpc/include/asm/uninorth.h
arch/powerpc/kernel/ptrace.c
arch/s390/crypto/prng.c
arch/s390/kvm/sie64a.S
arch/s390/mm/fault.c
arch/s390/mm/pageattr.c
arch/sh/kernel/ptrace_32.c
arch/um/Kconfig.um
arch/um/include/asm/thread_info.h
arch/um/sys-i386/Makefile
arch/um/sys-i386/atomic64_cx8_32.S [new file with mode: 0644]
arch/x86/boot/memory.c
arch/x86/include/asm/io_apic.h
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_p4.c
arch/x86/kernel/devicetree.c
arch/x86/kernel/kprobes.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/reboot_32.S
arch/x86/mm/numa_64.c
arch/x86/platform/ce4100/falconfalls.dts
arch/x86/xen/mmu.c
arch/xtensa/kernel/irq.c
drivers/acpi/scan.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ata_piix.c
drivers/ata/libahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_at91.c
drivers/base/power/main.c
drivers/base/power/wakeup.c
drivers/base/syscore.c
drivers/block/rbd.c
drivers/clk/clkdev.c
drivers/edac/amd64_edac.c
drivers/edac/amd64_edac.h
drivers/edac/edac_mc_sysfs.c
drivers/firewire/ohci.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_atpx_handler.c
drivers/gpu/drm/radeon/radeon_cursor.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/reg_srcs/r600
drivers/hwmon/Kconfig
drivers/hwmon/lm85.c
drivers/hwmon/lm90.c
drivers/hwmon/twl4030-madc-hwmon.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-parport.c
drivers/infiniband/hw/qib/qib_iba6120.c
drivers/infiniband/hw/qib/qib_iba7220.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/input/touchscreen/wm831x-ts.c
drivers/media/common/tuners/tda18271-common.c
drivers/media/common/tuners/tda18271-fe.c
drivers/media/common/tuners/tda18271-maps.c
drivers/media/dvb/b2c2/flexcop-pci.c
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/dib0700_devices.c
drivers/media/dvb/ngene/ngene-core.c
drivers/media/media-entity.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/saa7706h.c
drivers/media/radio/tef6862.c
drivers/media/rc/imon.c
drivers/media/rc/ite-cir.c
drivers/media/rc/mceusb.c
drivers/media/rc/rc-main.c
drivers/media/video/Kconfig
drivers/media/video/cx18/cx18-streams.c
drivers/media/video/cx23885/Kconfig
drivers/media/video/imx074.c
drivers/media/video/m52790.c
drivers/media/video/omap3isp/isp.c
drivers/media/video/omap3isp/isp.h
drivers/media/video/omap3isp/ispccdc.c
drivers/media/video/omap3isp/isppreview.c
drivers/media/video/omap3isp/ispqueue.c
drivers/media/video/omap3isp/ispresizer.c
drivers/media/video/omap3isp/ispstat.h
drivers/media/video/omap3isp/ispvideo.c
drivers/media/video/omap3isp/ispvideo.h
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/s5p-fimc/fimc-core.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/sh_mobile_csi2.c
drivers/media/video/soc_camera.c
drivers/media/video/tda9840.c
drivers/media/video/tea6415c.c
drivers/media/video/tea6420.c
drivers/media/video/upd64031a.c
drivers/media/video/upd64083.c
drivers/media/video/v4l2-dev.c
drivers/media/video/videobuf2-core.c
drivers/media/video/videobuf2-dma-contig.c
drivers/mfd/omap-usb-host.c
drivers/mmc/core/bus.c
drivers/mmc/core/host.c
drivers/mmc/host/omap.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/tmio_mmc_pio.c
drivers/mtd/nand/diskonchip.c
drivers/net/amd8111e.c
drivers/net/atl1c/atl1c.h
drivers/net/atl1c/atl1c_main.c
drivers/net/benet/be_main.c
drivers/net/bnx2.c
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bonding/bond_3ad.c
drivers/net/ehea/ehea_main.c
drivers/net/fs_enet/mac-fec.c
drivers/net/ftmac100.c
drivers/net/mii.c
drivers/net/netconsole.c
drivers/net/r8169.c
drivers/net/tg3.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
drivers/net/veth.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/iwlegacy/iwl-4965-tx.c
drivers/net/wireless/iwlegacy/iwl-led.c
drivers/net/wireless/iwlegacy/iwl4965-base.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/parport/parport_pc.c
drivers/pcmcia/pcmcia_resource.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/thinkpad_acpi.c
drivers/rtc/rtc-coh901331.c
drivers/rtc/rtc-max8925.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_genhd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_ioctl.c
drivers/s390/cio/qdio_main.c
drivers/s390/kvm/kvm_virtio.c
drivers/scsi/device_handler/scsi_dh.c
drivers/scsi/mpt2sas/mpt2sas_ctl.c
drivers/scsi/pmcraid.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_sysfs.c
drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
drivers/staging/gma500/Kconfig
drivers/staging/intel_sst/intelmid_v1_control.c
drivers/staging/intel_sst/intelmid_v2_control.c
drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
drivers/staging/rt2860/common/cmm_data_pci.c
drivers/staging/rt2860/common/cmm_data_usb.c
drivers/staging/rts_pstor/debug.h
drivers/staging/rts_pstor/ms.c
drivers/staging/rts_pstor/rtsx_chip.c
drivers/staging/rts_pstor/rtsx_scsi.c
drivers/staging/rts_pstor/sd.c
drivers/staging/rts_pstor/trace.h
drivers/staging/rts_pstor/xd.c
drivers/staging/solo6x10/Kconfig
drivers/staging/spectra/ffsport.c
drivers/staging/tidspbridge/dynload/cload.c
drivers/staging/tty/specialix.c
drivers/staging/usbip/vhci_hcd.c
drivers/staging/usbip/vhci_sysfs.c
drivers/staging/wlan-ng/cfg80211.c
drivers/tty/n_gsm.c
drivers/tty/serial/imx.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/xhci-hub.c
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/omap2430.c
drivers/watchdog/iTCO_wdt.c
drivers/xen/manage.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/super.h
fs/ceph/xattr.c
fs/cifs/connect.c
fs/cifs/sess.c
fs/dcache.c
fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/kthread.c
fs/ecryptfs/main.c
fs/ecryptfs/super.c
fs/file.c
fs/gfs2/glock.c
fs/hpfs/Kconfig
fs/hpfs/alloc.c
fs/hpfs/anode.c
fs/hpfs/buffer.c
fs/hpfs/dir.c
fs/hpfs/dnode.c
fs/hpfs/ea.c
fs/hpfs/file.c
fs/hpfs/hpfs.h
fs/hpfs/hpfs_fn.h
fs/hpfs/inode.c
fs/hpfs/map.c
fs/hpfs/name.c
fs/hpfs/namei.c
fs/hpfs/super.c
fs/logfs/super.c
fs/nfs/namespace.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c
fs/nfs/pnfs.c
fs/nfs/super.c
fs/nfs/write.c
fs/ocfs2/ocfs2_fs.h
fs/partitions/efi.c
fs/proc/task_mmu.c
fs/ubifs/log.c
fs/ubifs/recovery.c
fs/ubifs/replay.c
fs/ubifs/super.c
include/drm/drm_fb_helper.h
include/drm/drm_mm.h
include/drm/drm_pciids.h
include/drm/radeon_drm.h
include/linux/bit_spinlock.h
include/linux/dcache.h
include/linux/flex_array.h
include/linux/ftrace_event.h
include/linux/huge_mm.h
include/linux/libata.h
include/linux/list_bl.h
include/linux/mfd/wm831x/pdata.h
include/linux/mm.h
include/linux/mmc/host.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h
include/linux/pci_ids.h
include/linux/percpu.h
include/linux/ptrace.h
include/linux/sched.h
include/linux/security.h
include/linux/sunrpc/sched.h
include/linux/usb/usbnet.h
include/linux/v4l2-mediabus.h
include/linux/videodev2.h
include/media/v4l2-device.h
init/Kconfig
kernel/exit.c
kernel/hrtimer.c
kernel/irq/proc.c
kernel/kexec.c
kernel/power/hibernate.c
kernel/power/suspend.c
kernel/ptrace.c
kernel/trace/Kconfig
kernel/trace/trace.c
kernel/trace/trace_events.c
kernel/watchdog.c
kernel/workqueue.c
lib/flex_array.c
lib/xz/xz_dec_lzma2.c
mm/huge_memory.c
mm/memory.c
mm/mlock.c
mm/mmap.c
mm/oom_kill.c
mm/slub.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bluetooth/sco.c
net/bridge/br_input.c
net/can/bcm.c
net/can/raw.c
net/ceph/messenger.c
net/ceph/osd_client.c
net/core/dev.c
net/dsa/Kconfig
net/dsa/mv88e6131.c
net/ipv4/devinet.c
net/ipv4/fib_trie.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/esp6.c
net/ipv6/route.c
net/ipv6/udp.c
net/l2tp/l2tp_ip.c
net/mac80211/cfg.c
net/mac80211/debugfs_netdev.c
net/sctp/ulpevent.c
net/sunrpc/Kconfig
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/clnt.c
net/sunrpc/xprt.c
net/unix/af_unix.c
net/xfrm/xfrm_replay.c
net/xfrm/xfrm_user.c
scripts/kconfig/conf.c
security/capability.c
security/security.c
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/avc.h
security/selinux/ss/policydb.c
security/smack/smack_lsm.c
sound/aoa/codecs/tas.c
sound/pci/au88x0/au88x0_pcm.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_via.c
sound/soc/codecs/jz4740.c
sound/soc/codecs/sn95031.c
sound/soc/codecs/wm8903.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm_hubs.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/mid-x86/sst_platform.c
sound/soc/samsung/goni_wm8994.c
sound/soc/samsung/pcm.c
sound/soc/sh/fsi.c
sound/soc/soc-core.c
sound/soc/tegra/harmony.c
sound/usb/format.c
sound/usb/quirks.c
tools/perf/Makefile

index 5d259c6..fea63b4 100644 (file)
 <!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
 <!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
 <!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml">
+<!ENTITY sub-y12 SYSTEM "v4l/pixfmt-y12.xml">
 <!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
 <!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
 <!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
index 2331e76..cec97af 100644 (file)
@@ -34,7 +34,7 @@
       <varlistentry>
        <term><parameter>request</parameter></term>
        <listitem>
-         <para>MEDIA_IOC_ENUM_LINKS</para>
+         <para>MEDIA_IOC_SETUP_LINK</para>
        </listitem>
       </varlistentry>
       <varlistentry>
diff --git a/Documentation/DocBook/v4l/pixfmt-y12.xml b/Documentation/DocBook/v4l/pixfmt-y12.xml
new file mode 100644 (file)
index 0000000..ff417b8
--- /dev/null
@@ -0,0 +1,79 @@
+<refentry id="V4L2-PIX-FMT-Y12">
+  <refmeta>
+    <refentrytitle>V4L2_PIX_FMT_Y12 ('Y12 ')</refentrytitle>
+    &manvol;
+  </refmeta>
+  <refnamediv>
+    <refname><constant>V4L2_PIX_FMT_Y12</constant></refname>
+    <refpurpose>Grey-scale image</refpurpose>
+  </refnamediv>
+  <refsect1>
+    <title>Description</title>
+
+    <para>This is a grey-scale image with a depth of 12 bits per pixel. Pixels
+are stored in 16-bit words with unused high bits padded with 0. The least
+significant byte is stored at lower memory addresses (little-endian).</para>
+
+    <example>
+      <title><constant>V4L2_PIX_FMT_Y12</constant> 4 &times; 4
+pixel image</title>
+
+      <formalpara>
+       <title>Byte Order.</title>
+       <para>Each cell is one byte.
+         <informaltable frame="none">
+           <tgroup cols="9" align="center">
+             <colspec align="left" colwidth="2*" />
+             <tbody valign="top">
+               <row>
+                 <entry>start&nbsp;+&nbsp;0:</entry>
+                 <entry>Y'<subscript>00low</subscript></entry>
+                 <entry>Y'<subscript>00high</subscript></entry>
+                 <entry>Y'<subscript>01low</subscript></entry>
+                 <entry>Y'<subscript>01high</subscript></entry>
+                 <entry>Y'<subscript>02low</subscript></entry>
+                 <entry>Y'<subscript>02high</subscript></entry>
+                 <entry>Y'<subscript>03low</subscript></entry>
+                 <entry>Y'<subscript>03high</subscript></entry>
+               </row>
+               <row>
+                 <entry>start&nbsp;+&nbsp;8:</entry>
+                 <entry>Y'<subscript>10low</subscript></entry>
+                 <entry>Y'<subscript>10high</subscript></entry>
+                 <entry>Y'<subscript>11low</subscript></entry>
+                 <entry>Y'<subscript>11high</subscript></entry>
+                 <entry>Y'<subscript>12low</subscript></entry>
+                 <entry>Y'<subscript>12high</subscript></entry>
+                 <entry>Y'<subscript>13low</subscript></entry>
+                 <entry>Y'<subscript>13high</subscript></entry>
+               </row>
+               <row>
+                 <entry>start&nbsp;+&nbsp;16:</entry>
+                 <entry>Y'<subscript>20low</subscript></entry>
+                 <entry>Y'<subscript>20high</subscript></entry>
+                 <entry>Y'<subscript>21low</subscript></entry>
+                 <entry>Y'<subscript>21high</subscript></entry>
+                 <entry>Y'<subscript>22low</subscript></entry>
+                 <entry>Y'<subscript>22high</subscript></entry>
+                 <entry>Y'<subscript>23low</subscript></entry>
+                 <entry>Y'<subscript>23high</subscript></entry>
+               </row>
+               <row>
+                 <entry>start&nbsp;+&nbsp;24:</entry>
+                 <entry>Y'<subscript>30low</subscript></entry>
+                 <entry>Y'<subscript>30high</subscript></entry>
+                 <entry>Y'<subscript>31low</subscript></entry>
+                 <entry>Y'<subscript>31high</subscript></entry>
+                 <entry>Y'<subscript>32low</subscript></entry>
+                 <entry>Y'<subscript>32high</subscript></entry>
+                 <entry>Y'<subscript>33low</subscript></entry>
+                 <entry>Y'<subscript>33high</subscript></entry>
+               </row>
+             </tbody>
+           </tgroup>
+         </informaltable>
+       </para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>
index c6fdcbb..40af4be 100644 (file)
@@ -696,6 +696,7 @@ information.</para>
     &sub-packed-yuv;
     &sub-grey;
     &sub-y10;
+    &sub-y12;
     &sub-y16;
     &sub-yuyv;
     &sub-uyvy;
index 7041127..d7ccd25 100644 (file)
              <entry>b<subscript>1</subscript></entry>
              <entry>b<subscript>0</subscript></entry>
            </row>
+           <row id="V4L2-MBUS-FMT-SGBRG8-1X8">
+             <entry>V4L2_MBUS_FMT_SGBRG8_1X8</entry>
+             <entry>0x3013</entry>
+             <entry></entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>g<subscript>7</subscript></entry>
+             <entry>g<subscript>6</subscript></entry>
+             <entry>g<subscript>5</subscript></entry>
+             <entry>g<subscript>4</subscript></entry>
+             <entry>g<subscript>3</subscript></entry>
+             <entry>g<subscript>2</subscript></entry>
+             <entry>g<subscript>1</subscript></entry>
+             <entry>g<subscript>0</subscript></entry>
+           </row>
            <row id="V4L2-MBUS-FMT-SGRBG8-1X8">
              <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry>
              <entry>0x3002</entry>
              <entry>g<subscript>1</subscript></entry>
              <entry>g<subscript>0</subscript></entry>
            </row>
+           <row id="V4L2-MBUS-FMT-SRGGB8-1X8">
+             <entry>V4L2_MBUS_FMT_SRGGB8_1X8</entry>
+             <entry>0x3014</entry>
+             <entry></entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>r<subscript>7</subscript></entry>
+             <entry>r<subscript>6</subscript></entry>
+             <entry>r<subscript>5</subscript></entry>
+             <entry>r<subscript>4</subscript></entry>
+             <entry>r<subscript>3</subscript></entry>
+             <entry>r<subscript>2</subscript></entry>
+             <entry>r<subscript>1</subscript></entry>
+             <entry>r<subscript>0</subscript></entry>
+           </row>
            <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8">
              <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry>
              <entry>0x300b</entry>
              <entry>u<subscript>1</subscript></entry>
              <entry>u<subscript>0</subscript></entry>
            </row>
+           <row id="V4L2-MBUS-FMT-Y12-1X12">
+             <entry>V4L2_MBUS_FMT_Y12_1X12</entry>
+             <entry>0x2013</entry>
+             <entry></entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>y<subscript>11</subscript></entry>
+             <entry>y<subscript>10</subscript></entry>
+             <entry>y<subscript>9</subscript></entry>
+             <entry>y<subscript>8</subscript></entry>
+             <entry>y<subscript>7</subscript></entry>
+             <entry>y<subscript>6</subscript></entry>
+             <entry>y<subscript>5</subscript></entry>
+             <entry>y<subscript>4</subscript></entry>
+             <entry>y<subscript>3</subscript></entry>
+             <entry>y<subscript>2</subscript></entry>
+             <entry>y<subscript>1</subscript></entry>
+             <entry>y<subscript>0</subscript></entry>
+           </row>
            <row id="V4L2-MBUS-FMT-UYVY8-1X16">
              <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry>
              <entry>0x200f</entry>
index b6ed61c..7c16347 100644 (file)
@@ -52,8 +52,10 @@ Brief summary of control files.
  tasks                          # attach a task(thread) and show list of threads
  cgroup.procs                   # show list of processes
  cgroup.event_control           # an interface for event_fd()
- memory.usage_in_bytes          # show current memory(RSS+Cache) usage.
- memory.memsw.usage_in_bytes    # show current memory+Swap usage
+ memory.usage_in_bytes          # show current res_counter usage for memory
+                                (See 5.5 for details)
+ memory.memsw.usage_in_bytes    # show current res_counter usage for memory+Swap
+                                (See 5.5 for details)
  memory.limit_in_bytes          # set/show limit of memory usage
  memory.memsw.limit_in_bytes    # set/show limit of memory+Swap usage
  memory.failcnt                         # show the number of memory usage hits limits
@@ -453,6 +455,15 @@ memory under it will be reclaimed.
 You can reset failcnt by writing 0 to failcnt file.
 # echo 0 > .../memory.failcnt
 
+5.5 usage_in_bytes
+
+For efficiency, as other kernel components, memory cgroup uses some optimization
+to avoid unnecessary cacheline false sharing. usage_in_bytes is affected by the
+method and doesn't show 'exact' value of memory(and swap) usage, it's an fuzz
+value for efficient access. (Of course, when necessary, it's synchronized.)
+If you want to know more exact memory usage, you should use RSS+CACHE(+SWAP)
+value in memory.stat(see 5.2).
+
 6. Hierarchy support
 
 The memory controller supports a deep hierarchy and hierarchical accounting.
index cb8a3a0..df904ae 100644 (file)
@@ -66,10 +66,10 @@ trick is to ensure that any needed memory allocations are done before
 entering atomic context, using:
 
     int flex_array_prealloc(struct flex_array *array, unsigned int start,
-                           unsigned int end, gfp_t flags);
+                           unsigned int nr_elements, gfp_t flags);
 
 This function will ensure that memory for the elements indexed in the range
-defined by start and end has been allocated.  Thereafter, a
+defined by start and nr_elements has been allocated.  Thereafter, a
 flex_array_put() call on an element in that range is guaranteed not to
 block.
 
index 03d02bf..02ad96c 100644 (file)
@@ -14,10 +14,6 @@ Supported chips:
     Prefix: 'gl523sm'
     Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
     Datasheet:
-  * Intel Xeon Processor
-    Prefix: - any other - may require 'force_adm1021' parameter
-    Addresses scanned: none
-    Datasheet: Publicly available at Intel website
   * Maxim MAX1617
     Prefix: 'max1617'
     Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
@@ -91,21 +87,27 @@ will do no harm, but will return 'old' values. It is possible to make
 ADM1021-clones do faster measurements, but there is really no good reason
 for that.
 
-Xeon support
-------------
 
-Some Xeon processors have real max1617, adm1021, or compatible chips
-within them, with two temperature sensors.
+Netburst-based Xeon support
+---------------------------
 
-Other Xeons have chips with only one sensor.
+Some Xeon processors based on the Netburst (early Pentium 4, from 2001 to
+2003) microarchitecture had real MAX1617, ADM1021, or compatible chips
+within them, with two temperature sensors. Other Xeon processors of this
+era (with 400 MHz FSB) had chips with only one temperature sensor.
 
-If you have a Xeon, and the adm1021 module loads, and both temperatures
-appear valid, then things are good.
+If you have such an old Xeon, and you get two valid temperatures when
+loading the adm1021 module, then things are good.
 
-If the adm1021 module doesn't load, you should try this:
-       modprobe adm1021 force_adm1021=BUS,ADDRESS
-       ADDRESS can only be 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e.
+If nothing happens when loading the adm1021 module, and you are certain
+that your specific Xeon processor model includes compatible sensors, you
+will have to explicitly instantiate the sensor chips from user-space. See
+method 4 in Documentation/i2c/instantiating-devices. Possible slave
+addresses are 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e. It is likely that
+only temp2 will be correct and temp1 will have to be ignored.
 
-If you have dual Xeons you may have appear to have two separate
-adm1021-compatible chips, or two single-temperature sensors, at distinct
-addresses.
+Previous generations of the Xeon processor (based on Pentium II/III)
+didn't have these sensors. Next generations of Xeon processors (533 MHz
+FSB and faster) lost them, until the Core-based generation which
+introduced integrated digital thermal sensors. These are supported by
+the coretemp driver.
index fa475c0..f3efd18 100644 (file)
@@ -32,6 +32,16 @@ Supported chips:
     Addresses scanned: I2C 0x4c and 0x4d
     Datasheet: Publicly available at the ON Semiconductor website
                http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461
+  * Analog Devices ADT7461A
+    Prefix: 'adt7461a'
+    Addresses scanned: I2C 0x4c and 0x4d
+    Datasheet: Publicly available at the ON Semiconductor website
+               http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461A
+  * ON Semiconductor NCT1008
+    Prefix: 'nct1008'
+    Addresses scanned: I2C 0x4c and 0x4d
+    Datasheet: Publicly available at the ON Semiconductor website
+               http://www.onsemi.com/PowerSolutions/product.do?id=NCT1008
   * Maxim MAX6646
     Prefix: 'max6646'
     Addresses scanned: I2C 0x4d
@@ -149,7 +159,7 @@ ADM1032:
   * ALERT is triggered by open remote sensor.
   * SMBus PEC support for Write Byte and Receive Byte transactions.
 
-ADT7461:
+ADT7461, ADT7461A, NCT1008:
   * Extended temperature range (breaks compatibility)
   * Lower resolution for remote temperature
 
@@ -195,9 +205,9 @@ are exported, one for each channel, but these values are of course linked.
 Only the local hysteresis can be set from user-space, and the same delta
 applies to the remote hysteresis.
 
-The lm90 driver will not update its values more frequently than every
-other second; reading them more often will do no harm, but will return
-'old' values.
+The lm90 driver will not update its values more frequently than configured with
+the update_interval attribute; reading them more often will do no harm, but will
+return 'old' values.
 
 SMBus Alert Support
 -------------------
@@ -205,11 +215,12 @@ SMBus Alert Support
 This driver has basic support for SMBus alert. When an alert is received,
 the status register is read and the faulty temperature channel is logged.
 
-The Analog Devices chips (ADM1032 and ADT7461) do not implement the SMBus
-alert protocol properly so additional care is needed: the ALERT output is
-disabled when an alert is received, and is re-enabled only when the alarm
-is gone. Otherwise the chip would block alerts from other chips in the bus
-as long as the alarm is active.
+The Analog Devices chips (ADM1032, ADT7461 and ADT7461A) and ON
+Semiconductor chips (NCT1008) do not implement the SMBus alert protocol
+properly so additional care is needed: the ALERT output is disabled when
+an alert is received, and is re-enabled only when the alarm is gone.
+Otherwise the chip would block alerts from other chips in the bus as long
+as the alarm is active.
 
 PEC Support
 -----------
index f5639d4..f4b5988 100644 (file)
@@ -87,14 +87,14 @@ accumulator. ALSA uses accumulators 0 and 1 for left and right PCM.
 The result is forwarded to the ADC capture FIFO (thus to the standard capture
 PCM device).
 
-name='Music Playback Volume',index=0
+name='Synth Playback Volume',index=0
 
 This control is used to attenuate samples for left and right MIDI FX-bus
 accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
 The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
 
-name='Music Capture Volume',index=0
-name='Music Capture Switch',index=0
+name='Synth Capture Volume',index=0
+name='Synth Capture Switch',index=0
 
 These controls are used to attenuate samples for left and right MIDI FX-bus
 accumulator. ALSA uses accumulators 4 and 5 for left and right PCM.
index cb47e72..1e96ce6 100644 (file)
@@ -37,7 +37,7 @@ Generic scaling / cropping scheme
 -1'-
 
 In the above chart minuses and slashes represent "real" data amounts, points and
-accents represent "useful" data, basically, CEU scaled amd cropped output,
+accents represent "useful" data, basically, CEU scaled and cropped output,
 mapped back onto the client's source plane.
 
 Such a configuration can be produced by user requests:
@@ -65,7 +65,7 @@ Do not touch input rectangle - it is already optimal.
 
 1. Calculate current sensor scales:
 
-       scale_s = ((3') - (3)) / ((2') - (2))
+       scale_s = ((2') - (2)) / ((3') - (3))
 
 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
 current sensor scales onto input window - this is user S_CROP:
@@ -80,7 +80,7 @@ window:
 4. Calculate sensor output window by applying combined scales to real input
 window:
 
-       width_s_out = ((2') - (2)) / scale_comb
+       width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
 
 5. Apply iterative sensor S_FMT for sensor output window.
 
index 01c513f..a0b577d 100644 (file)
@@ -12,6 +12,7 @@ CONTENTS
 4. Application Programming Interface (API)
 5. Example Execution Scenarios
 6. Guidelines
+7. Debugging
 
 
 1. Introduction
@@ -379,3 +380,42 @@ If q1 has WQ_CPU_INTENSIVE set,
 * Unless work items are expected to consume a huge amount of CPU
   cycles, using a bound wq is usually beneficial due to the increased
   level of locality in wq operations and work item execution.
+
+
+7. Debugging
+
+Because the work functions are executed by generic worker threads
+there are a few tricks needed to shed some light on misbehaving
+workqueue users.
+
+Worker threads show up in the process list as:
+
+root      5671  0.0  0.0      0     0 ?        S    12:07   0:00 [kworker/0:1]
+root      5672  0.0  0.0      0     0 ?        S    12:07   0:00 [kworker/1:2]
+root      5673  0.0  0.0      0     0 ?        S    12:12   0:00 [kworker/0:0]
+root      5674  0.0  0.0      0     0 ?        S    12:13   0:00 [kworker/1:0]
+
+If kworkers are going crazy (using too much cpu), there are two types
+of possible problems:
+
+       1. Something beeing scheduled in rapid succession
+       2. A single work item that consumes lots of cpu cycles
+
+The first one can be tracked using tracing:
+
+       $ echo workqueue:workqueue_queue_work > /sys/kernel/debug/tracing/set_event
+       $ cat /sys/kernel/debug/tracing/trace_pipe > out.txt
+       (wait a few secs)
+       ^C
+
+If something is busy looping on work queueing, it would be dominating
+the output and the offender can be determined with the work item
+function.
+
+For the second type of problems it should be possible to just check
+the stack trace of the offending worker thread.
+
+       $ cat /proc/THE_OFFENDING_KWORKER/stack
+
+The work item's function should be trivially visible in the stack
+trace.
index 1e2724e..16a5c5f 100644 (file)
@@ -1032,12 +1032,13 @@ W:      http://www.fluff.org/ben/linux/
 S:     Maintained
 F:     arch/arm/mach-s3c64xx/
 
-ARM/S5P ARM ARCHITECTURES
+ARM/S5P EXYNOS ARM ARCHITECTURES
 M:     Kukjin Kim <kgene.kim@samsung.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-s5p*/
+F:     arch/arm/mach-exynos*/
 
 ARM/SAMSUNG MOBILE MACHINE SUPPORT
 M:     Kyungmin Park <kyungmin.park@samsung.com>
@@ -2808,7 +2809,7 @@ GPIO SUBSYSTEM
 M:     Grant Likely <grant.likely@secretlab.ca>
 S:     Maintained
 T:     git git://git.secretlab.ca/git/linux-2.6.git
-F:     Documentation/gpio/gpio.txt
+F:     Documentation/gpio.txt
 F:     drivers/gpio/
 F:     include/linux/gpio*
 
@@ -5396,7 +5397,7 @@ F:        drivers/media/video/*7146*
 F:     include/media/*7146*
 
 SAMSUNG AUDIO (ASoC) DRIVERS
-M:     Jassi Brar <jassi.brar@samsung.com>
+M:     Jassi Brar <jassisinghbrar@gmail.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
 F:     sound/soc/samsung
@@ -6555,7 +6556,7 @@ S:        Maintained
 F:     drivers/usb/host/uhci*
 
 USB "USBNET" DRIVER FRAMEWORK
-M:     David Brownell <dbrownell@users.sourceforge.net>
+M:     Oliver Neukum <oneukum@suse.de>
 L:     netdev@vger.kernel.org
 W:     http://www.linux-usb.org/usbnet
 S:     Maintained
@@ -6921,6 +6922,18 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.
 S:     Maintained
 F:     drivers/platform/x86
 
+XEN HYPERVISOR INTERFACE
+M:     Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
+M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
+L:     virtualization@lists.linux-foundation.org
+S:     Supported
+F:     arch/x86/xen/
+F:     drivers/*/xen-*front.c
+F:     drivers/xen/
+F:     arch/x86/include/asm/xen/
+F:     include/xen/
+
 XEN NETWORK BACKEND DRIVER
 M:     Ian Campbell <ian.campbell@citrix.com>
 L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
@@ -6942,18 +6955,6 @@ S:       Supported
 F:     arch/x86/xen/*swiotlb*
 F:     drivers/xen/*swiotlb*
 
-XEN HYPERVISOR INTERFACE
-M:     Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
-M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
-L:     virtualization@lists.linux-foundation.org
-S:     Supported
-F:     arch/x86/xen/
-F:     drivers/*/xen-*front.c
-F:     drivers/xen/
-F:     arch/x86/include/asm/xen/
-F:     include/xen/
-
 XFS FILESYSTEM
 P:     Silicon Graphics Inc
 M:     Alex Elder <aelder@sgi.com>
index b967b96..41ea6fb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 39
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc7
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
diff --git a/arch/arm/configs/at91x40_defconfig b/arch/arm/configs/at91x40_defconfig
new file mode 100644 (file)
index 0000000..c55e921
--- /dev/null
@@ -0,0 +1,48 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EMBEDDED=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_FUTEX is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_MMU is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91X40=y
+CONFIG_MACH_AT91EB01=y
+CONFIG_AT91_EARLY_USART0=y
+CONFIG_CPU_ARM7TDMI=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x01000000
+CONFIG_DRAM_SIZE=0x00400000
+CONFIG_FLASH_MEM_BASE=0x01400000
+CONFIG_PROCESSOR_ID=0x14000040
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_BINFMT_FLAT=y
+# CONFIG_SUSPEND is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_ENABLE_MUST_CHECK is not set
index bb8a19b..e46bdd0 100644 (file)
@@ -39,10 +39,13 @@ typedef u32 kprobe_opcode_t;
 struct kprobe;
 typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *);
 
+typedef unsigned long (kprobe_check_cc)(unsigned long);
+
 /* Architecture specific copy of original instruction. */
 struct arch_specific_insn {
        kprobe_opcode_t         *insn;
        kprobe_insn_handler_t   *insn_handler;
+       kprobe_check_cc         *insn_check_cc;
 };
 
 struct prev_kprobe {
index 2389131..15eeff6 100644 (file)
@@ -34,9 +34,6 @@
  *
  *   *) If the PC is written to by the instruction, the
  *      instruction must be fully simulated in software.
- *      If it is a conditional instruction, the handler
- *      will use insn[0] to copy its condition code to
- *     set r0 to 1 and insn[1] to "mov pc, lr" to return.
  *
  *   *) Otherwise, a modified form of the instruction is
  *      directly executed.  Its handler calls the
 
 #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
 
+#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
+
+/*
+ * Test if load/store instructions writeback the address register.
+ * if P (bit 24) == 0 or W (bit 21) == 1
+ */
+#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
+
 #define PSR_fs (PSR_f|PSR_s)
 
 #define KPROBE_RETURN_INSTRUCTION      0xe1a0f00e      /* mov pc, lr */
-#define SET_R0_TRUE_INSTRUCTION                0xe3a00001      /* mov  r0, #1 */
-
-#define        truecc_insn(insn)       (((insn) & 0xf0000000) | \
-                                (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))
 
 typedef long (insn_0arg_fn_t)(void);
 typedef long (insn_1arg_fn_t)(long);
@@ -419,14 +420,10 @@ insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
 
 static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
 {
-       insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
        long iaddr = (long)p->addr;
        int disp  = branch_displacement(insn);
 
-       if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
-               return;
-
        if (insn & (1 << 24))
                regs->ARM_lr = iaddr + 4;
 
@@ -446,14 +443,10 @@ static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
 
 static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
 {
-       insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
        int rm = insn & 0xf;
        long rmv = regs->uregs[rm];
 
-       if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
-               return;
-
        if (insn & (1 << 5))
                regs->ARM_lr = (long)p->addr + 4;
 
@@ -463,9 +456,16 @@ static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
                regs->ARM_cpsr |= PSR_T_BIT;
 }
 
+static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
+{
+       kprobe_opcode_t insn = p->opcode;
+       int rd = (insn >> 12) & 0xf;
+       unsigned long mask = 0xf8ff03df; /* Mask out execution state */
+       regs->uregs[rd] = regs->ARM_cpsr & mask;
+}
+
 static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
 {
-       insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
        int rn = (insn >> 16) & 0xf;
        int lbit = insn & (1 << 20);
@@ -476,9 +476,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
        int reg_bit_vector;
        int reg_count;
 
-       if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
-               return;
-
        reg_count = 0;
        reg_bit_vector = insn & 0xffff;
        while (reg_bit_vector) {
@@ -510,11 +507,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
 
 static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
 {
-       insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-
-       if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
-               return;
-
        regs->ARM_pc = (long)p->addr + str_pc_offset;
        simulate_ldm1stm1(p, regs);
        regs->ARM_pc = (long)p->addr + 4;
@@ -525,24 +517,16 @@ static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
        regs->uregs[12] = regs->uregs[13];
 }
 
-static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs)
-{
-       insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-       kprobe_opcode_t insn = p->opcode;
-       int rn = (insn >> 16) & 0xf;
-       long rnv = regs->uregs[rn];
-
-       /* Save Rn in case of writeback. */
-       regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
-}
-
 static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
 {
        insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
+       long ppc = (long)p->addr + 8;
        int rd = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;  /* rm may be invalid, don't care. */
+       long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+       long rnv = (rn == 15) ? ppc : regs->uregs[rn];
 
        /* Not following the C calling convention here, so need asm(). */
        __asm__ __volatile__ (
@@ -554,29 +538,36 @@ static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
                "str    r0, %[rn]       \n\t"   /* in case of writeback */
                "str    r2, %[rd0]      \n\t"
                "str    r3, %[rd1]      \n\t"
-               : [rn]  "+m" (regs->uregs[rn]),
+               : [rn]  "+m" (rnv),
                  [rd0] "=m" (regs->uregs[rd]),
                  [rd1] "=m" (regs->uregs[rd+1])
-               : [rm]   "m" (regs->uregs[rm]),
+               : [rm]   "m" (rmv),
                  [cpsr] "r" (regs->ARM_cpsr),
                  [i_fn] "r" (i_fn)
                : "r0", "r1", "r2", "r3", "lr", "cc"
        );
+       if (is_writeback(insn))
+               regs->uregs[rn] = rnv;
 }
 
 static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
 {
        insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
+       long ppc = (long)p->addr + 8;
        int rd = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm  = insn & 0xf;
-       long rnv = regs->uregs[rn];
-       long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
+       long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+       /* rm/rmv may be invalid, don't care. */
+       long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+       long rnv_wb;
 
-       regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
+       rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
                                               regs->uregs[rd+1],
                                               regs->ARM_cpsr, i_fn);
+       if (is_writeback(insn))
+               regs->uregs[rn] = rnv_wb;
 }
 
 static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
@@ -630,31 +621,6 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
                regs->uregs[rn] = rnv_wb;  /* Save Rn in case of writeback. */
 }
 
-static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
-{
-       insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0];
-       kprobe_opcode_t insn = p->opcode;
-       union reg_pair fnr;
-       int rd = (insn >> 12) & 0xf;
-       int rn = (insn >> 16) & 0xf;
-
-       fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn);
-       regs->uregs[rn] = fnr.r0;
-       regs->uregs[rd] = fnr.r1;
-}
-
-static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs)
-{
-       insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
-       kprobe_opcode_t insn = p->opcode;
-       int rd = (insn >> 12) & 0xf;
-       int rn = (insn >> 16) & 0xf;
-       long rnv = regs->uregs[rn];
-       long rdv = regs->uregs[rd];
-
-       insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn);
-}
-
 static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
 {
        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
@@ -688,32 +654,32 @@ static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
        insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
 }
 
-static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
 {
-       insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
-       kprobe_opcode_t insn = p->opcode;
-       int rd = (insn >> 12) & 0xf;
-
-       regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
 }
 
-static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes
+emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs)
 {
        insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
-       int ird = (insn >> 12) & 0xf;
+       int rd = (insn >> 12) & 0xf;
+       long rdv = regs->uregs[rd];
 
-       insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn);
+       regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn);
 }
 
-static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes
+emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs)
 {
-       insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+       insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
        kprobe_opcode_t insn = p->opcode;
-       int rn = (insn >> 16) & 0xf;
+       int rd = (insn >> 12) & 0xf;
+       int rn = insn & 0xf;
+       long rdv = regs->uregs[rd];
        long rnv = regs->uregs[rn];
 
-       insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
+       regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn);
 }
 
 static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
@@ -819,6 +785,17 @@ emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
+emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs)
+{
+       insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+       kprobe_opcode_t insn = p->opcode;
+       int rn = (insn >> 16) & 0xf;
+       long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
+
+       insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
 emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
 {
        insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
@@ -854,14 +831,34 @@ emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
                insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
 }
 
+static void __kprobes
+emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
+{
+       insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+       kprobe_opcode_t insn = p->opcode;
+       long ppc = (long)p->addr + 8;
+       int rn = (insn >> 16) & 0xf;
+       int rs = (insn >> 8) & 0xf;     /* rs/rsv may be invalid, don't care. */
+       int rm = insn & 0xf;
+       long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+       long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+       long rsv = regs->uregs[rs];
+
+       insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
+}
+
 static enum kprobe_insn __kprobes
 prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
-       int ibit = (insn & (1 << 26)) ? 25 : 22;
+       int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25))
+                                        : (~insn & (1 << 22));
+
+       if (is_writeback(insn) && is_r15(insn, 16))
+               return INSN_REJECTED;   /* Writeback to PC */
 
        insn &= 0xfff00fff;
        insn |= 0x00001000;     /* Rn = r0, Rd = r1 */
-       if (insn & (1 << ibit)) {
+       if (not_imm) {
                insn &= ~0xf;
                insn |= 2;      /* Rm = r2 */
        }
@@ -871,20 +868,40 @@ prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 }
 
 static enum kprobe_insn __kprobes
-prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
-       insn &= 0xffff0ff0;     /* Rd = r0, Rm = r0 */
+       if (is_r15(insn, 12))
+               return INSN_REJECTED;   /* Rd is PC */
+
+       insn &= 0xffff0fff;     /* Rd = r0 */
        asi->insn[0] = insn;
-       asi->insn_handler = emulate_rd12rm0;
+       asi->insn_handler = emulate_rd12_modify;
        return INSN_GOOD;
 }
 
 static enum kprobe_insn __kprobes
-prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+prep_emulate_rd12rn0_modify(kprobe_opcode_t insn,
+                           struct arch_specific_insn *asi)
 {
-       insn &= 0xffff0fff;     /* Rd = r0 */
+       if (is_r15(insn, 12))
+               return INSN_REJECTED;   /* Rd is PC */
+
+       insn &= 0xffff0ff0;     /* Rd = r0 */
+       insn |= 0x00000001;     /* Rn = r1 */
+       asi->insn[0] = insn;
+       asi->insn_handler = emulate_rd12rn0_modify;
+       return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+       if (is_r15(insn, 12))
+               return INSN_REJECTED;   /* Rd is PC */
+
+       insn &= 0xffff0ff0;     /* Rd = r0, Rm = r0 */
        asi->insn[0] = insn;
-       asi->insn_handler = emulate_rd12;
+       asi->insn_handler = emulate_rd12rm0;
        return INSN_GOOD;
 }
 
@@ -892,6 +909,9 @@ static enum kprobe_insn __kprobes
 prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
                                struct arch_specific_insn *asi)
 {
+       if (is_r15(insn, 12))
+               return INSN_REJECTED;   /* Rd is PC */
+
        insn &= 0xfff00ff0;     /* Rd = r0, Rn = r0 */
        insn |= 0x00000001;     /* Rm = r1 */
        asi->insn[0] = insn;
@@ -903,6 +923,9 @@ static enum kprobe_insn __kprobes
 prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
                               struct arch_specific_insn *asi)
 {
+       if (is_r15(insn, 16))
+               return INSN_REJECTED;   /* Rd is PC */
+
        insn &= 0xfff0f0f0;     /* Rd = r0, Rs = r0 */
        insn |= 0x00000001;     /* Rm = r1          */
        asi->insn[0] = insn;
@@ -914,6 +937,9 @@ static enum kprobe_insn __kprobes
 prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
                                   struct arch_specific_insn *asi)
 {
+       if (is_r15(insn, 16))
+               return INSN_REJECTED;   /* Rd is PC */
+
        insn &= 0xfff000f0;     /* Rd = r0, Rn = r0 */
        insn |= 0x00000102;     /* Rs = r1, Rm = r2 */
        asi->insn[0] = insn;
@@ -925,6 +951,9 @@ static enum kprobe_insn __kprobes
 prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
                                       struct arch_specific_insn *asi)
 {
+       if (is_r15(insn, 16) || is_r15(insn, 12))
+               return INSN_REJECTED;   /* RdHi or RdLo is PC */
+
        insn &= 0xfff000f0;     /* RdHi = r0, RdLo = r1 */
        insn |= 0x00001203;     /* Rs = r2, Rm = r3 */
        asi->insn[0] = insn;
@@ -945,20 +974,13 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
 static enum kprobe_insn __kprobes
 space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
-       /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */
-       /* RFE           : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */
-       /* SRS           : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */
-       if ((insn & 0xfff30020) == 0xf1020000 ||
-           (insn & 0xfe500f00) == 0xf8100a00 ||
-           (insn & 0xfe5f0f00) == 0xf84d0500)
-               return INSN_REJECTED;
-
-       /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */
-       if ((insn & 0xfd700000) == 0xf4500000) {
-               insn &= 0xfff0ffff;     /* Rn = r0 */
-               asi->insn[0] = insn;
-               asi->insn_handler = emulate_rn16;
-               return INSN_GOOD;
+       /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */
+       /* PLDI        : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */
+       /* PLDW        : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */
+       /* PLD         : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */
+       if ((insn & 0xfe300000) == 0xf4100000) {
+               asi->insn_handler = emulate_nop;
+               return INSN_GOOD_NO_SLOT;
        }
 
        /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
@@ -967,41 +989,22 @@ space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
                return INSN_GOOD_NO_SLOT;
        }
 
-       /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
-       /* CDP2   : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
-       if ((insn & 0xffff00f0) == 0xf1010000 ||
-           (insn & 0xff000010) == 0xfe000000) {
-               asi->insn[0] = insn;
-               asi->insn_handler = emulate_none;
-               return INSN_GOOD;
-       }
+       /* CPS   : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
+       /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
 
+       /* SRS   : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
+       /* RFE   : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+
+       /* Coprocessor instructions... */
        /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
        /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
-       if ((insn & 0xffe00000) == 0xfc400000) {
-               insn &= 0xfff00fff;     /* Rn = r0 */
-               insn |= 0x00001000;     /* Rd = r1 */
-               asi->insn[0] = insn;
-               asi->insn_handler =
-                       (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
-               return INSN_GOOD;
-       }
+       /* LDC2  : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+       /* STC2  : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+       /* CDP2  : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+       /* MCR2  : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+       /* MRC2  : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
 
-       /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
-       /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
-       if ((insn & 0xfe000000) == 0xfc000000) {
-               insn &= 0xfff0ffff;      /* Rn = r0 */
-               asi->insn[0] = insn;
-               asi->insn_handler = emulate_ldcstc;
-               return INSN_GOOD;
-       }
-
-       /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
-       /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
-       insn &= 0xffff0fff;     /* Rd = r0 */
-       asi->insn[0]      = insn;
-       asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
-       return INSN_GOOD;
+       return INSN_REJECTED;
 }
 
 static enum kprobe_insn __kprobes
@@ -1010,19 +1013,18 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
        /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
        if ((insn & 0x0f900010) == 0x01000000) {
 
-               /* BXJ  : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
-               /* MSR  : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
-               if ((insn & 0x0ff000f0) == 0x01200020 ||
-                   (insn & 0x0fb000f0) == 0x01200000)
-                       return INSN_REJECTED;
-
-               /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */
-               if ((insn & 0x0fb00010) == 0x01000000)
-                       return prep_emulate_rd12(insn, asi);
+               /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
+               if ((insn & 0x0ff000f0) == 0x01000000) {
+                       if (is_r15(insn, 12))
+                               return INSN_REJECTED;   /* Rd is PC */
+                       asi->insn_handler = simulate_mrs;
+                       return INSN_GOOD_NO_SLOT;
+               }
 
                /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
                if ((insn & 0x0ff00090) == 0x01400080)
-                       return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
+                       return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
+                                                                       asi);
 
                /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
                /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
@@ -1031,24 +1033,29 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
                        return prep_emulate_rd16rs8rm0_wflags(insn, asi);
 
                /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
-               /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */
-               return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+               /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */
+               if ((insn & 0x0ff00090) == 0x01000080 ||
+                   (insn & 0x0ff000b0) == 0x01200080)
+                       return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+
+               /* BXJ      : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
+               /* MSR      : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
+               /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
 
+               /* Other instruction encodings aren't yet defined */
+               return INSN_REJECTED;
        }
 
        /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
        else if ((insn & 0x0f900090) == 0x01000010) {
 
-               /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
-               if ((insn & 0xfff000f0) == 0xe1200070)
-                       return INSN_REJECTED;
-
                /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
                /* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
                if ((insn & 0x0ff000d0) == 0x01200010) {
-                       asi->insn[0] = truecc_insn(insn);
+                       if ((insn & 0x0ff000ff) == 0x0120003f)
+                               return INSN_REJECTED; /* BLX pc */
                        asi->insn_handler = simulate_blx2bx;
-                       return INSN_GOOD;
+                       return INSN_GOOD_NO_SLOT;
                }
 
                /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
@@ -1059,17 +1066,27 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
                /* QSUB    : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
                /* QDADD   : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
                /* QDSUB   : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
-               return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+               if ((insn & 0x0f9000f0) == 0x01000050)
+                       return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+
+               /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
+               /* SMC  : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
+
+               /* Other instruction encodings aren't yet defined */
+               return INSN_REJECTED;
        }
 
        /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
-       else if ((insn & 0x0f000090) == 0x00000090) {
+       else if ((insn & 0x0f0000f0) == 0x00000090) {
 
                /* MUL    : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx :   */
                /* MULS   : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
                /* MLA    : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx :   */
                /* MLAS   : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
                /* UMAAL  : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx :   */
+               /* undef  : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx :   */
+               /* MLS    : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx :   */
+               /* undef  : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx :   */
                /* UMULL  : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx :   */
                /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
                /* UMLAL  : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx :   */
@@ -1078,13 +1095,15 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
                /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
                /* SMLAL  : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx :   */
                /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
-               if ((insn & 0x0fe000f0) == 0x00000090) {
-                      return prep_emulate_rd16rs8rm0_wflags(insn, asi);
-               } else if  ((insn & 0x0fe000f0) == 0x00200090) {
-                      return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
-               } else {
-                      return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
-               }
+               if ((insn & 0x00d00000) == 0x00500000)
+                       return INSN_REJECTED;
+               else if ((insn & 0x00e00000) == 0x00000000)
+                       return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+               else if ((insn & 0x00a00000) == 0x00200000)
+                       return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+               else
+                       return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
+                                                                       asi);
        }
 
        /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
@@ -1092,23 +1111,45 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
                /* SWP   : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
                /* SWPB  : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
-               /* LDRD  : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
-               /* STRD  : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
+               /* ???   : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */
+               /* ???   : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */
+               /* ???   : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */
                /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
                /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
+               /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */
+               /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */
+               /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */
+               /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */
+               /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */
+               /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */
+
+               /* LDRD  : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
+               /* STRD  : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
                /* LDRH  : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
                /* STRH  : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
                /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
                /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
-               if ((insn & 0x0fb000f0) == 0x01000090) {
-                       /* SWP/SWPB */
-                       return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+               if ((insn & 0x0f0000f0) == 0x01000090) {
+                       if ((insn & 0x0fb000f0) == 0x01000090) {
+                               /* SWP/SWPB */
+                               return prep_emulate_rd12rn16rm0_wflags(insn,
+                                                                       asi);
+                       } else {
+                               /* STREX/LDREX variants and unallocaed space */
+                               return INSN_REJECTED;
+                       }
+
                } else if ((insn & 0x0e1000d0) == 0x00000d0) {
                        /* STRD/LDRD */
+                       if ((insn & 0x0000e000) == 0x0000e000)
+                               return INSN_REJECTED;   /* Rd is LR or PC */
+                       if (is_writeback(insn) && is_r15(insn, 16))
+                               return INSN_REJECTED;   /* Writeback to PC */
+
                        insn &= 0xfff00fff;
                        insn |= 0x00002000;     /* Rn = r0, Rd = r2 */
-                       if (insn & (1 << 22)) {
-                               /* I bit */
+                       if (!(insn & (1 << 22))) {
+                               /* Register index */
                                insn &= ~0xf;
                                insn |= 1;      /* Rm = r1 */
                        }
@@ -1118,6 +1159,9 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
                        return INSN_GOOD;
                }
 
+               /* LDRH/STRH/LDRSB/LDRSH */
+               if (is_r15(insn, 12))
+                       return INSN_REJECTED;   /* Rd is PC */
                return prep_emulate_ldr_str(insn, asi);
        }
 
@@ -1125,7 +1169,7 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
        /*
         * ALU op with S bit and Rd == 15 :
-        *      cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
+        *      cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
         */
        if ((insn & 0x0e10f000) == 0x0010f000)
                return INSN_REJECTED;
@@ -1154,22 +1198,61 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
                insn |= 0x00000200;     /* Rs = r2 */
        }
        asi->insn[0] = insn;
-       asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
+
+       if ((insn & 0x0f900000) == 0x01100000) {
+               /*
+                * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx
+                * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx
+                * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx
+                * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx
+                */
+               asi->insn_handler = emulate_alu_tests;
+       } else {
+               /* ALU ops which write to Rd */
+               asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
                                emulate_alu_rwflags : emulate_alu_rflags;
+       }
        return INSN_GOOD;
 }
 
 static enum kprobe_insn __kprobes
 space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
+       /* MOVW  : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
+       /* MOVT  : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
+       if ((insn & 0x0fb00000) == 0x03000000)
+               return prep_emulate_rd12_modify(insn, asi);
+
+       /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
+       if ((insn & 0x0fff0000) == 0x03200000) {
+               unsigned op2 = insn & 0x000000ff;
+               if (op2 == 0x01 || op2 == 0x04) {
+                       /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
+                       /* SEV   : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
+                       asi->insn[0] = insn;
+                       asi->insn_handler = emulate_none;
+                       return INSN_GOOD;
+               } else if (op2 <= 0x03) {
+                       /* NOP   : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
+                       /* WFE   : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
+                       /* WFI   : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
+                       /*
+                        * We make WFE and WFI true NOPs to avoid stalls due
+                        * to missing events whilst processing the probe.
+                        */
+                       asi->insn_handler = emulate_nop;
+                       return INSN_GOOD_NO_SLOT;
+               }
+               /* For DBG and unallocated hints it's safest to reject them */
+               return INSN_REJECTED;
+       }
+
        /*
         * MSR   : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
-        * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx
         * ALU op with S bit and Rd == 15 :
         *         cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
         */
        if ((insn & 0x0fb00000) == 0x03200000 ||        /* MSR */
-           (insn & 0x0ff00000) == 0x03400000 ||        /* Undef */
            (insn & 0x0e10f000) == 0x0210f000)          /* ALU s-bit, R15  */
                return INSN_REJECTED;
 
@@ -1180,10 +1263,22 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
         * *S (bit 20) updates condition codes
         * ADC/SBC/RSC reads the C flag
         */
-       insn &= 0xffff0fff;     /* Rd = r0 */
+       insn &= 0xfff00fff;     /* Rn = r0 and Rd = r0 */
        asi->insn[0] = insn;
-       asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
+
+       if ((insn & 0x0f900000) == 0x03100000) {
+               /*
+                * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
+                * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
+                * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
+                * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
+                */
+               asi->insn_handler = emulate_alu_tests_imm;
+       } else {
+               /* ALU ops which write to Rd */
+               asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
                        emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
+       }
        return INSN_GOOD;
 }
 
@@ -1192,6 +1287,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
        /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
        if ((insn & 0x0ff000f0) == 0x068000b0) {
+               if (is_r15(insn, 12))
+                       return INSN_REJECTED;   /* Rd is PC */
                insn &= 0xfff00ff0;     /* Rd = r0, Rn = r0 */
                insn |= 0x00000001;     /* Rm = r1 */
                asi->insn[0] = insn;
@@ -1205,6 +1302,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
        /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
        if ((insn & 0x0fa00030) == 0x06a00010 ||
            (insn & 0x0fb000f0) == 0x06a00030) {
+               if (is_r15(insn, 12))
+                       return INSN_REJECTED;   /* Rd is PC */
                insn &= 0xffff0ff0;     /* Rd = r0, Rm = r0 */
                asi->insn[0] = insn;
                asi->insn_handler = emulate_sat;
@@ -1213,57 +1312,101 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
        /* REV    : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
        /* REV16  : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
+       /* RBIT   : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
        /* REVSH  : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
        if ((insn & 0x0ff00070) == 0x06b00030 ||
-           (insn & 0x0ff000f0) == 0x06f000b0)
+           (insn & 0x0ff00070) == 0x06f00030)
                return prep_emulate_rd12rm0(insn, asi);
 
+       /* ???       : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx :   */
        /* SADD16    : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
        /* SADDSUBX  : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
        /* SSUBADDX  : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
        /* SSUB16    : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
        /* SADD8     : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
+       /* ???       : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx :   */
+       /* ???       : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx :   */
        /* SSUB8     : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
        /* QADD16    : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx :   */
        /* QADDSUBX  : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx :   */
        /* QSUBADDX  : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx :   */
        /* QSUB16    : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx :   */
        /* QADD8     : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx :   */
+       /* ???       : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx :   */
+       /* ???       : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx :   */
        /* QSUB8     : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx :   */
        /* SHADD16   : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx :   */
        /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx :   */
        /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx :   */
        /* SHSUB16   : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx :   */
        /* SHADD8    : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx :   */
+       /* ???       : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx :   */
+       /* ???       : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx :   */
        /* SHSUB8    : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx :   */
+       /* ???       : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx :   */
        /* UADD16    : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
        /* UADDSUBX  : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
        /* USUBADDX  : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
        /* USUB16    : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
        /* UADD8     : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
+       /* ???       : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx :   */
+       /* ???       : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx :   */
        /* USUB8     : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
        /* UQADD16   : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx :   */
        /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx :   */
        /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx :   */
        /* UQSUB16   : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx :   */
        /* UQADD8    : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx :   */
+       /* ???       : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx :   */
+       /* ???       : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx :   */
        /* UQSUB8    : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx :   */
        /* UHADD16   : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx :   */
        /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx :   */
        /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx :   */
        /* UHSUB16   : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx :   */
        /* UHADD8    : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx :   */
+       /* ???       : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx :   */
+       /* ???       : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx :   */
        /* UHSUB8    : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx :   */
+       if ((insn & 0x0f800010) == 0x06000010) {
+               if ((insn & 0x00300000) == 0x00000000 ||
+                   (insn & 0x000000e0) == 0x000000a0 ||
+                   (insn & 0x000000e0) == 0x000000c0)
+                       return INSN_REJECTED;   /* Unallocated space */
+               return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+       }
+
        /* PKHBT     : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx :   */
        /* PKHTB     : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx :   */
+       if ((insn & 0x0ff00030) == 0x06800010)
+               return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+
        /* SXTAB16   : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx :   */
-       /* SXTB      : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
+       /* SXTB16    : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx :   */
+       /* ???       : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx :   */
        /* SXTAB     : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
+       /* SXTB      : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx :   */
        /* SXTAH     : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx :   */
+       /* SXTH      : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx :   */
        /* UXTAB16   : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx :   */
+       /* UXTB16    : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx :   */
+       /* ???       : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx :   */
        /* UXTAB     : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx :   */
+       /* UXTB      : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx :   */
        /* UXTAH     : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx :   */
-       return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+       /* UXTH      : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx :   */
+       if ((insn & 0x0f8000f0) == 0x06800070) {
+               if ((insn & 0x00300000) == 0x00100000)
+                       return INSN_REJECTED;   /* Unallocated space */
+
+               if ((insn & 0x000f0000) == 0x000f0000)
+                       return prep_emulate_rd12rm0(insn, asi);
+               else
+                       return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+       }
+
+       /* Other instruction encodings aren't yet defined */
+       return INSN_REJECTED;
 }
 
 static enum kprobe_insn __kprobes
@@ -1273,29 +1416,49 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
        if ((insn & 0x0ff000f0) == 0x03f000f0)
                return INSN_REJECTED;
 
-       /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
-       /* USAD8  : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
-       if ((insn & 0x0ff000f0) == 0x07800010)
-                return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
-
        /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
        /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
        if ((insn & 0x0ff00090) == 0x07400010)
                return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
 
        /* SMLAD  : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
+       /* SMUAD  : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
        /* SMLSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
+       /* SMUSD  : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx :  */
        /* SMMLA  : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx :  */
-       /* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
+       /* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
+       /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx :  */
+       /* USAD8  : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx :  */
        if ((insn & 0x0ff00090) == 0x07000010 ||
            (insn & 0x0ff000d0) == 0x07500010 ||
-           (insn & 0x0ff000d0) == 0x075000d0)
+           (insn & 0x0ff000f0) == 0x07800010) {
+
+               if ((insn & 0x0000f000) == 0x0000f000)
+                       return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+               else
+                       return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+       }
+
+       /* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
+       if ((insn & 0x0ff000d0) == 0x075000d0)
                return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
 
-       /* SMUSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :  */
-       /* SMUAD  : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
-       /* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
-       return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+       /* SBFX   : cccc 0111 101x xxxx xxxx xxxx x101 xxxx :  */
+       /* UBFX   : cccc 0111 111x xxxx xxxx xxxx x101 xxxx :  */
+       if ((insn & 0x0fa00070) == 0x07a00050)
+               return prep_emulate_rd12rm0(insn, asi);
+
+       /* BFI    : cccc 0111 110x xxxx xxxx xxxx x001 xxxx :  */
+       /* BFC    : cccc 0111 110x xxxx xxxx xxxx x001 1111 :  */
+       if ((insn & 0x0fe00070) == 0x07c00010) {
+
+               if ((insn & 0x0000000f) == 0x0000000f)
+                       return prep_emulate_rd12_modify(insn, asi);
+               else
+                       return prep_emulate_rd12rn0_modify(insn, asi);
+       }
+
+       return INSN_REJECTED;
 }
 
 static enum kprobe_insn __kprobes
@@ -1309,6 +1472,10 @@ space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
        /* STRB  : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
        /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
        /* STRT  : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
+
+       if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12))
+               return INSN_REJECTED;   /* LDRB into PC */
+
        return prep_emulate_ldr_str(insn, asi);
 }
 
@@ -1323,10 +1490,9 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
        /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
        /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
-       asi->insn[0] = truecc_insn(insn);
        asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
                                simulate_stm1_pc : simulate_ldm1stm1;
-       return INSN_GOOD;
+       return INSN_GOOD_NO_SLOT;
 }
 
 static enum kprobe_insn __kprobes
@@ -1334,58 +1500,117 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
        /* B  : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
        /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
-       asi->insn[0] = truecc_insn(insn);
        asi->insn_handler = simulate_bbl;
-       return INSN_GOOD;
+       return INSN_GOOD_NO_SLOT;
 }
 
 static enum kprobe_insn __kprobes
-space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
+       /* Coprocessor instructions... */
        /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
        /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
-       insn &= 0xfff00fff;
-       insn |= 0x00001000;     /* Rn = r0, Rd = r1 */
-       asi->insn[0] = insn;
-       asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
-       return INSN_GOOD;
+       /* LDC  : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+       /* STC  : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+       /* CDP  : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+       /* MCR  : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+       /* MRC  : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+
+       /* SVC  : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
+
+       return INSN_REJECTED;
 }
 
-static enum kprobe_insn __kprobes
-space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static unsigned long __kprobes __check_eq(unsigned long cpsr)
 {
-       /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
-       /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
-       insn &= 0xfff0ffff;     /* Rn = r0 */
-       asi->insn[0] = insn;
-       asi->insn_handler = emulate_ldcstc;
-       return INSN_GOOD;
+       return cpsr & PSR_Z_BIT;
 }
 
-static enum kprobe_insn __kprobes
-space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static unsigned long __kprobes __check_ne(unsigned long cpsr)
 {
-       /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
-       /* SWI  : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
-       if ((insn & 0xfff000f0) == 0xe1200070 ||
-           (insn & 0x0f000000) == 0x0f000000)
-               return INSN_REJECTED;
+       return (~cpsr) & PSR_Z_BIT;
+}
 
-       /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
-       if ((insn & 0x0f000010) == 0x0e000000) {
-               asi->insn[0] = insn;
-               asi->insn_handler = emulate_none;
-               return INSN_GOOD;
-       }
+static unsigned long __kprobes __check_cs(unsigned long cpsr)
+{
+       return cpsr & PSR_C_BIT;
+}
 
-       /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
-       /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
-       insn &= 0xffff0fff;     /* Rd = r0 */
-       asi->insn[0] = insn;
-       asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
-       return INSN_GOOD;
+static unsigned long __kprobes __check_cc(unsigned long cpsr)
+{
+       return (~cpsr) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_mi(unsigned long cpsr)
+{
+       return cpsr & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_pl(unsigned long cpsr)
+{
+       return (~cpsr) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_vs(unsigned long cpsr)
+{
+       return cpsr & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_vc(unsigned long cpsr)
+{
+       return (~cpsr) & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_hi(unsigned long cpsr)
+{
+       cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+       return cpsr & PSR_C_BIT;
 }
 
+static unsigned long __kprobes __check_ls(unsigned long cpsr)
+{
+       cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+       return (~cpsr) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_ge(unsigned long cpsr)
+{
+       cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       return (~cpsr) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_lt(unsigned long cpsr)
+{
+       cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       return cpsr & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_gt(unsigned long cpsr)
+{
+       unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
+       return (~temp) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_le(unsigned long cpsr)
+{
+       unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
+       return temp & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_al(unsigned long cpsr)
+{
+       return true;
+}
+
+static kprobe_check_cc * const condition_checks[16] = {
+       &__check_eq, &__check_ne, &__check_cs, &__check_cc,
+       &__check_mi, &__check_pl, &__check_vs, &__check_vc,
+       &__check_hi, &__check_ls, &__check_ge, &__check_lt,
+       &__check_gt, &__check_le, &__check_al, &__check_al
+};
+
 /* Return:
  *   INSN_REJECTED     If instruction is one not allowed to kprobe,
  *   INSN_GOOD         If instruction is supported and uses instruction slot,
@@ -1401,133 +1626,45 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 enum kprobe_insn __kprobes
 arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
+       asi->insn_check_cc = condition_checks[insn>>28];
        asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
 
-       if ((insn & 0xf0000000) == 0xf0000000) {
+       if ((insn & 0xf0000000) == 0xf0000000)
 
                return space_1111(insn, asi);
 
-       } else if ((insn & 0x0e000000) == 0x00000000) {
+       else if ((insn & 0x0e000000) == 0x00000000)
 
                return space_cccc_000x(insn, asi);
 
-       } else if ((insn & 0x0e000000) == 0x02000000) {
+       else if ((insn & 0x0e000000) == 0x02000000)
 
                return space_cccc_001x(insn, asi);
 
-       } else if ((insn & 0x0f000010) == 0x06000010) {
+       else if ((insn & 0x0f000010) == 0x06000010)
 
                return space_cccc_0110__1(insn, asi);
 
-       } else if ((insn & 0x0f000010) == 0x07000010) {
+       else if ((insn & 0x0f000010) == 0x07000010)
 
                return space_cccc_0111__1(insn, asi);
 
-       } else if ((insn & 0x0c000000) == 0x04000000) {
+       else if ((insn & 0x0c000000) == 0x04000000)
 
                return space_cccc_01xx(insn, asi);
 
-       } else if ((insn & 0x0e000000) == 0x08000000) {
+       else if ((insn & 0x0e000000) == 0x08000000)
 
                return space_cccc_100x(insn, asi);
 
-       } else if ((insn & 0x0e000000) == 0x0a000000) {
+       else if ((insn & 0x0e000000) == 0x0a000000)
 
                return space_cccc_101x(insn, asi);
 
-       } else if ((insn & 0x0fe00000) == 0x0c400000) {
-
-               return space_cccc_1100_010x(insn, asi);
-
-       } else if ((insn & 0x0e000000) == 0x0c000000) {
-
-               return space_cccc_110x(insn, asi);
-
-       }
-
-       return space_cccc_111x(insn, asi);
+       return space_cccc_11xx(insn, asi);
 }
 
 void __init arm_kprobe_decode_init(void)
 {
        find_str_pc_offset();
 }
-
-
-/*
- * All ARM instructions listed below.
- *
- * Instructions and their general purpose registers are given.
- * If a particular register may not use R15, it is prefixed with a "!".
- * If marked with a "*" means the value returned by reading R15
- * is implementation defined.
- *
- * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ
- *     TST: Rd, Rn, Rm, !Rs
- * BX: Rm
- * BLX(2): !Rm
- * BX: Rm (R15 legal, but discouraged)
- * BXJ: !Rm,
- * CLZ: !Rd, !Rm
- * CPY: Rd, Rm
- * LDC/2,STC/2 immediate offset & unindex: Rn
- * LDC/2,STC/2 immediate pre/post-indexed: !Rn
- * LDM(1/3): !Rn, register_list
- * LDM(2): !Rn, !register_list
- * LDR,STR,PLD immediate offset: Rd, Rn
- * LDR,STR,PLD register offset: Rd, Rn, !Rm
- * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm
- * LDR,STR immediate pre/post-indexed: Rd, !Rn
- * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm
- * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm
- * LDRB,STRB immediate offset: !Rd, Rn
- * LDRB,STRB register offset: !Rd, Rn, !Rm
- * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm
- * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn
- * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm
- * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm
- * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn
- * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm
- * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm
- * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn
- * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm
- * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn
- * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm
- * LDREX: !Rd, !Rn
- * MCR/2: !Rd
- * MCRR/2,MRRC/2: !Rd, !Rn
- * MLA: !Rd, !Rn, !Rm, !Rs
- * MOV: Rd
- * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register)
- * MRS,MSR: !Rd
- * MUL: !Rd, !Rm, !Rs
- * PKH{BT,TB}: !Rd, !Rn, !Rm
- * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn
- * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn
- * REV/16/SH: !Rd, !Rm
- * RFE: !Rn
- * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm
- * SEL: !Rd, !Rn, !Rm
- * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs
- * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs
- * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs
- * SSAT/16: !Rd, !Rm
- * STM(1/2): !Rn, register_list* (R15 in reg list not recommended)
- * STRT immediate pre/post-indexed: Rd*, !Rn
- * STRT register pre/post-indexed: Rd*, !Rn, !Rm
- * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm
- * STREX: !Rd, !Rn, !Rm
- * SWP/B: !Rd, !Rn, !Rm
- * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm
- * {S,U}XT{B,B16,H}: !Rd, !Rm
- * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs
- * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs
- *
- * May transfer control by writing R15 (possible mode changes or alternate
- * mode accesses marked by "*"):
- * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY,
- * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI*
- *
- * Instructions that do not take general registers, nor transfer control:
- * CDP/2, SETEND, SRS*
- */
index 2ba7deb..1656c87 100644 (file)
@@ -134,7 +134,8 @@ static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs,
                                 struct kprobe_ctlblk *kcb)
 {
        regs->ARM_pc += 4;
-       p->ainsn.insn_handler(p, regs);
+       if (p->ainsn.insn_check_cc(regs->ARM_cpsr))
+               p->ainsn.insn_handler(p, regs);
 }
 
 /*
index 979da39..139e3c8 100644 (file)
@@ -746,7 +746,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
 
        tail = (struct frame_tail __user *)regs->ARM_fp - 1;
 
-       while (tail && !((unsigned long)tail & 0x3))
+       while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
+              tail && !((unsigned long)tail & 0x3))
                tail = user_backtrace(tail, entry);
 }
 
index 2bf27f3..8182f45 100644 (file)
@@ -767,12 +767,20 @@ long arch_ptrace(struct task_struct *child, long request,
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
                case PTRACE_GETHBPREGS:
+                       if (ptrace_get_breakpoints(child) < 0)
+                               return -ESRCH;
+
                        ret = ptrace_gethbpregs(child, addr,
                                                (unsigned long __user *)data);
+                       ptrace_put_breakpoints(child);
                        break;
                case PTRACE_SETHBPREGS:
+                       if (ptrace_get_breakpoints(child) < 0)
+                               return -ESRCH;
+
                        ret = ptrace_sethbpregs(child, addr,
                                                (unsigned long __user *)data);
+                       ptrace_put_breakpoints(child);
                        break;
 #endif
 
index 8fe05ad..f29b8a2 100644 (file)
@@ -479,7 +479,7 @@ static void broadcast_timer_set_mode(enum clock_event_mode mode,
 {
 }
 
-static void broadcast_timer_setup(struct clock_event_device *evt)
+static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
 {
        evt->name       = "dummy_timer";
        evt->features   = CLOCK_EVT_FEAT_ONESHOT |
index 4ad8da1..af0aaeb 100644 (file)
@@ -311,7 +311,7 @@ asmlinkage long sys_oabi_semtimedop(int semid,
        long err;
        int i;
 
-       if (nsops < 1)
+       if (nsops < 1 || nsops > SEMOPM)
                return -EINVAL;
        sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
        if (!sops)
index 1939023..2d299bf 100644 (file)
@@ -83,6 +83,7 @@ config ARCH_AT91CAP9
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
+       select HAVE_NET_MACB
 
 config ARCH_AT572D940HF
        bool "AT572D940HF"
index 1f9d3cb..d8df59a 100644 (file)
 #include <mach/board.h>
 #include "generic.h"
 
+static void __init at91eb01_init_irq(void)
+{
+       at91x40_init_interrupts(NULL);
+}
+
 static void __init at91eb01_map_io(void)
 {
        at91x40_initialize(40000000);
@@ -38,7 +43,7 @@ static void __init at91eb01_map_io(void)
 MACHINE_START(AT91EB01, "Atmel AT91 EB01")
        /* Maintainer: Greg Ungerer <gerg@snapgear.com> */
        .timer          = &at91x40_timer,
-       .init_irq       = at91x40_init_interrupts,
+       .init_irq       = at91eb01_init_irq,
        .map_io         = at91eb01_map_io,
 MACHINE_END
 
index 3bef931..0700f21 100644 (file)
@@ -27,6 +27,7 @@
 #define ARCH_ID_AT91SAM9G45    0x819b05a0
 #define ARCH_ID_AT91SAM9G45MRL 0x819b05a2      /* aka 9G45-ES2 & non ES lots */
 #define ARCH_ID_AT91SAM9G45ES  0x819b05a1      /* 9G45-ES (Engineering Sample) */
+#define ARCH_ID_AT91SAM9X5     0x819a05a0
 #define ARCH_ID_AT91CAP9       0x039A03A0
 
 #define ARCH_ID_AT91SAM9XE128  0x329973a0
@@ -55,6 +56,12 @@ static inline unsigned long at91_cpu_fully_identify(void)
 #define ARCH_EXID_AT91SAM9G46  0x00000003
 #define ARCH_EXID_AT91SAM9G45  0x00000004
 
+#define ARCH_EXID_AT91SAM9G15  0x00000000
+#define ARCH_EXID_AT91SAM9G35  0x00000001
+#define ARCH_EXID_AT91SAM9X35  0x00000002
+#define ARCH_EXID_AT91SAM9G25  0x00000003
+#define ARCH_EXID_AT91SAM9X25  0x00000004
+
 static inline unsigned long at91_exid_identify(void)
 {
        return at91_sys_read(AT91_DBGU_EXID);
@@ -143,6 +150,27 @@ static inline unsigned long at91cap9_rev_identify(void)
 #define cpu_is_at91sam9m11()   (0)
 #endif
 
+#ifdef CONFIG_ARCH_AT91SAM9X5
+#define cpu_is_at91sam9x5()    (at91_cpu_identify() == ARCH_ID_AT91SAM9X5)
+#define cpu_is_at91sam9g15()   (cpu_is_at91sam9x5() && \
+                               (at91_exid_identify() == ARCH_EXID_AT91SAM9G15))
+#define cpu_is_at91sam9g35()   (cpu_is_at91sam9x5() && \
+                               (at91_exid_identify() == ARCH_EXID_AT91SAM9G35))
+#define cpu_is_at91sam9x35()   (cpu_is_at91sam9x5() && \
+                               (at91_exid_identify() == ARCH_EXID_AT91SAM9X35))
+#define cpu_is_at91sam9g25()   (cpu_is_at91sam9x5() && \
+                               (at91_exid_identify() == ARCH_EXID_AT91SAM9G25))
+#define cpu_is_at91sam9x25()   (cpu_is_at91sam9x5() && \
+                               (at91_exid_identify() == ARCH_EXID_AT91SAM9X25))
+#else
+#define cpu_is_at91sam9x5()    (0)
+#define cpu_is_at91sam9g15()   (0)
+#define cpu_is_at91sam9g35()   (0)
+#define cpu_is_at91sam9x35()   (0)
+#define cpu_is_at91sam9g25()   (0)
+#define cpu_is_at91sam9x25()   (0)
+#endif
+
 #ifdef CONFIG_ARCH_AT91CAP9
 #define cpu_is_at91cap9()      (at91_cpu_identify() == ARCH_ID_AT91CAP9)
 #define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
index 32f1479..c0deaca 100644 (file)
@@ -63,6 +63,7 @@ config MACH_DAVINCI_EVM
        depends on ARCH_DAVINCI_DM644x
        select MISC_DEVICES
        select EEPROM_AT24
+       select I2C
        help
          Configure this option to specify the whether the board used
          for development is a DM644x EVM
@@ -72,6 +73,7 @@ config MACH_SFFSDR
        depends on ARCH_DAVINCI_DM644x
        select MISC_DEVICES
        select EEPROM_AT24
+       select I2C
        help
          Say Y here to select the Lyrtech Small Form Factor
          Software Defined Radio (SFFSDR) board.
@@ -105,6 +107,7 @@ config MACH_DAVINCI_DM6467_EVM
        select MACH_DAVINCI_DM6467TEVM
        select MISC_DEVICES
        select EEPROM_AT24
+       select I2C
        help
          Configure this option to specify the whether the board used
          for development is a DM6467 EVM
@@ -118,6 +121,7 @@ config MACH_DAVINCI_DM365_EVM
        depends on ARCH_DAVINCI_DM365
        select MISC_DEVICES
        select EEPROM_AT24
+       select I2C
        help
          Configure this option to specify whether the board used
          for development is a DM365 EVM
@@ -129,6 +133,7 @@ config MACH_DAVINCI_DA830_EVM
        select GPIO_PCF857X
        select MISC_DEVICES
        select EEPROM_AT24
+       select I2C
        help
          Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
 
@@ -205,6 +210,7 @@ config MACH_MITYOMAPL138
        depends on ARCH_DAVINCI_DA850
        select MISC_DEVICES
        select EEPROM_AT24
+       select I2C
        help
          Say Y here to select the Critical Link MityDSP-L138/MityARM-1808
          System on Module.  Information on this SoM may be found at
index 2aa79c5..606a6f2 100644 (file)
@@ -29,7 +29,7 @@
 #include <mach/mux.h>
 #include <mach/spi.h>
 
-#define MITYOMAPL138_PHY_ID            "0:03"
+#define MITYOMAPL138_PHY_ID            ""
 
 #define FACTORY_CONFIG_MAGIC   0x012C0138
 #define FACTORY_CONFIG_VERSION 0x00010001
@@ -414,7 +414,7 @@ static struct resource mityomapl138_nandflash_resource[] = {
 
 static struct platform_device mityomapl138_nandflash_device = {
        .name           = "davinci_nand",
-       .id             = 0,
+       .id             = 1,
        .dev            = {
                .platform_data  = &mityomapl138_nandflash_data,
        },
index 625d4b6..58a02dc 100644 (file)
@@ -39,7 +39,8 @@
 #define DA8XX_GPIO_BASE                        0x01e26000
 #define DA8XX_I2C1_BASE                        0x01e28000
 #define DA8XX_SPI0_BASE                        0x01c41000
-#define DA8XX_SPI1_BASE                        0x01f0e000
+#define DA830_SPI1_BASE                        0x01e12000
+#define DA850_SPI1_BASE                        0x01f0e000
 
 #define DA8XX_EMAC_CTRL_REG_OFFSET     0x3000
 #define DA8XX_EMAC_MOD_REG_OFFSET      0x2000
@@ -762,8 +763,8 @@ static struct resource da8xx_spi0_resources[] = {
 
 static struct resource da8xx_spi1_resources[] = {
        [0] = {
-               .start  = DA8XX_SPI1_BASE,
-               .end    = DA8XX_SPI1_BASE + SZ_4K - 1,
+               .start  = DA830_SPI1_BASE,
+               .end    = DA830_SPI1_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -832,5 +833,10 @@ int __init da8xx_register_spi(int instance, struct spi_board_info *info,
 
        da8xx_spi_pdata[instance].num_chipselect = len;
 
+       if (instance == 1 && cpu_is_davinci_da850()) {
+               da8xx_spi1_resources[0].start = DA850_SPI1_BASE;
+               da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1;
+       }
+
        return platform_device_register(&da8xx_spi_device[instance]);
 }
index f680122..a3a94e9 100644 (file)
@@ -314,7 +314,7 @@ static struct clk timer2_clk = {
        .name = "timer2",
        .parent = &pll1_aux_clk,
        .lpsc = DAVINCI_LPSC_TIMER2,
-       .usecount = 1,              /* REVISIT: why can't' this be disabled? */
+       .usecount = 1,              /* REVISIT: why can't this be disabled? */
 };
 
 static struct clk timer3_clk = {
index 5f8a654..4c82c27 100644 (file)
@@ -274,7 +274,7 @@ static struct clk timer2_clk = {
        .name = "timer2",
        .parent = &pll1_aux_clk,
        .lpsc = DAVINCI_LPSC_TIMER2,
-       .usecount = 1,              /* REVISIT: why can't' this be disabled? */
+       .usecount = 1,              /* REVISIT: why can't this be disabled? */
 };
 
 static struct clk_lookup dm644x_clks[] = {
index 9f1befc..f8b7ea4 100644 (file)
@@ -24,6 +24,9 @@
 
 #define UART_SHIFT     2
 
+#define davinci_uart_v2p(x)    ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET)
+#define davinci_uart_p2v(x)    ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
                .pushsection .data
 davinci_uart_phys:     .word   0
 davinci_uart_virt:     .word   0
@@ -34,7 +37,7 @@ davinci_uart_virt:    .word   0
                /* Use davinci_uart_phys/virt if already configured */
 10:            mrc     p15, 0, \rp, c1, c0
                tst     \rp, #1                 @ MMU enabled?
-               ldreq   \rp, =__virt_to_phys(davinci_uart_phys)
+               ldreq   \rp, =davinci_uart_v2p(davinci_uart_phys)
                ldrne   \rp, =davinci_uart_phys
                add     \rv, \rp, #4            @ davinci_uart_virt
                ldr     \rp, [\rp, #0]
@@ -48,18 +51,18 @@ davinci_uart_virt:  .word   0
                tst     \rp, #1                 @ MMU enabled?
 
                /* Copy uart phys address from decompressor uart info */
-               ldreq   \rv, =__virt_to_phys(davinci_uart_phys)
+               ldreq   \rv, =davinci_uart_v2p(davinci_uart_phys)
                ldrne   \rv, =davinci_uart_phys
                ldreq   \rp, =DAVINCI_UART_INFO
-               ldrne   \rp, =__phys_to_virt(DAVINCI_UART_INFO)
+               ldrne   \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
                ldr     \rp, [\rp, #0]
                str     \rp, [\rv]
 
                /* Copy uart virt address from decompressor uart info */
-               ldreq   \rv, =__virt_to_phys(davinci_uart_virt)
+               ldreq   \rv, =davinci_uart_v2p(davinci_uart_virt)
                ldrne   \rv, =davinci_uart_virt
                ldreq   \rp, =DAVINCI_UART_INFO
-               ldrne   \rp, =__phys_to_virt(DAVINCI_UART_INFO)
+               ldrne   \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
                ldr     \rp, [\rp, #4]
                str     \rp, [\rv]
 
index 8051110..c9e6ce1 100644 (file)
@@ -22,7 +22,7 @@
  *
  * This area sits just below the page tables (see arch/arm/kernel/head.S).
  */
-#define DAVINCI_UART_INFO      (PHYS_OFFSET + 0x3ff8)
+#define DAVINCI_UART_INFO      (PLAT_PHYS_OFFSET + 0x3ff8)
 
 #define DAVINCI_UART0_BASE     (IO_PHYS + 0x20000)
 #define DAVINCI_UART1_BASE     (IO_PHYS + 0x20400)
index 2cf390f..47a69cb 100644 (file)
@@ -257,11 +257,16 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
        .workaround     = FLS_USB2_WORKAROUND_ENGCM09152,
 };
 
+static int vpr200_usbh_init(struct platform_device *pdev)
+{
+       return mx35_initialize_usb_hw(pdev->id,
+                       MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY);
+}
+
 /* USB HOST config */
 static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
-       .portsc         = MXC_EHCI_MODE_SERIAL,
-       .flags          = MXC_EHCI_INTERFACE_SINGLE_UNI |
-                         MXC_EHCI_INTERNAL_PHY,
+       .init = vpr200_usbh_init,
+       .portsc = MXC_EHCI_MODE_SERIAL,
 };
 
 static struct platform_device *devices[] __initdata = {
index 10a1bea..6206b11 100644 (file)
@@ -193,7 +193,7 @@ static iomux_v3_cfg_t mx53_loco_pads[] = {
        .wakeup         = wake,                                 \
 }
 
-static const struct gpio_keys_button loco_buttons[] __initconst = {
+static struct gpio_keys_button loco_buttons[] = {
        GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0),
        GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
        GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
index 1ad97fe..5dcc59d 100644 (file)
@@ -295,11 +295,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)           \
        unsigned long diff, parent_rate, calc_rate;                     \
        int i;                                                          \
                                                                        \
-       parent_rate = clk_get_rate(clk->parent);                        \
        div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;       \
        bm_busy = BM_CLKCTRL_##dr##_BUSY;                               \
                                                                        \
        if (clk->parent == &ref_xtal_clk) {                             \
+               parent_rate = clk_get_rate(clk->parent);                \
                div = DIV_ROUND_UP(parent_rate, rate);                  \
                if (clk == &cpu_clk) {                                  \
                        div_max = BM_CLKCTRL_CPU_DIV_XTAL >>            \
@@ -309,6 +309,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)            \
                if (div == 0 || div > div_max)                          \
                        return -EINVAL;                                 \
        } else {                                                        \
+               /*                                                      \
+                * hack alert: this block modifies clk->parent, too,    \
+                * so the base to use it the grand parent.              \
+                */                                                     \
+               parent_rate = clk_get_rate(clk->parent->parent);        \
                rate >>= PARENT_RATE_SHIFT;                             \
                parent_rate >>= PARENT_RATE_SHIFT;                      \
                diff = parent_rate;                                     \
index a45cd64..512b152 100644 (file)
@@ -68,7 +68,7 @@ obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
 obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)  += smartreflex-class3.o
 
 AFLAGS_sleep24xx.o                     :=-Wa,-march=armv6
-AFLAGS_sleep34xx.o                     :=-Wa,-march=armv7-a
+AFLAGS_sleep34xx.o                     :=-Wa,-march=armv7-a$(plus_sec)
 
 ifeq ($(CONFIG_PM_VERBOSE),y)
 CFLAGS_pm_bus.o                                += -DDEBUG
index e964895..f8ba20a 100644 (file)
@@ -141,14 +141,19 @@ static void __init rx51_init(void)
 static void __init rx51_map_io(void)
 {
        omap2_set_globals_3xxx();
-       rx51_video_mem_init();
        omap34xx_map_common_io();
 }
 
+static void __init rx51_reserve(void)
+{
+       rx51_video_mem_init();
+       omap_reserve();
+}
+
 MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
        /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
        .boot_params    = 0x80000100,
-       .reserve        = omap_reserve,
+       .reserve        = rx51_reserve,
        .map_io         = rx51_map_io,
        .init_early     = rx51_init_early,
        .init_irq       = omap_init_irq,
index 276992d..8c96567 100644 (file)
@@ -3116,14 +3116,9 @@ static struct omap_clk omap44xx_clks[] = {
        CLK(NULL,       "dsp_fck",                      &dsp_fck,       CK_443X),
        CLK("omapdss_dss",      "sys_clk",                      &dss_sys_clk,   CK_443X),
        CLK("omapdss_dss",      "tv_clk",                       &dss_tv_clk,    CK_443X),
-       CLK("omapdss_dss",      "dss_clk",                      &dss_dss_clk,   CK_443X),
        CLK("omapdss_dss",      "video_clk",                    &dss_48mhz_clk, CK_443X),
-       CLK("omapdss_dss",      "fck",                          &dss_fck,       CK_443X),
-       /*
-        * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility
-        * with OMAP2/3.
-        */
-       CLK("omapdss_dss",      "ick",                          &dummy_ck,      CK_443X),
+       CLK("omapdss_dss",      "fck",                          &dss_dss_clk,   CK_443X),
+       CLK("omapdss_dss",      "ick",                          &dss_fck,       CK_443X),
        CLK(NULL,       "efuse_ctrl_cust_fck",          &efuse_ctrl_cust_fck,   CK_443X),
        CLK(NULL,       "emif1_fck",                    &emif1_fck,     CK_443X),
        CLK(NULL,       "emif2_fck",                    &emif2_fck,     CK_443X),
index 9d0dec8..38830d8 100644 (file)
@@ -247,6 +247,7 @@ struct omap3_cm_regs {
        u32 per_cm_clksel;
        u32 emu_cm_clksel;
        u32 emu_cm_clkstctrl;
+       u32 pll_cm_autoidle;
        u32 pll_cm_autoidle2;
        u32 pll_cm_clksel4;
        u32 pll_cm_clksel5;
@@ -319,6 +320,15 @@ void omap3_cm_save_context(void)
                omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
        cm_context.emu_cm_clkstctrl =
                omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
+       /*
+        * As per erratum i671, ROM code does not respect the PER DPLL
+        * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
+        * In this case, even though this register has been saved in
+        * scratchpad contents, we need to restore AUTO_PERIPH_DPLL
+        * by ourselves. So, we need to save it anyway.
+        */
+       cm_context.pll_cm_autoidle =
+               omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
        cm_context.pll_cm_autoidle2 =
                omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
        cm_context.pll_cm_clksel4 =
@@ -441,6 +451,13 @@ void omap3_cm_restore_context(void)
                               CM_CLKSEL1);
        omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
                               OMAP2_CM_CLKSTCTRL);
+       /*
+        * As per erratum i671, ROM code does not respect the PER DPLL
+        * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
+        * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves.
+        */
+       omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD,
+                              CM_AUTOIDLE);
        omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
                               CM_AUTOIDLE2);
        omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
index 6952794..da53ba3 100644 (file)
@@ -316,8 +316,14 @@ void omap3_save_scratchpad_contents(void)
                        omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
        prcm_block_contents.cm_clken_pll =
                        omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+       /*
+        * As per erratum i671, ROM code does not respect the PER DPLL
+        * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
+        * Then,  in anycase, clear these bits to avoid extra latencies.
+        */
        prcm_block_contents.cm_autoidle_pll =
-                       omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+                       omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
+                       ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
        prcm_block_contents.cm_clksel1_pll =
                        omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
        prcm_block_contents.cm_clksel2_pll =
index 8eb3ce1..c4d0ae8 100644 (file)
@@ -1639,6 +1639,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = {
 
 static struct omap_hwmod omap2420_gpio1_hwmod = {
        .name           = "gpio1",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap242x_gpio1_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap242x_gpio1_irqs),
        .main_clk       = "gpios_fck",
@@ -1669,6 +1670,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = {
 
 static struct omap_hwmod omap2420_gpio2_hwmod = {
        .name           = "gpio2",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap242x_gpio2_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap242x_gpio2_irqs),
        .main_clk       = "gpios_fck",
@@ -1699,6 +1701,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = {
 
 static struct omap_hwmod omap2420_gpio3_hwmod = {
        .name           = "gpio3",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap242x_gpio3_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap242x_gpio3_irqs),
        .main_clk       = "gpios_fck",
@@ -1729,6 +1732,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = {
 
 static struct omap_hwmod omap2420_gpio4_hwmod = {
        .name           = "gpio4",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap242x_gpio4_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap242x_gpio4_irqs),
        .main_clk       = "gpios_fck",
@@ -1782,7 +1786,7 @@ static struct omap_hwmod_irq_info omap2420_dma_system_irqs[] = {
 static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = {
        {
                .pa_start       = 0x48056000,
-               .pa_end         = 0x4a0560ff,
+               .pa_end         = 0x48056fff,
                .flags          = ADDR_TYPE_RT
        },
 };
index e6e3810..9682dd5 100644 (file)
@@ -1742,6 +1742,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = {
 
 static struct omap_hwmod omap2430_gpio1_hwmod = {
        .name           = "gpio1",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap243x_gpio1_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap243x_gpio1_irqs),
        .main_clk       = "gpios_fck",
@@ -1772,6 +1773,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = {
 
 static struct omap_hwmod omap2430_gpio2_hwmod = {
        .name           = "gpio2",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap243x_gpio2_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap243x_gpio2_irqs),
        .main_clk       = "gpios_fck",
@@ -1802,6 +1804,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = {
 
 static struct omap_hwmod omap2430_gpio3_hwmod = {
        .name           = "gpio3",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap243x_gpio3_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap243x_gpio3_irqs),
        .main_clk       = "gpios_fck",
@@ -1832,6 +1835,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = {
 
 static struct omap_hwmod omap2430_gpio4_hwmod = {
        .name           = "gpio4",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap243x_gpio4_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap243x_gpio4_irqs),
        .main_clk       = "gpios_fck",
@@ -1862,6 +1866,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = {
 
 static struct omap_hwmod omap2430_gpio5_hwmod = {
        .name           = "gpio5",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap243x_gpio5_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap243x_gpio5_irqs),
        .main_clk       = "gpio5_fck",
@@ -1915,7 +1920,7 @@ static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = {
 static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = {
        {
                .pa_start       = 0x48056000,
-               .pa_end         = 0x4a0560ff,
+               .pa_end         = 0x48056fff,
                .flags          = ADDR_TYPE_RT
        },
 };
index b98e2df..909a84d 100644 (file)
@@ -2141,6 +2141,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = {
 
 static struct omap_hwmod omap3xxx_gpio1_hwmod = {
        .name           = "gpio1",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap3xxx_gpio1_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap3xxx_gpio1_irqs),
        .main_clk       = "gpio1_ick",
@@ -2177,6 +2178,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = {
 
 static struct omap_hwmod omap3xxx_gpio2_hwmod = {
        .name           = "gpio2",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap3xxx_gpio2_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap3xxx_gpio2_irqs),
        .main_clk       = "gpio2_ick",
@@ -2213,6 +2215,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = {
 
 static struct omap_hwmod omap3xxx_gpio3_hwmod = {
        .name           = "gpio3",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap3xxx_gpio3_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap3xxx_gpio3_irqs),
        .main_clk       = "gpio3_ick",
@@ -2249,6 +2252,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = {
 
 static struct omap_hwmod omap3xxx_gpio4_hwmod = {
        .name           = "gpio4",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap3xxx_gpio4_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap3xxx_gpio4_irqs),
        .main_clk       = "gpio4_ick",
@@ -2285,6 +2289,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = {
 
 static struct omap_hwmod omap3xxx_gpio5_hwmod = {
        .name           = "gpio5",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap3xxx_gpio5_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap3xxx_gpio5_irqs),
        .main_clk       = "gpio5_ick",
@@ -2321,6 +2326,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = {
 
 static struct omap_hwmod omap3xxx_gpio6_hwmod = {
        .name           = "gpio6",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .mpu_irqs       = omap3xxx_gpio6_irqs,
        .mpu_irqs_cnt   = ARRAY_SIZE(omap3xxx_gpio6_irqs),
        .main_clk       = "gpio6_ick",
@@ -2386,7 +2392,7 @@ static struct omap_hwmod_irq_info omap3xxx_dma_system_irqs[] = {
 static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = {
        {
                .pa_start       = 0x48056000,
-               .pa_end         = 0x4a0560ff,
+               .pa_end         = 0x48056fff,
                .flags          = ADDR_TYPE_RT
        },
 };
index 3e88dd3..abc548a 100644 (file)
@@ -885,7 +885,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dma_system_masters[] = {
 static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = {
        {
                .pa_start       = 0x4a056000,
-               .pa_end         = 0x4a0560ff,
+               .pa_end         = 0x4a056fff,
                .flags          = ADDR_TYPE_RT
        },
 };
index 5f2da75..4321e79 100644 (file)
@@ -196,11 +196,11 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3)
                /* No timeout error for debug sources */
        }
 
-       base = ((l3->rt) + (*(omap3_l3_bases[int_type] + err_source)));
-
        /* identify the error source */
        for (err_source = 0; !(status & (1 << err_source)); err_source++)
                                                                        ;
+
+       base = l3->rt + *(omap3_l3_bases[int_type] + err_source);
        error = omap3_l3_readll(base, L3_ERROR_LOG);
 
        if (error) {
index 30af335..49486f5 100644 (file)
@@ -89,6 +89,7 @@ static void omap2_init_processor_devices(void)
        if (cpu_is_omap44xx()) {
                _init_omap_device("l3_main_1", &l3_dev);
                _init_omap_device("dsp", &dsp_dev);
+               _init_omap_device("iva", &iva_dev);
        } else {
                _init_omap_device("l3_main", &l3_dev);
        }
index 6fb5209..0c1552d 100644 (file)
@@ -114,7 +114,6 @@ static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)
        sys_clk_speed /= 1000;
 
        /* Generic voltage parameters */
-       vdd->curr_volt = 1200000;
        vdd->volt_scale = vp_forceupdate_scale_voltage;
        vdd->vp_enabled = false;
 
index 6de0ad0..9cdcca5 100644 (file)
@@ -711,7 +711,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
 static struct regulator_init_data bq24022_init_data = {
        .constraints = {
                .max_uA         = 500000,
-               .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+               .valid_ops_mask = REGULATOR_CHANGE_CURRENT|REGULATOR_CHANGE_STATUS,
        },
        .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
        .consumer_supplies      = bq24022_consumers,
index a72993d..9984ef7 100644 (file)
@@ -599,7 +599,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
 static struct regulator_init_data bq24022_init_data = {
        .constraints = {
                .max_uA         = 500000,
-               .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+               .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
        },
        .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
        .consumer_supplies      = bq24022_consumers,
index 0db2411..7166620 100644 (file)
@@ -409,6 +409,10 @@ struct platform_device s3c24xx_pwm_device = {
        .num_resources  = 0,
 };
 
+static struct platform_device gta02_dfbmcs320_device = {
+       .name = "dfbmcs320",
+};
+
 static struct i2c_board_info gta02_i2c_devs[] __initdata = {
        {
                I2C_BOARD_INFO("pcf50633", 0x73),
@@ -523,6 +527,7 @@ static struct platform_device *gta02_devices[] __initdata = {
        &s3c_device_iis,
        &samsung_asoc_dma,
        &s3c_device_i2c0,
+       &gta02_dfbmcs320_device,
        &gta02_buttons_device,
        &s3c_device_adc,
        &s3c_device_ts,
index af91374..6e1907f 100644 (file)
@@ -178,16 +178,15 @@ static struct i2c_board_info __initdata mop500_i2c0_devices[] = {
                .irq            = NOMADIK_GPIO_TO_IRQ(217),
                .platform_data  = &mop500_tc35892_data,
        },
-};
-
-/* I2C0 devices only available prior to HREFv60 */
-static struct i2c_board_info __initdata mop500_i2c0_old_devices[] = {
+       /* I2C0 devices only available prior to HREFv60 */
        {
                I2C_BOARD_INFO("tps61052", 0x33),
                .platform_data  = &mop500_tps61052_data,
        },
 };
 
+#define NUM_PRE_V60_I2C0_DEVICES 1
+
 static struct i2c_board_info __initdata mop500_i2c2_devices[] = {
        {
                /* lp5521 LED driver, 1st device */
@@ -425,6 +424,8 @@ static void __init mop500_uart_init(void)
 
 static void __init mop500_init_machine(void)
 {
+       int i2c0_devs;
+
        /*
         * The HREFv60 board removed a GPIO expander and routed
         * all these GPIO pins to the internal GPIO controller
@@ -448,11 +449,11 @@ static void __init mop500_init_machine(void)
 
        platform_device_register(&ab8500_device);
 
-       i2c_register_board_info(0, mop500_i2c0_devices,
-                               ARRAY_SIZE(mop500_i2c0_devices));
-       if (!machine_is_hrefv60())
-               i2c_register_board_info(0, mop500_i2c0_old_devices,
-                                       ARRAY_SIZE(mop500_i2c0_old_devices));
+       i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
+       if (machine_is_hrefv60())
+               i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES;
+
+       i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
        i2c_register_board_info(2, mop500_i2c2_devices,
                                ARRAY_SIZE(mop500_i2c2_devices));
 }
index ce233bc..42af976 100644 (file)
@@ -395,7 +395,7 @@ ENTRY(xscale_dma_a0_map_area)
        teq     r2, #DMA_TO_DEVICE
        beq     xscale_dma_clean_range
        b       xscale_dma_flush_range
-ENDPROC(xscsale_dma_a0_map_area)
+ENDPROC(xscale_dma_a0_map_area)
 
 /*
  *     dma_unmap_area(start, size, dir)
index 7a10724..6cd6d7f 100644 (file)
@@ -295,6 +295,12 @@ static int mxc_gpio_direction_output(struct gpio_chip *chip,
        return 0;
 }
 
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
 int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
 {
        int i, j;
@@ -311,6 +317,7 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
                __raw_writel(~0, port[i].base + GPIO_ISR);
                for (j = port[i].virtual_irq_start;
                        j < port[i].virtual_irq_start + 32; j++) {
+                       irq_set_lockdep_class(j, &gpio_lock_class);
                        irq_set_chip_and_handler(j, &gpio_irq_chip,
                                                 handle_level_irq);
                        set_irq_flags(j, IRQF_VALID);
index 4ddce56..8397a2d 100644 (file)
@@ -124,6 +124,8 @@ imx_ssi_fiq_start:
 1:
                @ return from FIQ
                subs    pc, lr, #4
+
+               .align
 imx_ssi_fiq_base:
                .word 0x0
 imx_ssi_fiq_rx_buffer:
index 02b7a03..8b3db1c 100644 (file)
@@ -300,6 +300,8 @@ void __init paging_init(void)
                zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
                free_area_init_node(i, zones_size,
                                    m68k_memory[i].addr >> PAGE_SHIFT, NULL);
+               if (node_present_pages(i))
+                       node_set_state(i, N_NORMAL_MEMORY);
        }
 }
 
index b7ed8d7..b1d1262 100644 (file)
@@ -266,8 +266,10 @@ static void __init setup_bootmem(void)
        }
        memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
 
-       for (i = 0; i < npmem_ranges; i++)
+       for (i = 0; i < npmem_ranges; i++) {
+               node_set_state(i, N_NORMAL_MEMORY);
                node_set_online(i);
+       }
 #endif
 
        /*
index 6b6dc20..bdf0563 100644 (file)
@@ -393,8 +393,8 @@ typedef struct fec {
        uint    fec_addr_low;           /* lower 32 bits of station address     */
        ushort  fec_addr_high;          /* upper 16 bits of station address     */
        ushort  res1;                   /* reserved                             */
-       uint    fec_hash_table_high;    /* upper 32-bits of hash table          */
-       uint    fec_hash_table_low;     /* lower 32-bits of hash table          */
+       uint    fec_grp_hash_table_high;        /* upper 32-bits of hash table          */
+       uint    fec_grp_hash_table_low; /* lower 32-bits of hash table          */
        uint    fec_r_des_start;        /* beginning of Rx descriptor ring      */
        uint    fec_x_des_start;        /* beginning of Tx descriptor ring      */
        uint    fec_r_buff_size;        /* Rx buffer size                       */
index ae9c899..d12b11d 100644 (file)
@@ -60,7 +60,7 @@
  *
  * Obviously, the GART is not cache coherent and so any change to it
  * must be flushed to memory (or maybe just make the GART space non
- * cachable). AGP memory itself does't seem to be cache coherent neither.
+ * cachable). AGP memory itself doesn't seem to be cache coherent neither.
  *
  * In order to invalidate the GART (which is probably necessary to inval
  * the bridge internal TLBs), the following sequence has to be written,
index 55613e3..a6ae1cf 100644 (file)
@@ -933,12 +933,16 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
        if (data && !(data & DABR_TRANSLATION))
                return -EIO;
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
+       if (ptrace_get_breakpoints(task) < 0)
+               return -ESRCH;
+
        bp = thread->ptrace_bps[0];
        if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) {
                if (bp) {
                        unregister_hw_breakpoint(bp);
                        thread->ptrace_bps[0] = NULL;
                }
+               ptrace_put_breakpoints(task);
                return 0;
        }
        if (bp) {
@@ -948,9 +952,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
                                        (DABR_DATA_WRITE | DABR_DATA_READ),
                                                        &attr.bp_type);
                ret =  modify_user_hw_breakpoint(bp, &attr);
-               if (ret)
+               if (ret) {
+                       ptrace_put_breakpoints(task);
                        return ret;
+               }
                thread->ptrace_bps[0] = bp;
+               ptrace_put_breakpoints(task);
                thread->dabr = data;
                return 0;
        }
@@ -965,9 +972,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
                                                        ptrace_triggered, task);
        if (IS_ERR(bp)) {
                thread->ptrace_bps[0] = NULL;
+               ptrace_put_breakpoints(task);
                return PTR_ERR(bp);
        }
 
+       ptrace_put_breakpoints(task);
+
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
        /* Move contents to the DABR register */
index 975e3ab..8b16c47 100644 (file)
@@ -76,7 +76,7 @@ static void prng_seed(int nbytes)
 
        /* Add the entropy */
        while (nbytes >= 8) {
-               *((__u64 *)parm_block) ^= *((__u64 *)buf+i*8);
+               *((__u64 *)parm_block) ^= *((__u64 *)(buf+i));
                prng_add_entropy();
                i += 8;
                nbytes -= 8;
index 7e9d30d..ab0e041 100644 (file)
@@ -48,10 +48,10 @@ sie_irq_handler:
        tm      __TI_flags+7(%r2),_TIF_EXIT_SIE
        jz      0f
        larl    %r2,sie_exit                    # work pending, leave sie
-       stg     %r2,__LC_RETURN_PSW+8
+       stg     %r2,SPI_PSW+8(0,%r15)
        br      %r14
 0:     larl    %r2,sie_reenter                 # re-enter with guest id
-       stg     %r2,__LC_RETURN_PSW+8
+       stg     %r2,SPI_PSW+8(0,%r15)
 1:     br      %r14
 
 /*
index 9217e33..ab98813 100644 (file)
@@ -543,7 +543,6 @@ static void pfault_interrupt(unsigned int ext_int_code,
        struct task_struct *tsk;
        __u16 subcode;
 
-       kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
        /*
         * Get the external interruption subcode & pfault
         * initial/completion signal bit. VM stores this 
@@ -553,14 +552,15 @@ static void pfault_interrupt(unsigned int ext_int_code,
        subcode = ext_int_code >> 16;
        if ((subcode & 0xff00) != __SUBCODE_MASK)
                return;
+       kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
 
        /*
         * Get the token (= address of the task structure of the affected task).
         */
 #ifdef CONFIG_64BIT
-       tsk = *(struct task_struct **) param64;
+       tsk = (struct task_struct *) param64;
 #else
-       tsk = *(struct task_struct **) param32;
+       tsk = (struct task_struct *) param32;
 #endif
 
        if (subcode & 0x0080) {
index 122ffbd..0607e4b 100644 (file)
@@ -24,12 +24,13 @@ static void change_page_attr(unsigned long addr, int numpages,
                        WARN_ON_ONCE(1);
                        continue;
                }
-               ptep = pte_offset_kernel(pmdp, addr + i * PAGE_SIZE);
+               ptep = pte_offset_kernel(pmdp, addr);
 
                pte = *ptep;
                pte = set(pte);
-               ptep_invalidate(&init_mm, addr + i * PAGE_SIZE, ptep);
+               ptep_invalidate(&init_mm, addr, ptep);
                *ptep = pte;
+               addr += PAGE_SIZE;
        }
 }
 
index 2130ca6..3d7b209 100644 (file)
@@ -117,7 +117,11 @@ void user_enable_single_step(struct task_struct *child)
 
        set_tsk_thread_flag(child, TIF_SINGLESTEP);
 
+       if (ptrace_get_breakpoints(child) < 0)
+               return;
+
        set_single_step(child, pc);
+       ptrace_put_breakpoints(child);
 }
 
 void user_disable_single_step(struct task_struct *child)
index 90a438a..b5e675e 100644 (file)
@@ -47,7 +47,7 @@ config HOSTFS
 
 config HPPFS
        tristate "HoneyPot ProcFS (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on EXPERIMENTAL && PROC_FS
        help
          hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
          entries to be overridden, removed, or fabricated from the host.
index e2cf786..5bd1bad 100644 (file)
@@ -49,7 +49,10 @@ static inline struct thread_info *current_thread_info(void)
 {
        struct thread_info *ti;
        unsigned long mask = THREAD_SIZE - 1;
-       ti = (struct thread_info *) (((unsigned long) &ti) & ~mask);
+       void *p;
+
+       asm volatile ("" : "=r" (p) : "0" (&ti));
+       ti = (struct thread_info *) (((unsigned long)p) & ~mask);
        return ti;
 }
 
index 804b28d..b1da91c 100644 (file)
@@ -4,7 +4,7 @@
 
 obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
        ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
-       sys_call_table.o tls.o
+       sys_call_table.o tls.o atomic64_cx8_32.o
 
 obj-$(CONFIG_BINFMT_ELF) += elfcore.o
 
diff --git a/arch/um/sys-i386/atomic64_cx8_32.S b/arch/um/sys-i386/atomic64_cx8_32.S
new file mode 100644 (file)
index 0000000..1e901d3
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * atomic64_t for 586+
+ *
+ * Copied from arch/x86/lib/atomic64_cx8_32.S
+ *
+ * Copyright © 2010  Luca Barbieri
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/alternative-asm.h>
+#include <asm/dwarf2.h>
+
+.macro SAVE reg
+       pushl_cfi %\reg
+       CFI_REL_OFFSET \reg, 0
+.endm
+
+.macro RESTORE reg
+       popl_cfi %\reg
+       CFI_RESTORE \reg
+.endm
+
+.macro read64 reg
+       movl %ebx, %eax
+       movl %ecx, %edx
+/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
+       LOCK_PREFIX
+       cmpxchg8b (\reg)
+.endm
+
+ENTRY(atomic64_read_cx8)
+       CFI_STARTPROC
+
+       read64 %ecx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_read_cx8)
+
+ENTRY(atomic64_set_cx8)
+       CFI_STARTPROC
+
+1:
+/* we don't need LOCK_PREFIX since aligned 64-bit writes
+ * are atomic on 586 and newer */
+       cmpxchg8b (%esi)
+       jne 1b
+
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_set_cx8)
+
+ENTRY(atomic64_xchg_cx8)
+       CFI_STARTPROC
+
+       movl %ebx, %eax
+       movl %ecx, %edx
+1:
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_xchg_cx8)
+
+.macro addsub_return func ins insc
+ENTRY(atomic64_\func\()_return_cx8)
+       CFI_STARTPROC
+       SAVE ebp
+       SAVE ebx
+       SAVE esi
+       SAVE edi
+
+       movl %eax, %esi
+       movl %edx, %edi
+       movl %ecx, %ebp
+
+       read64 %ebp
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       \ins\()l %esi, %ebx
+       \insc\()l %edi, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%ebp)
+       jne 1b
+
+10:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE edi
+       RESTORE esi
+       RESTORE ebx
+       RESTORE ebp
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_return_cx8)
+.endm
+
+addsub_return add add adc
+addsub_return sub sub sbb
+
+.macro incdec_return func ins insc
+ENTRY(atomic64_\func\()_return_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       \ins\()l $1, %ebx
+       \insc\()l $0, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+10:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE ebx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_return_cx8)
+.endm
+
+incdec_return inc add adc
+incdec_return dec sub sbb
+
+ENTRY(atomic64_dec_if_positive_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       subl $1, %ebx
+       sbb $0, %ecx
+       js 2f
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+2:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE ebx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_dec_if_positive_cx8)
+
+ENTRY(atomic64_add_unless_cx8)
+       CFI_STARTPROC
+       SAVE ebp
+       SAVE ebx
+/* these just push these two parameters on the stack */
+       SAVE edi
+       SAVE esi
+
+       movl %ecx, %ebp
+       movl %eax, %esi
+       movl %edx, %edi
+
+       read64 %ebp
+1:
+       cmpl %eax, 0(%esp)
+       je 4f
+2:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       addl %esi, %ebx
+       adcl %edi, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%ebp)
+       jne 1b
+
+       movl $1, %eax
+3:
+       addl $8, %esp
+       CFI_ADJUST_CFA_OFFSET -8
+       RESTORE ebx
+       RESTORE ebp
+       ret
+4:
+       cmpl %edx, 4(%esp)
+       jne 2b
+       xorl %eax, %eax
+       jmp 3b
+       CFI_ENDPROC
+ENDPROC(atomic64_add_unless_cx8)
+
+ENTRY(atomic64_inc_not_zero_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       testl %eax, %eax
+       je 4f
+2:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       addl $1, %ebx
+       adcl $0, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+       movl $1, %eax
+3:
+       RESTORE ebx
+       ret
+4:
+       testl %edx, %edx
+       jne 2b
+       jmp 3b
+       CFI_ENDPROC
+ENDPROC(atomic64_inc_not_zero_cx8)
index cae3feb..db75d07 100644 (file)
@@ -91,7 +91,7 @@ static int detect_memory_e801(void)
        if (oreg.ax > 15*1024) {
                return -1;      /* Bogus! */
        } else if (oreg.ax == 15*1024) {
-               boot_params.alt_mem_k = (oreg.dx << 6) + oreg.ax;
+               boot_params.alt_mem_k = (oreg.bx << 6) + oreg.ax;
        } else {
                /*
                 * This ignores memory above 16MB if we have a memory
index c4bd267..a97a240 100644 (file)
@@ -150,7 +150,7 @@ void setup_IO_APIC_irq_extra(u32 gsi);
 extern void ioapic_and_gsi_init(void);
 extern void ioapic_insert_resources(void);
 
-int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr);
+int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
 
 extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
 extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
index 68df09b..45fd33d 100644 (file)
@@ -128,8 +128,8 @@ static int __init parse_noapic(char *str)
 }
 early_param("noapic", parse_noapic);
 
-static int io_apic_setup_irq_pin_once(unsigned int irq, int node,
-                                     struct io_apic_irq_attr *attr);
+static int io_apic_setup_irq_pin(unsigned int irq, int node,
+                                struct io_apic_irq_attr *attr);
 
 /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
 void mp_save_irq(struct mpc_intsrc *m)
@@ -3570,7 +3570,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
 }
 #endif /* CONFIG_HT_IRQ */
 
-int
+static int
 io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
 {
        struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node);
@@ -3585,8 +3585,8 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
        return ret;
 }
 
-static int io_apic_setup_irq_pin_once(unsigned int irq, int node,
-                                     struct io_apic_irq_attr *attr)
+int io_apic_setup_irq_pin_once(unsigned int irq, int node,
+                              struct io_apic_irq_attr *attr)
 {
        unsigned int id = attr->ioapic, pin = attr->ioapic_pin;
        int ret;
index 0b4be43..adee12e 100644 (file)
 #include <linux/kthread.h>
 #include <linux/jiffies.h>
 #include <linux/acpi.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -1238,6 +1239,7 @@ static int suspend(int vetoable)
 
        local_irq_disable();
        sysdev_suspend(PMSG_SUSPEND);
+       syscore_suspend();
 
        local_irq_enable();
 
@@ -1255,6 +1257,7 @@ static int suspend(int vetoable)
                apm_error("suspend", err);
        err = (err == APM_SUCCESS) ? 0 : -EIO;
 
+       syscore_resume();
        sysdev_resume();
        local_irq_enable();
 
@@ -1280,6 +1283,7 @@ static void standby(void)
 
        local_irq_disable();
        sysdev_suspend(PMSG_SUSPEND);
+       syscore_suspend();
        local_irq_enable();
 
        err = set_system_power_state(APM_STATE_STANDBY);
@@ -1287,6 +1291,7 @@ static void standby(void)
                apm_error("standby", err);
 
        local_irq_disable();
+       syscore_resume();
        sysdev_resume();
        local_irq_enable();
 
index 3532d3b..bb9eb29 100644 (file)
@@ -698,7 +698,7 @@ cpu_dev_register(amd_cpu_dev);
  */
 
 const int amd_erratum_400[] =
-       AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),
+       AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0x0f, 0x4, 0x2, 0xff, 0xf),
                            AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
 EXPORT_SYMBOL_GPL(amd_erratum_400);
 
index 632e5dc..e638689 100644 (file)
@@ -613,8 +613,8 @@ static int x86_setup_perfctr(struct perf_event *event)
        /*
         * Branch tracing:
         */
-       if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
-           (hwc->sample_period == 1)) {
+       if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
+           !attr->freq && hwc->sample_period == 1) {
                /* BTS is not supported by this architecture. */
                if (!x86_pmu.bts_active)
                        return -EOPNOTSUPP;
@@ -1288,6 +1288,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
 
        cpuc = &__get_cpu_var(cpu_hw_events);
 
+       /*
+        * Some chipsets need to unmask the LVTPC in a particular spot
+        * inside the nmi handler.  As a result, the unmasking was pushed
+        * into all the nmi handlers.
+        *
+        * This generic handler doesn't seem to have any issues where the
+        * unmasking occurs so it was left at the top.
+        */
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
+
        for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                if (!test_bit(idx, cpuc->active_mask)) {
                        /*
@@ -1374,8 +1384,6 @@ perf_event_nmi_handler(struct notifier_block *self,
                return NOTIFY_DONE;
        }
 
-       apic_write(APIC_LVTPC, APIC_DM_NMI);
-
        handled = x86_pmu.handle_irq(args->regs);
        if (!handled)
                return NOTIFY_DONE;
index 43fa20b..447a28d 100644 (file)
@@ -25,7 +25,7 @@ struct intel_percore {
 /*
  * Intel PerfMon, used on Core and later.
  */
-static const u64 intel_perfmon_event_map[] =
+static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
 {
   [PERF_COUNT_HW_CPU_CYCLES]           = 0x003c,
   [PERF_COUNT_HW_INSTRUCTIONS]         = 0x00c0,
@@ -184,26 +184,23 @@ static __initconst const u64 snb_hw_cache_event_ids
        },
  },
  [ C(LL  ) ] = {
-       /*
-        * TBD: Need Off-core Response Performance Monitoring support
-        */
        [ C(OP_READ) ] = {
-               /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */
+               /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
                [ C(RESULT_ACCESS) ] = 0x01b7,
-               /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */
-               [ C(RESULT_MISS)   ] = 0x01bb,
+               /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+               [ C(RESULT_MISS)   ] = 0x01b7,
        },
        [ C(OP_WRITE) ] = {
-               /* OFFCORE_RESPONSE_0.ANY_RFO.LOCAL_CACHE */
+               /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
                [ C(RESULT_ACCESS) ] = 0x01b7,
-               /* OFFCORE_RESPONSE_1.ANY_RFO.ANY_LLC_MISS */
-               [ C(RESULT_MISS)   ] = 0x01bb,
+               /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+               [ C(RESULT_MISS)   ] = 0x01b7,
        },
        [ C(OP_PREFETCH) ] = {
-               /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */
+               /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
                [ C(RESULT_ACCESS) ] = 0x01b7,
-               /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */
-               [ C(RESULT_MISS)   ] = 0x01bb,
+               /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+               [ C(RESULT_MISS)   ] = 0x01b7,
        },
  },
  [ C(DTLB) ] = {
@@ -285,26 +282,26 @@ static __initconst const u64 westmere_hw_cache_event_ids
  },
  [ C(LL  ) ] = {
        [ C(OP_READ) ] = {
-               /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */
+               /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
                [ C(RESULT_ACCESS) ] = 0x01b7,
-               /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */
-               [ C(RESULT_MISS)   ] = 0x01bb,
+               /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+               [ C(RESULT_MISS)   ] = 0x01b7,
        },
        /*
         * Use RFO, not WRITEBACK, because a write miss would typically occur
         * on RFO.
         */
        [ C(OP_WRITE) ] = {
-               /* OFFCORE_RESPONSE_1.ANY_RFO.LOCAL_CACHE */
-               [ C(RESULT_ACCESS) ] = 0x01bb,
-               /* OFFCORE_RESPONSE_0.ANY_RFO.ANY_LLC_MISS */
+               /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+               [ C(RESULT_ACCESS) ] = 0x01b7,
+               /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
                [ C(RESULT_MISS)   ] = 0x01b7,
        },
        [ C(OP_PREFETCH) ] = {
-               /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */
+               /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
                [ C(RESULT_ACCESS) ] = 0x01b7,
-               /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */
-               [ C(RESULT_MISS)   ] = 0x01bb,
+               /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+               [ C(RESULT_MISS)   ] = 0x01b7,
        },
  },
  [ C(DTLB) ] = {
@@ -352,16 +349,36 @@ static __initconst const u64 westmere_hw_cache_event_ids
 };
 
 /*
- * OFFCORE_RESPONSE MSR bits (subset), See IA32 SDM Vol 3 30.6.1.3
+ * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits;
+ * See IA32 SDM Vol 3B 30.6.1.3
  */
 
-#define DMND_DATA_RD     (1 << 0)
-#define DMND_RFO         (1 << 1)
-#define DMND_WB          (1 << 3)
-#define PF_DATA_RD       (1 << 4)
-#define PF_DATA_RFO      (1 << 5)
-#define RESP_UNCORE_HIT  (1 << 8)
-#define RESP_MISS        (0xf600) /* non uncore hit */
+#define NHM_DMND_DATA_RD       (1 << 0)
+#define NHM_DMND_RFO           (1 << 1)
+#define NHM_DMND_IFETCH                (1 << 2)
+#define NHM_DMND_WB            (1 << 3)
+#define NHM_PF_DATA_RD         (1 << 4)
+#define NHM_PF_DATA_RFO                (1 << 5)
+#define NHM_PF_IFETCH          (1 << 6)
+#define NHM_OFFCORE_OTHER      (1 << 7)
+#define NHM_UNCORE_HIT         (1 << 8)
+#define NHM_OTHER_CORE_HIT_SNP (1 << 9)
+#define NHM_OTHER_CORE_HITM    (1 << 10)
+                               /* reserved */
+#define NHM_REMOTE_CACHE_FWD   (1 << 12)
+#define NHM_REMOTE_DRAM                (1 << 13)
+#define NHM_LOCAL_DRAM         (1 << 14)
+#define NHM_NON_DRAM           (1 << 15)
+
+#define NHM_ALL_DRAM           (NHM_REMOTE_DRAM|NHM_LOCAL_DRAM)
+
+#define NHM_DMND_READ          (NHM_DMND_DATA_RD)
+#define NHM_DMND_WRITE         (NHM_DMND_RFO|NHM_DMND_WB)
+#define NHM_DMND_PREFETCH      (NHM_PF_DATA_RD|NHM_PF_DATA_RFO)
+
+#define NHM_L3_HIT     (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM)
+#define NHM_L3_MISS    (NHM_NON_DRAM|NHM_ALL_DRAM|NHM_REMOTE_CACHE_FWD)
+#define NHM_L3_ACCESS  (NHM_L3_HIT|NHM_L3_MISS)
 
 static __initconst const u64 nehalem_hw_cache_extra_regs
                                [PERF_COUNT_HW_CACHE_MAX]
@@ -370,16 +387,16 @@ static __initconst const u64 nehalem_hw_cache_extra_regs
 {
  [ C(LL  ) ] = {
        [ C(OP_READ) ] = {
-               [ C(RESULT_ACCESS) ] = DMND_DATA_RD|RESP_UNCORE_HIT,
-               [ C(RESULT_MISS)   ] = DMND_DATA_RD|RESP_MISS,
+               [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS,
+               [ C(RESULT_MISS)   ] = NHM_DMND_READ|NHM_L3_MISS,
        },
        [ C(OP_WRITE) ] = {
-               [ C(RESULT_ACCESS) ] = DMND_RFO|DMND_WB|RESP_UNCORE_HIT,
-               [ C(RESULT_MISS)   ] = DMND_RFO|DMND_WB|RESP_MISS,
+               [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS,
+               [ C(RESULT_MISS)   ] = NHM_DMND_WRITE|NHM_L3_MISS,
        },
        [ C(OP_PREFETCH) ] = {
-               [ C(RESULT_ACCESS) ] = PF_DATA_RD|PF_DATA_RFO|RESP_UNCORE_HIT,
-               [ C(RESULT_MISS)   ] = PF_DATA_RD|PF_DATA_RFO|RESP_MISS,
+               [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS,
+               [ C(RESULT_MISS)   ] = NHM_DMND_PREFETCH|NHM_L3_MISS,
        },
  }
 };
@@ -933,6 +950,16 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
 
        cpuc = &__get_cpu_var(cpu_hw_events);
 
+       /*
+        * Some chipsets need to unmask the LVTPC in a particular spot
+        * inside the nmi handler.  As a result, the unmasking was pushed
+        * into all the nmi handlers.
+        *
+        * This handler doesn't seem to have any issues with the unmasking
+        * so it was left at the top.
+        */
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
+
        intel_pmu_disable_all();
        handled = intel_pmu_drain_bts_buffer();
        status = intel_pmu_get_status();
@@ -998,6 +1025,9 @@ intel_bts_constraints(struct perf_event *event)
        struct hw_perf_event *hwc = &event->hw;
        unsigned int hw_event, bts_event;
 
+       if (event->attr.freq)
+               return NULL;
+
        hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
        bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
 
@@ -1305,7 +1335,7 @@ static void intel_clovertown_quirks(void)
         * AJ106 could possibly be worked around by not allowing LBR
         *       usage from PEBS, including the fixup.
         * AJ68  could possibly be worked around by always programming
-        *       a pebs_event_reset[0] value and coping with the lost events.
+        *       a pebs_event_reset[0] value and coping with the lost events.
         *
         * But taken together it might just make sense to not enable PEBS on
         * these chips.
@@ -1409,6 +1439,18 @@ static __init int intel_pmu_init(void)
                x86_pmu.percore_constraints = intel_nehalem_percore_constraints;
                x86_pmu.enable_all = intel_pmu_nhm_enable_all;
                x86_pmu.extra_regs = intel_nehalem_extra_regs;
+
+               if (ebx & 0x40) {
+                       /*
+                        * Erratum AAJ80 detected, we work it around by using
+                        * the BR_MISP_EXEC.ANY event. This will over-count
+                        * branch-misses, but it's still much better than the
+                        * architectural event which is often completely bogus:
+                        */
+                       intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89;
+
+                       pr_cont("erratum AAJ80 worked around, ");
+               }
                pr_cont("Nehalem events, ");
                break;
 
index d1f77e2..e93fcd5 100644 (file)
@@ -950,11 +950,20 @@ static int p4_pmu_handle_irq(struct pt_regs *regs)
                        x86_pmu_stop(event, 0);
        }
 
-       if (handled) {
-               /* p4 quirk: unmask it again */
-               apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
+       if (handled)
                inc_irq_stat(apic_perf_irqs);
-       }
+
+       /*
+        * When dealing with the unmasking of the LVTPC on P4 perf hw, it has
+        * been observed that the OVF bit flag has to be cleared first _before_
+        * the LVTPC can be unmasked.
+        *
+        * The reason is the NMI line will continue to be asserted while the OVF
+        * bit is set.  This causes a second NMI to generate if the LVTPC is
+        * unmasked before the OVF bit is cleared, leading to unknown NMI
+        * messages.
+        */
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
 
        return handled;
 }
index 706a9fb..e90f084 100644 (file)
@@ -391,7 +391,7 @@ static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
 
        set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
 
-       return io_apic_setup_irq_pin(*out_hwirq, cpu_to_node(0), &attr);
+       return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr);
 }
 
 static void __init ioapic_add_ofnode(struct device_node *np)
index c969fd9..f1a6244 100644 (file)
@@ -1183,12 +1183,13 @@ static void __kprobes optimized_callback(struct optimized_kprobe *op,
                                         struct pt_regs *regs)
 {
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+       unsigned long flags;
 
        /* This is possible if op is under delayed unoptimizing */
        if (kprobe_disabled(&op->kp))
                return;
 
-       preempt_disable();
+       local_irq_save(flags);
        if (kprobe_running()) {
                kprobes_inc_nmissed_count(&op->kp);
        } else {
@@ -1207,7 +1208,7 @@ static void __kprobes optimized_callback(struct optimized_kprobe *op,
                opt_pre_handler(&op->kp, regs);
                __this_cpu_write(current_kprobe, NULL);
        }
-       preempt_enable_no_resched();
+       local_irq_restore(flags);
 }
 
 static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src)
index 45892dc..f65e5b5 100644 (file)
@@ -608,6 +608,9 @@ static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data)
        unsigned len, type;
        struct perf_event *bp;
 
+       if (ptrace_get_breakpoints(tsk) < 0)
+               return -ESRCH;
+
        data &= ~DR_CONTROL_RESERVED;
        old_dr7 = ptrace_get_dr7(thread->ptrace_bps);
 restore:
@@ -655,6 +658,9 @@ restore:
                }
                goto restore;
        }
+
+       ptrace_put_breakpoints(tsk);
+
        return ((orig_ret < 0) ? orig_ret : rc);
 }
 
@@ -668,10 +674,17 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
 
        if (n < HBP_NUM) {
                struct perf_event *bp;
+
+               if (ptrace_get_breakpoints(tsk) < 0)
+                       return -ESRCH;
+
                bp = thread->ptrace_bps[n];
                if (!bp)
-                       return 0;
-               val = bp->hw.info.address;
+                       val = 0;
+               else
+                       val = bp->hw.info.address;
+
+               ptrace_put_breakpoints(tsk);
        } else if (n == 6) {
                val = thread->debugreg6;
         } else if (n == 7) {
@@ -686,6 +699,10 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
        struct perf_event *bp;
        struct thread_struct *t = &tsk->thread;
        struct perf_event_attr attr;
+       int err = 0;
+
+       if (ptrace_get_breakpoints(tsk) < 0)
+               return -ESRCH;
 
        if (!t->ptrace_bps[nr]) {
                ptrace_breakpoint_init(&attr);
@@ -709,24 +726,23 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
                 * writing for the user. And anyway this is the previous
                 * behaviour.
                 */
-               if (IS_ERR(bp))
-                       return PTR_ERR(bp);
+               if (IS_ERR(bp)) {
+                       err = PTR_ERR(bp);
+                       goto put;
+               }
 
                t->ptrace_bps[nr] = bp;
        } else {
-               int err;
-
                bp = t->ptrace_bps[nr];
 
                attr = bp->attr;
                attr.bp_addr = addr;
                err = modify_user_hw_breakpoint(bp, &attr);
-               if (err)
-                       return err;
        }
 
-
-       return 0;
+put:
+       ptrace_put_breakpoints(tsk);
+       return err;
 }
 
 /*
index 29092b3..1d5c46d 100644 (file)
@@ -21,26 +21,26 @@ r_base = .
        /* Get our own relocated address */
        call    1f
 1:     popl    %ebx
-       subl    $1b, %ebx
+       subl    $(1b - r_base), %ebx
 
        /* Compute the equivalent real-mode segment */
        movl    %ebx, %ecx
        shrl    $4, %ecx
        
        /* Patch post-real-mode segment jump */
-       movw    dispatch_table(%ebx,%eax,2),%ax
-       movw    %ax, 101f(%ebx)
-       movw    %cx, 102f(%ebx)
+       movw    (dispatch_table - r_base)(%ebx,%eax,2),%ax
+       movw    %ax, (101f - r_base)(%ebx)
+       movw    %cx, (102f - r_base)(%ebx)
 
        /* Set up the IDT for real mode. */
-       lidtl   machine_real_restart_idt(%ebx)
+       lidtl   (machine_real_restart_idt - r_base)(%ebx)
 
        /*
         * Set up a GDT from which we can load segment descriptors for real
         * mode.  The GDT is not used in real mode; it is just needed here to
         * prepare the descriptors.
         */
-       lgdtl   machine_real_restart_gdt(%ebx)
+       lgdtl   (machine_real_restart_gdt - r_base)(%ebx)
 
        /*
         * Load the data segment registers with 16-bit compatible values
index e8c00cc..85b52fc 100644 (file)
@@ -306,7 +306,7 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
                bi->end = min(bi->end, high);
 
                /* and there's no empty block */
-               if (bi->start == bi->end) {
+               if (bi->start >= bi->end) {
                        numa_remove_memblk_from(i--, mi);
                        continue;
                }
index 2d6d226..e70be38 100644 (file)
                                                   "pciclass0c03";
 
                                        reg = <0x16800 0x0 0x0 0x0 0x0>;
-                                       interrupts = <22 3>;
+                                       interrupts = <22 1>;
                                };
 
                                usb@d,1 {
                                                   "pciclass0c03";
 
                                        reg = <0x16900 0x0 0x0 0x0 0x0>;
-                                       interrupts = <22 3>;
+                                       interrupts = <22 1>;
                                };
 
                                sata@e,0 {
                                                   "pciclass0106";
 
                                        reg = <0x17000 0x0 0x0 0x0 0x0>;
-                                       interrupts = <23 3>;
+                                       interrupts = <23 1>;
                                };
 
                                flash@f,0 {
index aef7af9..55c965b 100644 (file)
@@ -1463,6 +1463,119 @@ static int xen_pgd_alloc(struct mm_struct *mm)
        return ret;
 }
 
+#ifdef CONFIG_X86_64
+static __initdata u64 __last_pgt_set_rw = 0;
+static __initdata u64 __pgt_buf_start = 0;
+static __initdata u64 __pgt_buf_end = 0;
+static __initdata u64 __pgt_buf_top = 0;
+/*
+ * As a consequence of the commit:
+ * 
+ * commit 4b239f458c229de044d6905c2b0f9fe16ed9e01e
+ * Author: Yinghai Lu <yinghai@kernel.org>
+ * Date:   Fri Dec 17 16:58:28 2010 -0800
+ * 
+ *     x86-64, mm: Put early page table high
+ * 
+ * at some point init_memory_mapping is going to reach the pagetable pages
+ * area and map those pages too (mapping them as normal memory that falls
+ * in the range of addresses passed to init_memory_mapping as argument).
+ * Some of those pages are already pagetable pages (they are in the range
+ * pgt_buf_start-pgt_buf_end) therefore they are going to be mapped RO and
+ * everything is fine.
+ * Some of these pages are not pagetable pages yet (they fall in the range
+ * pgt_buf_end-pgt_buf_top; for example the page at pgt_buf_end) so they
+ * are going to be mapped RW.  When these pages become pagetable pages and
+ * are hooked into the pagetable, xen will find that the guest has already
+ * a RW mapping of them somewhere and fail the operation.
+ * The reason Xen requires pagetables to be RO is that the hypervisor needs
+ * to verify that the pagetables are valid before using them. The validation
+ * operations are called "pinning".
+ * 
+ * In order to fix the issue we mark all the pages in the entire range
+ * pgt_buf_start-pgt_buf_top as RO, however when the pagetable allocation
+ * is completed only the range pgt_buf_start-pgt_buf_end is reserved by
+ * init_memory_mapping. Hence the kernel is going to crash as soon as one
+ * of the pages in the range pgt_buf_end-pgt_buf_top is reused (b/c those
+ * ranges are RO).
+ * 
+ * For this reason, 'mark_rw_past_pgt' is introduced which is called _after_
+ * the init_memory_mapping has completed (in a perfect world we would
+ * call this function from init_memory_mapping, but lets ignore that).
+ * 
+ * Because we are called _after_ init_memory_mapping the pgt_buf_[start,
+ * end,top] have all changed to new values (b/c init_memory_mapping
+ * is called and setting up another new page-table). Hence, the first time
+ * we enter this function, we save away the pgt_buf_start value and update
+ * the pgt_buf_[end,top].
+ * 
+ * When we detect that the "old" pgt_buf_start through pgt_buf_end
+ * PFNs have been reserved (so memblock_x86_reserve_range has been called),
+ * we immediately set out to RW the "old" pgt_buf_end through pgt_buf_top.
+ * 
+ * And then we update those "old" pgt_buf_[end|top] with the new ones
+ * so that we can redo this on the next pagetable.
+ */
+static __init void mark_rw_past_pgt(void) {
+
+       if (pgt_buf_end > pgt_buf_start) {
+               u64 addr, size;
+
+               /* Save it away. */
+               if (!__pgt_buf_start) {
+                       __pgt_buf_start = pgt_buf_start;
+                       __pgt_buf_end = pgt_buf_end;
+                       __pgt_buf_top = pgt_buf_top;
+                       return;
+               }
+               /* If we get the range that starts at __pgt_buf_end that means
+                * the range is reserved, and that in 'init_memory_mapping'
+                * the 'memblock_x86_reserve_range' has been called with the
+                * outdated __pgt_buf_start, __pgt_buf_end (the "new"
+                * pgt_buf_[start|end|top] refer now to a new pagetable.
+                * Note: we are called _after_ the pgt_buf_[..] have been
+                * updated.*/
+
+               addr = memblock_x86_find_in_range_size(PFN_PHYS(__pgt_buf_start),
+                                                      &size, PAGE_SIZE);
+
+               /* Still not reserved, meaning 'memblock_x86_reserve_range'
+                * hasn't been called yet. Update the _end and _top.*/
+               if (addr == PFN_PHYS(__pgt_buf_start)) {
+                       __pgt_buf_end = pgt_buf_end;
+                       __pgt_buf_top = pgt_buf_top;
+                       return;
+               }
+
+               /* OK, the area is reserved, meaning it is time for us to
+                * set RW for the old end->top PFNs. */
+
+               /* ..unless we had already done this. */
+               if (__pgt_buf_end == __last_pgt_set_rw)
+                       return;
+
+               addr = PFN_PHYS(__pgt_buf_end);
+               
+               /* set as RW the rest */
+               printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n",
+                       PFN_PHYS(__pgt_buf_end), PFN_PHYS(__pgt_buf_top));
+               
+               while (addr < PFN_PHYS(__pgt_buf_top)) {
+                       make_lowmem_page_readwrite(__va(addr));
+                       addr += PAGE_SIZE;
+               }
+               /* And update everything so that we are ready for the next
+                * pagetable (the one created for regions past 4GB) */
+               __last_pgt_set_rw = __pgt_buf_end;
+               __pgt_buf_start = pgt_buf_start;
+               __pgt_buf_end = pgt_buf_end;
+               __pgt_buf_top = pgt_buf_top;
+       }
+       return;
+}
+#else
+static __init void mark_rw_past_pgt(void) { }
+#endif
 static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
 #ifdef CONFIG_X86_64
@@ -1489,13 +1602,21 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
        unsigned long pfn = pte_pfn(pte);
 
        /*
+        * A bit of optimization. We do not need to call the workaround
+        * when xen_set_pte_init is called with a PTE with 0 as PFN.
+        * That is b/c the pagetable at that point are just being populated
+        * with empty values and we can save some cycles by not calling
+        * the 'memblock' code.*/
+       if (pfn)
+               mark_rw_past_pgt();
+       /*
         * If the new pfn is within the range of the newly allocated
         * kernel pagetable, and it isn't being mapped into an
         * early_ioremap fixmap slot as a freshly allocated page, make sure
         * it is RO.
         */
        if (((!is_early_ioremap_ptep(ptep) &&
-                       pfn >= pgt_buf_start && pfn < pgt_buf_end)) ||
+                       pfn >= pgt_buf_start && pfn < pgt_buf_top)) ||
                        (is_early_ioremap_ptep(ptep) && pfn != (pgt_buf_end - 1)))
                pte = pte_wrprotect(pte);
 
@@ -1997,6 +2118,8 @@ __init void xen_ident_map_ISA(void)
 
 static __init void xen_post_allocator_init(void)
 {
+       mark_rw_past_pgt();
+
 #ifdef CONFIG_XEN_DEBUG
        pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug);
 #endif
index d77089d..4340ee0 100644 (file)
@@ -64,47 +64,41 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
 
 int arch_show_interrupts(struct seq_file *p, int prec)
 {
-       int j;
-
-       seq_printf(p, "%*s: ", prec, "NMI");
-       for_each_online_cpu(j)
-               seq_printf(p, "%10u ", nmi_count(j));
-       seq_putc(p, '\n');
        seq_printf(p, "%*s: ", prec, "ERR");
        seq_printf(p, "%10u\n", atomic_read(&irq_err_count));
        return 0;
 }
 
-static void xtensa_irq_mask(struct irq_chip *d)
+static void xtensa_irq_mask(struct irq_data *d)
 {
        cached_irq_mask &= ~(1 << d->irq);
        set_sr (cached_irq_mask, INTENABLE);
 }
 
-static void xtensa_irq_unmask(struct irq_chip *d)
+static void xtensa_irq_unmask(struct irq_data *d)
 {
        cached_irq_mask |= 1 << d->irq;
        set_sr (cached_irq_mask, INTENABLE);
 }
 
-static void xtensa_irq_enable(struct irq_chip *d)
+static void xtensa_irq_enable(struct irq_data *d)
 {
        variant_irq_enable(d->irq);
        xtensa_irq_unmask(d->irq);
 }
 
-static void xtensa_irq_disable(struct irq_chip *d)
+static void xtensa_irq_disable(struct irq_data *d)
 {
        xtensa_irq_mask(d->irq);
        variant_irq_disable(d->irq);
 }
 
-static void xtensa_irq_ack(struct irq_chip *d)
+static void xtensa_irq_ack(struct irq_data *d)
 {
        set_sr(1 << d->irq, INTCLEAR);
 }
 
-static int xtensa_irq_retrigger(struct irq_chip *d)
+static int xtensa_irq_retrigger(struct irq_data *d)
 {
        set_sr (1 << d->irq, INTSET);
        return 1;
index b136c9c..449c556 100644 (file)
@@ -943,6 +943,10 @@ static int acpi_bus_get_flags(struct acpi_device *device)
        if (ACPI_SUCCESS(status))
                device->flags.lockable = 1;
 
+       /* Power resources cannot be power manageable. */
+       if (device->device_type == ACPI_BUS_TYPE_POWER)
+               return 0;
+
        /* Presence of _PS0|_PR0 indicates 'power manageable' */
        status = acpi_get_handle(device->handle, "_PS0", &temp);
        if (ACPI_FAILURE(status))
index 39d829c..71afe03 100644 (file)
@@ -150,7 +150,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
                                 AHCI_HFLAG_YES_NCQ),
-               .flags          = AHCI_FLAG_COMMON,
+               .flags          = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
@@ -261,6 +261,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */
        { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
        { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
+       { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
+       { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */
+       { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
index 3986500..12c5282 100644 (file)
@@ -229,6 +229,10 @@ enum {
        EM_CTL_ALHD             = (1 << 26), /* Activity LED */
        EM_CTL_XMT              = (1 << 25), /* Transmit Only */
        EM_CTL_SMB              = (1 << 24), /* Single Message Buffer */
+       EM_CTL_SGPIO            = (1 << 19), /* SGPIO messages supported */
+       EM_CTL_SES              = (1 << 18), /* SES-2 messages supported */
+       EM_CTL_SAFTE            = (1 << 17), /* SAF-TE messages supported */
+       EM_CTL_LED              = (1 << 16), /* LED messages supported */
 
        /* em message type */
        EM_MSG_TYPE_LED         = (1 << 0), /* LED */
index 0bc3fd6..6f6e771 100644 (file)
@@ -309,6 +309,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
        /* SATA Controller IDE (PBG) */
        { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        { }     /* terminate list */
 };
 
index 26d4523..ff9d832 100644 (file)
@@ -109,6 +109,8 @@ static ssize_t ahci_read_em_buffer(struct device *dev,
 static ssize_t ahci_store_em_buffer(struct device *dev,
                                    struct device_attribute *attr,
                                    const char *buf, size_t size);
+static ssize_t ahci_show_em_supported(struct device *dev,
+                                     struct device_attribute *attr, char *buf);
 
 static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
 static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
@@ -116,6 +118,7 @@ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
 static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
 static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
                   ahci_read_em_buffer, ahci_store_em_buffer);
+static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL);
 
 struct device_attribute *ahci_shost_attrs[] = {
        &dev_attr_link_power_management_policy,
@@ -126,6 +129,7 @@ struct device_attribute *ahci_shost_attrs[] = {
        &dev_attr_ahci_host_version,
        &dev_attr_ahci_port_cmd,
        &dev_attr_em_buffer,
+       &dev_attr_em_message_supported,
        NULL
 };
 EXPORT_SYMBOL_GPL(ahci_shost_attrs);
@@ -343,6 +347,24 @@ static ssize_t ahci_store_em_buffer(struct device *dev,
        return size;
 }
 
+static ssize_t ahci_show_em_supported(struct device *dev,
+                                     struct device_attribute *attr, char *buf)
+{
+       struct Scsi_Host *shost = class_to_shost(dev);
+       struct ata_port *ap = ata_shost_to_port(shost);
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *mmio = hpriv->mmio;
+       u32 em_ctl;
+
+       em_ctl = readl(mmio + HOST_EM_CTL);
+
+       return sprintf(buf, "%s%s%s%s\n",
+                      em_ctl & EM_CTL_LED ? "led " : "",
+                      em_ctl & EM_CTL_SAFTE ? "saf-te " : "",
+                      em_ctl & EM_CTL_SES ? "ses-2 " : "",
+                      em_ctl & EM_CTL_SGPIO ? "sgpio " : "");
+}
+
 /**
  *     ahci_save_initial_config - Save and fixup initial config values
  *     @dev: target AHCI device
@@ -539,6 +561,27 @@ void ahci_start_engine(struct ata_port *ap)
 {
        void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
+       u8 status;
+
+       status = readl(port_mmio + PORT_TFDATA) & 0xFF;
+
+       /*
+        * At end of section 10.1 of AHCI spec (rev 1.3), it states
+        * Software shall not set PxCMD.ST to 1 until it is determined
+        * that a functoinal device is present on the port as determined by
+        * PxTFD.STS.BSY=0, PxTFD.STS.DRQ=0 and PxSSTS.DET=3h
+        *
+        * Even though most AHCI host controllers work without this check,
+        * specific controller will fail under this condition
+        */
+       if (status & (ATA_BUSY | ATA_DRQ))
+               return;
+       else {
+               ahci_scr_read(&ap->link, SCR_STATUS, &tmp);
+
+               if ((tmp & 0xf) != 0x3)
+                       return;
+       }
 
        /* start DMA */
        tmp = readl(port_mmio + PORT_CMD);
@@ -1897,7 +1940,17 @@ static void ahci_pmp_attach(struct ata_port *ap)
        ahci_enable_fbs(ap);
 
        pp->intr_mask |= PORT_IRQ_BAD_PMP;
-       writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
+
+       /*
+        * We must not change the port interrupt mask register if the
+        * port is marked frozen, the value in pp->intr_mask will be
+        * restored later when the port is thawed.
+        *
+        * Note that during initialization, the port is marked as
+        * frozen since the irq handler is not yet registered.
+        */
+       if (!(ap->pflags & ATA_PFLAG_FROZEN))
+               writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
 }
 
 static void ahci_pmp_detach(struct ata_port *ap)
@@ -1913,7 +1966,10 @@ static void ahci_pmp_detach(struct ata_port *ap)
        writel(cmd, port_mmio + PORT_CMD);
 
        pp->intr_mask &= ~PORT_IRQ_BAD_PMP;
-       writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
+
+       /* see comment above in ahci_pmp_attach() */
+       if (!(ap->pflags & ATA_PFLAG_FROZEN))
+               writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
 }
 
 int ahci_port_resume(struct ata_port *ap)
index 423c0a6..76c3c15 100644 (file)
@@ -4139,6 +4139,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
         */
        { "PIONEER DVD-RW  DVRTD08",    "1.00", ATA_HORKAGE_NOSETXFER },
        { "PIONEER DVD-RW  DVR-212D",   "1.28", ATA_HORKAGE_NOSETXFER },
+       { "PIONEER DVD-RW  DVR-216D",   "1.08", ATA_HORKAGE_NOSETXFER },
 
        /* End Marker */
        { }
@@ -5480,7 +5481,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        if (!ap)
                return NULL;
 
-       ap->pflags |= ATA_PFLAG_INITIALIZING;
+       ap->pflags |= ATA_PFLAG_INITIALIZING | ATA_PFLAG_FROZEN;
        ap->lock = &host->lock;
        ap->print_id = -1;
        ap->host = host;
index 88cd22f..f26f2fe 100644 (file)
@@ -3316,6 +3316,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
        struct ata_eh_context *ehc = &link->eh_context;
        struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
        enum ata_lpm_policy old_policy = link->lpm_policy;
+       bool no_dipm = ap->flags & ATA_FLAG_NO_DIPM;
        unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
        unsigned int err_mask;
        int rc;
@@ -3332,7 +3333,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
         */
        ata_for_each_dev(dev, link, ENABLED) {
                bool hipm = ata_id_has_hipm(dev->id);
-               bool dipm = ata_id_has_dipm(dev->id);
+               bool dipm = ata_id_has_dipm(dev->id) && !no_dipm;
 
                /* find the first enabled and LPM enabled devices */
                if (!link_dev)
@@ -3389,7 +3390,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
 
        /* host config updated, enable DIPM if transitioning to MIN_POWER */
        ata_for_each_dev(dev, link, ENABLED) {
-               if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) {
+               if (policy == ATA_LPM_MIN_POWER && !no_dipm &&
+                   ata_id_has_dipm(dev->id)) {
                        err_mask = ata_dev_set_feature(dev,
                                        SETFEATURES_SATA_ENABLE, SATA_DIPM);
                        if (err_mask && err_mask != AC_ERR_DEV) {
index 0da0dcc..a5fdbdc 100644 (file)
 
 
 #define DRV_NAME "pata_at91"
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
 
 #define CF_IDE_OFFSET      0x00c00000
 #define CF_ALT_IDE_OFFSET   0x00e00000
 #define CF_IDE_RES_SIZE     0x08
+#define NCS_RD_PULSE_LIMIT  0x3f /* maximal value for pulse bitfields */
 
 struct at91_ide_info {
        unsigned long mode;
@@ -49,8 +50,18 @@ struct at91_ide_info {
        void __iomem *alt_addr;
 };
 
-static const struct ata_timing initial_timing =
-       {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0};
+static const struct ata_timing initial_timing = {
+       .mode           = XFER_PIO_0,
+       .setup          = 70,
+       .act8b          = 290,
+       .rec8b          = 240,
+       .cyc8b          = 600,
+       .active         = 165,
+       .recover        = 150,
+       .dmack_hold     = 0,
+       .cycle          = 600,
+       .udma           = 0
+};
 
 static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz)
 {
@@ -109,6 +120,11 @@ static void set_smc_timing(struct device *dev,
        /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */
        ncs_read_setup = 1;
        ncs_read_pulse = read_cycle - 2;
+       if (ncs_read_pulse > NCS_RD_PULSE_LIMIT) {
+               ncs_read_pulse = NCS_RD_PULSE_LIMIT;
+               dev_warn(dev, "ncs_read_pulse limited to maximal value %lu\n",
+                       ncs_read_pulse);
+       }
 
        /* Write timings same as read timings */
        write_cycle = read_cycle;
index fbc5b6e..abe3ab7 100644 (file)
@@ -63,6 +63,7 @@ void device_pm_init(struct device *dev)
        dev->power.wakeup = NULL;
        spin_lock_init(&dev->power.lock);
        pm_runtime_init(dev);
+       INIT_LIST_HEAD(&dev->power.entry);
 }
 
 /**
index 4573c83..abbbd33 100644 (file)
@@ -258,7 +258,7 @@ void device_set_wakeup_capable(struct device *dev, bool capable)
        if (!!dev->power.can_wakeup == !!capable)
                return;
 
-       if (device_is_registered(dev)) {
+       if (device_is_registered(dev) && !list_empty(&dev->power.entry)) {
                if (capable) {
                        if (wakeup_sysfs_add(dev))
                                return;
index 90af294..c126db3 100644 (file)
@@ -73,6 +73,7 @@ int syscore_suspend(void)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(syscore_suspend);
 
 /**
  * syscore_resume - Execute all the registered system core resume callbacks.
@@ -95,6 +96,7 @@ void syscore_resume(void)
                                "Interrupts enabled after %pF\n", ops->resume);
                }
 }
+EXPORT_SYMBOL_GPL(syscore_resume);
 #endif /* CONFIG_PM_SLEEP */
 
 /**
index 16dc364..3e90471 100644 (file)
@@ -777,9 +777,9 @@ static int rbd_do_request(struct request *rq,
                                      ops,
                                      false,
                                      GFP_NOIO, pages, bio);
-       if (IS_ERR(req)) {
+       if (!req) {
                up_read(&header->snap_rwsem);
-               ret = PTR_ERR(req);
+               ret = -ENOMEM;
                goto done_pages;
        }
 
index 0fc0a79..6db161f 100644 (file)
@@ -32,10 +32,9 @@ static DEFINE_MUTEX(clocks_mutex);
  * Then we take the most specific entry - with the following
  * order of precedence: dev+con > dev only > con only.
  */
-static struct clk *clk_find(const char *dev_id, const char *con_id)
+static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
 {
-       struct clk_lookup *p;
-       struct clk *clk = NULL;
+       struct clk_lookup *p, *cl = NULL;
        int match, best = 0;
 
        list_for_each_entry(p, &clocks, node) {
@@ -52,27 +51,27 @@ static struct clk *clk_find(const char *dev_id, const char *con_id)
                }
 
                if (match > best) {
-                       clk = p->clk;
+                       cl = p;
                        if (match != 3)
                                best = match;
                        else
                                break;
                }
        }
-       return clk;
+       return cl;
 }
 
 struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 {
-       struct clk *clk;
+       struct clk_lookup *cl;
 
        mutex_lock(&clocks_mutex);
-       clk = clk_find(dev_id, con_id);
-       if (clk && !__clk_get(clk))
-               clk = NULL;
+       cl = clk_find(dev_id, con_id);
+       if (cl && !__clk_get(cl->clk))
+               cl = NULL;
        mutex_unlock(&clocks_mutex);
 
-       return clk ? clk : ERR_PTR(-ENOENT);
+       return cl ? cl->clk : ERR_PTR(-ENOENT);
 }
 EXPORT_SYMBOL(clk_get_sys);
 
index 31e71c4..9a8bebc 100644 (file)
@@ -211,8 +211,6 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci)
 
        scrubval = scrubval & 0x001F;
 
-       amd64_debug("pci-read, sdram scrub control value: %d\n", scrubval);
-
        for (i = 0; i < ARRAY_SIZE(scrubrates); i++) {
                if (scrubrates[i].scrubval == scrubval) {
                        retval = scrubrates[i].bandwidth;
@@ -933,25 +931,74 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
 /* On F10h and later ErrAddr is MC4_ADDR[47:1] */
 static u64 get_error_address(struct mce *m)
 {
+       struct cpuinfo_x86 *c = &boot_cpu_data;
+       u64 addr;
        u8 start_bit = 1;
        u8 end_bit   = 47;
 
-       if (boot_cpu_data.x86 == 0xf) {
+       if (c->x86 == 0xf) {
                start_bit = 3;
                end_bit   = 39;
        }
 
-       return m->addr & GENMASK(start_bit, end_bit);
+       addr = m->addr & GENMASK(start_bit, end_bit);
+
+       /*
+        * Erratum 637 workaround
+        */
+       if (c->x86 == 0x15) {
+               struct amd64_pvt *pvt;
+               u64 cc6_base, tmp_addr;
+               u32 tmp;
+               u8 mce_nid, intlv_en;
+
+               if ((addr & GENMASK(24, 47)) >> 24 != 0x00fdf7)
+                       return addr;
+
+               mce_nid = amd_get_nb_id(m->extcpu);
+               pvt     = mcis[mce_nid]->pvt_info;
+
+               amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp);
+               intlv_en = tmp >> 21 & 0x7;
+
+               /* add [47:27] + 3 trailing bits */
+               cc6_base  = (tmp & GENMASK(0, 20)) << 3;
+
+               /* reverse and add DramIntlvEn */
+               cc6_base |= intlv_en ^ 0x7;
+
+               /* pin at [47:24] */
+               cc6_base <<= 24;
+
+               if (!intlv_en)
+                       return cc6_base | (addr & GENMASK(0, 23));
+
+               amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_BASE, &tmp);
+
+                                                       /* faster log2 */
+               tmp_addr  = (addr & GENMASK(12, 23)) << __fls(intlv_en + 1);
+
+               /* OR DramIntlvSel into bits [14:12] */
+               tmp_addr |= (tmp & GENMASK(21, 23)) >> 9;
+
+               /* add remaining [11:0] bits from original MC4_ADDR */
+               tmp_addr |= addr & GENMASK(0, 11);
+
+               return cc6_base | tmp_addr;
+       }
+
+       return addr;
 }
 
 static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
 {
+       struct cpuinfo_x86 *c = &boot_cpu_data;
        int off = range << 3;
 
        amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off,  &pvt->ranges[range].base.lo);
        amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo);
 
-       if (boot_cpu_data.x86 == 0xf)
+       if (c->x86 == 0xf)
                return;
 
        if (!dram_rw(pvt, range))
@@ -959,6 +1006,31 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
 
        amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off,  &pvt->ranges[range].base.hi);
        amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi);
+
+       /* Factor in CC6 save area by reading dst node's limit reg */
+       if (c->x86 == 0x15) {
+               struct pci_dev *f1 = NULL;
+               u8 nid = dram_dst_node(pvt, range);
+               u32 llim;
+
+               f1 = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x18 + nid, 1));
+               if (WARN_ON(!f1))
+                       return;
+
+               amd64_read_pci_cfg(f1, DRAM_LOCAL_NODE_LIM, &llim);
+
+               pvt->ranges[range].lim.lo &= GENMASK(0, 15);
+
+                                           /* {[39:27],111b} */
+               pvt->ranges[range].lim.lo |= ((llim & 0x1fff) << 3 | 0x7) << 16;
+
+               pvt->ranges[range].lim.hi &= GENMASK(0, 7);
+
+                                           /* [47:40] */
+               pvt->ranges[range].lim.hi |= llim >> 13;
+
+               pci_dev_put(f1);
+       }
 }
 
 static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
@@ -1403,12 +1475,8 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
                return -EINVAL;
        }
 
-       if (intlv_en &&
-           (intlv_sel != ((sys_addr >> 12) & intlv_en))) {
-               amd64_warn("Botched intlv bits, en: 0x%x, sel: 0x%x\n",
-                          intlv_en, intlv_sel);
+       if (intlv_en && (intlv_sel != ((sys_addr >> 12) & intlv_en)))
                return -EINVAL;
-       }
 
        sys_addr = f1x_swap_interleaved_region(pvt, sys_addr);
 
index 11be36a..9a666cb 100644 (file)
 
 #define DCT_CFG_SEL                    0x10C
 
+#define DRAM_LOCAL_NODE_BASE           0x120
+#define DRAM_LOCAL_NODE_LIM            0x124
+
 #define DRAM_BASE_HI                   0x140
 #define DRAM_LIMIT_HI                  0x144
 
index 26343fd..29ffa35 100644 (file)
@@ -458,13 +458,13 @@ static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci,
                return -EINVAL;
 
        new_bw = mci->set_sdram_scrub_rate(mci, bandwidth);
-       if (new_bw >= 0) {
-               edac_printk(KERN_DEBUG, EDAC_MC, "Scrub rate set to %d\n", new_bw);
-               return count;
+       if (new_bw < 0) {
+               edac_printk(KERN_WARNING, EDAC_MC,
+                           "Error setting scrub rate to: %lu\n", bandwidth);
+               return -EINVAL;
        }
 
-       edac_printk(KERN_DEBUG, EDAC_MC, "Error setting scrub rate to: %lu\n", bandwidth);
-       return -EINVAL;
+       return count;
 }
 
 /*
@@ -483,7 +483,6 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data)
                return bandwidth;
        }
 
-       edac_printk(KERN_DEBUG, EDAC_MC, "Read scrub rate: %d\n", bandwidth);
        return sprintf(data, "%d\n", bandwidth);
 }
 
index f903d7b..23d1468 100644 (file)
@@ -2199,7 +2199,6 @@ static int ohci_set_config_rom(struct fw_card *card,
 {
        struct fw_ohci *ohci;
        unsigned long flags;
-       int ret = -EBUSY;
        __be32 *next_config_rom;
        dma_addr_t uninitialized_var(next_config_rom_bus);
 
@@ -2240,22 +2239,37 @@ static int ohci_set_config_rom(struct fw_card *card,
 
        spin_lock_irqsave(&ohci->lock, flags);
 
+       /*
+        * If there is not an already pending config_rom update,
+        * push our new allocation into the ohci->next_config_rom
+        * and then mark the local variable as null so that we
+        * won't deallocate the new buffer.
+        *
+        * OTOH, if there is a pending config_rom update, just
+        * use that buffer with the new config_rom data, and
+        * let this routine free the unused DMA allocation.
+        */
+
        if (ohci->next_config_rom == NULL) {
                ohci->next_config_rom = next_config_rom;
                ohci->next_config_rom_bus = next_config_rom_bus;
+               next_config_rom = NULL;
+       }
 
-               copy_config_rom(ohci->next_config_rom, config_rom, length);
+       copy_config_rom(ohci->next_config_rom, config_rom, length);
 
-               ohci->next_header = config_rom[0];
-               ohci->next_config_rom[0] = 0;
+       ohci->next_header = config_rom[0];
+       ohci->next_config_rom[0] = 0;
 
-               reg_write(ohci, OHCI1394_ConfigROMmap,
-                         ohci->next_config_rom_bus);
-               ret = 0;
-       }
+       reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus);
 
        spin_unlock_irqrestore(&ohci->lock, flags);
 
+       /* If we didn't use the DMA allocation, delete it. */
+       if (next_config_rom != NULL)
+               dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
+                                 next_config_rom, next_config_rom_bus);
+
        /*
         * Now initiate a bus reset to have the changes take
         * effect. We clean up the old config rom memory and DMA
@@ -2263,13 +2277,10 @@ static int ohci_set_config_rom(struct fw_card *card,
         * controller could need to access it before the bus reset
         * takes effect.
         */
-       if (ret == 0)
-               fw_schedule_bus_reset(&ohci->card, true, true);
-       else
-               dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
-                                 next_config_rom, next_config_rom_bus);