Merge branch 'perf/urgent' into perf/core
authorIngo Molnar <mingo@elte.hu>
Wed, 16 Feb 2011 12:27:18 +0000 (13:27 +0100)
committerIngo Molnar <mingo@elte.hu>
Wed, 16 Feb 2011 12:27:23 +0000 (13:27 +0100)
Merge reason: we need to queue up dependent patch

Signed-off-by: Ingo Molnar <mingo@elte.hu>
376 files changed:
Documentation/DocBook/drm.tmpl
Documentation/devicetree/bindings/ata/fsl-sata.txt [moved from Documentation/powerpc/dts-bindings/fsl/sata.txt with 100% similarity]
Documentation/devicetree/bindings/eeprom.txt [moved from Documentation/powerpc/dts-bindings/eeprom.txt with 100% similarity]
Documentation/devicetree/bindings/gpio/8xxx_gpio.txt [moved from Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt with 100% similarity]
Documentation/devicetree/bindings/gpio/gpio.txt [moved from Documentation/powerpc/dts-bindings/gpio/gpio.txt with 100% similarity]
Documentation/devicetree/bindings/gpio/led.txt [moved from Documentation/powerpc/dts-bindings/gpio/led.txt with 100% similarity]
Documentation/devicetree/bindings/i2c/fsl-i2c.txt [moved from Documentation/powerpc/dts-bindings/fsl/i2c.txt with 100% similarity]
Documentation/devicetree/bindings/marvell.txt [moved from Documentation/powerpc/dts-bindings/marvell.txt with 100% similarity]
Documentation/devicetree/bindings/mmc/fsl-esdhc.txt [moved from Documentation/powerpc/dts-bindings/fsl/esdhc.txt with 100% similarity]
Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt [moved from Documentation/powerpc/dts-bindings/mmc-spi-slot.txt with 100% similarity]
Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt [moved from Documentation/powerpc/dts-bindings/fsl/upm-nand.txt with 100% similarity]
Documentation/devicetree/bindings/mtd/mtd-physmap.txt [moved from Documentation/powerpc/dts-bindings/mtd-physmap.txt with 100% similarity]
Documentation/devicetree/bindings/net/can/mpc5xxx-mscan.txt [moved from Documentation/powerpc/dts-bindings/fsl/can.txt with 100% similarity]
Documentation/devicetree/bindings/net/can/sja1000.txt [moved from Documentation/powerpc/dts-bindings/can/sja1000.txt with 100% similarity]
Documentation/devicetree/bindings/net/fsl-tsec-phy.txt [moved from Documentation/powerpc/dts-bindings/fsl/tsec.txt with 100% similarity]
Documentation/devicetree/bindings/net/mdio-gpio.txt [moved from Documentation/powerpc/dts-bindings/gpio/mdio.txt with 100% similarity]
Documentation/devicetree/bindings/net/phy.txt [moved from Documentation/powerpc/dts-bindings/phy.txt with 100% similarity]
Documentation/devicetree/bindings/pci/83xx-512x-pci.txt [moved from Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/4xx/cpm.txt [moved from Documentation/powerpc/dts-bindings/4xx/cpm.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/4xx/emac.txt [moved from Documentation/powerpc/dts-bindings/4xx/emac.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/4xx/ndfc.txt [moved from Documentation/powerpc/dts-bindings/4xx/ndfc.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/4xx/ppc440spe-adma.txt [moved from Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/4xx/reboot.txt [moved from Documentation/powerpc/dts-bindings/4xx/reboot.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/board.txt [moved from Documentation/powerpc/dts-bindings/fsl/board.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/brg.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/brg.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/i2c.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/pic.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/pic.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/usb.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/usb.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/gpio.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/gpio.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/network.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/firmware.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/par_io.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/pincfg.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/ucc.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/ucc.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/usb.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/serial.txt [moved from Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/diu.txt [moved from Documentation/powerpc/dts-bindings/fsl/diu.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/dma.txt [moved from Documentation/powerpc/dts-bindings/fsl/dma.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/ecm.txt [moved from Documentation/powerpc/dts-bindings/ecm.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/gtm.txt [moved from Documentation/powerpc/dts-bindings/fsl/gtm.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/guts.txt [moved from Documentation/powerpc/dts-bindings/fsl/guts.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/lbc.txt [moved from Documentation/powerpc/dts-bindings/fsl/lbc.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/mcm.txt [moved from Documentation/powerpc/dts-bindings/fsl/mcm.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt [moved from Documentation/powerpc/dts-bindings/fsl/mcu-mpc8349emitx.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/mpc5121-psc.txt [moved from Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt [moved from Documentation/powerpc/dts-bindings/fsl/mpc5200.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/mpic.txt [moved from Documentation/powerpc/dts-bindings/fsl/mpic.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt [moved from Documentation/powerpc/dts-bindings/fsl/msi-pic.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/pmc.txt [moved from Documentation/powerpc/dts-bindings/fsl/pmc.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/sec.txt [moved from Documentation/powerpc/dts-bindings/fsl/sec.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/fsl/ssi.txt [moved from Documentation/powerpc/dts-bindings/fsl/ssi.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/nintendo/gamecube.txt [moved from Documentation/powerpc/dts-bindings/nintendo/gamecube.txt with 100% similarity]
Documentation/devicetree/bindings/powerpc/nintendo/wii.txt [moved from Documentation/powerpc/dts-bindings/nintendo/wii.txt with 100% similarity]
Documentation/devicetree/bindings/spi/fsl-spi.txt [moved from Documentation/powerpc/dts-bindings/fsl/spi.txt with 100% similarity]
Documentation/devicetree/bindings/spi/spi-bus.txt [moved from Documentation/powerpc/dts-bindings/spi-bus.txt with 100% similarity]
Documentation/devicetree/bindings/usb/fsl-usb.txt [moved from Documentation/powerpc/dts-bindings/fsl/usb.txt with 100% similarity]
Documentation/devicetree/bindings/usb/usb-ehci.txt [moved from Documentation/powerpc/dts-bindings/usb-ehci.txt with 100% similarity]
Documentation/devicetree/bindings/xilinx.txt [moved from Documentation/powerpc/dts-bindings/xilinx.txt with 100% similarity]
Documentation/devicetree/booting-without-of.txt [moved from Documentation/powerpc/booting-without-of.txt with 90% similarity]
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/kernel/head.S
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/module.c
arch/arm/kernel/perf_event.c
arch/arm/mach-pxa/colibri-evalboard.c
arch/arm/mach-pxa/colibri-pxa300.c
arch/arm/mach-pxa/include/mach/colibri.h
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-s5pv310/Kconfig
arch/arm/mach-s5pv310/include/mach/map.h
arch/arm/mach-s5pv310/include/mach/sysmmu.h
arch/arm/mach-sa1100/collie.c
arch/arm/mm/Kconfig
arch/arm/oprofile/common.c
arch/arm/plat-pxa/mfp.c
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/include/plat/sysmmu.h [deleted file]
arch/arm/plat-s5p/sysmmu.c
arch/arm/plat-samsung/include/plat/pm.h
arch/blackfin/include/asm/bfin_serial.h
arch/m68k/include/asm/string.h
arch/m68k/lib/string.c
arch/m68knommu/kernel/vmlinux.lds.S
arch/m68knommu/lib/Makefile
arch/m68knommu/lib/memmove.c [new file with mode: 0644]
arch/m68knommu/platform/5249/intc2.c
arch/m68knommu/platform/68328/entry.S
arch/m68knommu/platform/68360/commproc.c
arch/m68knommu/platform/68360/config.c
arch/m68knommu/platform/68360/entry.S
arch/m68knommu/platform/68360/ints.c
arch/m68knommu/platform/coldfire/entry.S
arch/microblaze/include/asm/irqflags.h
arch/microblaze/include/asm/pgtable.h
arch/microblaze/kernel/cpu/pvr.c
arch/microblaze/kernel/head.S
arch/microblaze/kernel/setup.c
arch/s390/include/asm/processor.h
arch/s390/kernel/traps.c
arch/x86/include/asm/apic.h
arch/x86/include/asm/cpu.h
arch/x86/include/asm/perf_event_p4.h
arch/x86/kernel/alternative.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/perf_event_p4.c
arch/x86/kernel/irq.c
arch/x86/kernel/process.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/svm.c
block/blk-throttle.c
block/cfq-iosched.c
drivers/acpi/acpica/evxfgpe.c
drivers/acpi/osl.c
drivers/acpi/video_detect.c
drivers/acpi/wakeup.c
drivers/block/Makefile
drivers/block/aoe/Makefile
drivers/block/cciss.c
drivers/block/loop.c
drivers/block/nbd.c
drivers/cdrom/cdrom.c
drivers/char/Makefile
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_tis.c
drivers/char/virtio_console.c [moved from drivers/tty/hvc/virtio_console.c with 99% similarity]
drivers/dma/amba-pl08x.c
drivers/dma/imx-dma.c
drivers/dma/imx-sdma.c
drivers/dma/ipu/ipu_idmac.c
drivers/edac/amd64_edac.c
drivers/firmware/dmi_scan.c
drivers/gpio/pca953x.c
drivers/gpu/drm/drm_info.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_reg.h
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_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/evergreen_blit_shaders.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/mkregtable.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100_track.h
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300_reg.h
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/r600_blit_shaders.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.h
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/reg_srcs/r300
drivers/gpu/drm/radeon/reg_srcs/r420
drivers/gpu/drm/radeon/reg_srcs/rs600
drivers/gpu/drm/radeon/reg_srcs/rv515
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/rv770d.h
drivers/hwmon/emc1403.c
drivers/hwmon/lm63.c
drivers/input/input.c
drivers/input/misc/rotary_encoder.c
drivers/input/serio/serio.c
drivers/input/tablet/wacom_sys.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/wacom_w8001.c
drivers/isdn/hysdn/hysdn_defs.h
drivers/isdn/hysdn/hysdn_init.c
drivers/isdn/hysdn/hysdn_net.c
drivers/isdn/hysdn/hysdn_procconf.c
drivers/md/md.c
drivers/md/md.h
drivers/md/raid0.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/net/benet/be_cmds.c
drivers/net/bnx2x/bnx2x_main.c
drivers/net/can/mscan/Kconfig
drivers/net/can/pch_can.c
drivers/net/can/softing/softing_cs.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000e/netdev.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_fcoe.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_sriov.c
drivers/net/ixgbe/ixgbe_x540.c
drivers/net/pch_gbe/pch_gbe_main.c
drivers/net/sis900.c
drivers/net/usb/cdc_ncm.c
drivers/net/virtio_net.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/rx.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/wl1251/main.c
drivers/pci/pci-sysfs.c
drivers/rtc/rtc-at32ap700x.c
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-bfin.c
drivers/rtc/rtc-dev.c
drivers/rtc/rtc-ds1286.c
drivers/rtc/rtc-ds1305.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1374.c
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-m48t59.c
drivers/rtc/rtc-mrst.c
drivers/rtc/rtc-msm6242.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-proc.c
drivers/rtc/rtc-rp5c01.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-test.c
drivers/rtc/rtc-vr41xx.c
drivers/spi/spi_sh_msiof.c
drivers/ssb/pcmcia.c
drivers/staging/brcm80211/sys/wl_mac80211.c
drivers/staging/brcm80211/sys/wlc_mac80211.c
drivers/staging/brcm80211/sys/wlc_pub.h
drivers/staging/comedi/Kconfig
drivers/staging/comedi/drivers/mite.c
drivers/staging/comedi/drivers/ni_6527.c
drivers/staging/comedi/drivers/ni_65xx.c
drivers/staging/comedi/drivers/ni_660x.c
drivers/staging/comedi/drivers/ni_670x.c
drivers/staging/comedi/drivers/ni_pcidio.c
drivers/staging/comedi/drivers/ni_pcimio.c
drivers/staging/hv/netvsc_drv.c
drivers/staging/intel_sst/intelmid_v2_control.c
drivers/staging/zram/zram_drv.c
drivers/tty/hvc/Makefile
drivers/tty/n_gsm.c
drivers/tty/serial/68328serial.c
drivers/tty/serial/68360serial.c
drivers/tty/serial/bfin_5xx.c
drivers/tty/sysrq.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-au1xxx.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/sl811-hcd.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_dma.h
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_gadget.h
drivers/usb/musb/musb_host.c
drivers/usb/musb/musbhsdma.h
drivers/usb/otg/Kconfig
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/storage/unusual_devs.h
drivers/w1/masters/omap_hdq.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/m54xx_wdt.c [moved from drivers/watchdog/m548x_wdt.c with 80% similarity]
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_map.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/relocation.c
fs/btrfs/volumes.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/transport.c
fs/dlm/lowcomms.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/file.c
fs/ext4/mballoc.c
fs/ext4/page-io.c
fs/ext4/super.c
fs/jbd2/journal.c
fs/jbd2/transaction.c
fs/namei.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4state.c
fs/nfsd/state.h
fs/nfsd/vfs.c
fs/open.c
fs/proc/array.c
fs/super.c
include/linux/huge_mm.h
include/linux/input/matrix_keypad.h
include/linux/klist.h
include/linux/oprofile.h
include/linux/security.h
include/linux/usb/cdc.h
include/linux/usb/msm_hsusb_hw.h
include/linux/virtio_console.h
init/calibrate.c
kernel/capability.c
kernel/perf_event.c
kernel/printk.c
kernel/ptrace.c
kernel/time/timer_list.c
kernel/timer.c
kernel/trace/blktrace.c
lib/Kconfig.debug
mm/huge_memory.c
mm/memblock.c
mm/memory.c
mm/vmscan.c
net/batman-adv/unicast.c
net/caif/chnl_net.c
net/core/dev.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/status.c
net/mac80211/tx.c
net/netfilter/nf_conntrack_core.c
net/x25/x25_facilities.c
net/x25/x25_in.c
net/x25/x25_link.c
scripts/package/builddeb
security/security.c
sound/core/hrtimer.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/wm8994.c
sound/soc/davinci/davinci-evm.c
sound/soc/soc-core.c
sound/usb/mixer.c
sound/usb/quirks-table.h
sound/usb/quirks.c
tools/power/x86/turbostat/turbostat.c

index 2861055..c279158 100644 (file)
@@ -73,8 +73,8 @@
       services.
     </para>
     <para>
-      The core of every DRM driver is struct drm_device.  Drivers
-      will typically statically initialize a drm_device structure,
+      The core of every DRM driver is struct drm_driver.  Drivers
+      will typically statically initialize a drm_driver structure,
       then pass it to drm_init() at load time.
     </para>
 
@@ -84,7 +84,7 @@
     <title>Driver initialization</title>
     <para>
       Before calling the DRM initialization routines, the driver must
-      first create and fill out a struct drm_device structure.
+      first create and fill out a struct drm_driver structure.
     </para>
     <programlisting>
       static struct drm_driver driver = {
@@ -13,7 +13,6 @@ Table of Contents
 
   I - Introduction
     1) Entry point for arch/powerpc
-    2) Board support
 
   II - The DT block format
     1) Header
@@ -41,13 +40,6 @@ Table of Contents
   VI - System-on-a-chip devices and nodes
     1) Defining child nodes of an SOC
     2) Representing devices without a current OF specification
-      a) PHY nodes
-      b) Interrupt controllers
-      c) 4xx/Axon EMAC ethernet nodes
-      d) Xilinx IP cores
-      e) USB EHCI controllers
-      f) MDIO on GPIOs
-      g) SPI busses
 
   VII - Specifying interrupt information for devices
     1) interrupts property
@@ -123,7 +115,7 @@ Revision Information
 I - Introduction
 ================
 
-During the recent development of the Linux/ppc64 kernel, and more
+During the development of the Linux/ppc64 kernel, and more
 specifically, the addition of new platform types outside of the old
 IBM pSeries/iSeries pair, it was decided to enforce some strict rules
 regarding the kernel entry and bootloader <-> kernel interfaces, in
@@ -146,7 +138,7 @@ section III, but, for example, the kernel does not require you to
 create a node for every PCI device in the system. It is a requirement
 to have a node for PCI host bridges in order to provide interrupt
 routing informations and memory/IO ranges, among others. It is also
-recommended to define nodes for on chip devices and other busses that
+recommended to define nodes for on chip devices and other buses that
 don't specifically fit in an existing OF specification. This creates a
 great flexibility in the way the kernel can then probe those and match
 drivers to device, without having to hard code all sorts of tables. It
@@ -158,7 +150,7 @@ it with special cases.
 1) Entry point for arch/powerpc
 -------------------------------
 
-   There is one and one single entry point to the kernel, at the start
+   There is one single entry point to the kernel, at the start
    of the kernel image. That entry point supports two calling
    conventions:
 
@@ -210,12 +202,6 @@ it with special cases.
         with all CPUs. The way to do that with method b) will be
         described in a later revision of this document.
 
-
-2) Board support
-----------------
-
-64-bit kernels:
-
    Board supports (platforms) are not exclusive config options. An
    arbitrary set of board supports can be built in a single kernel
    image. The kernel will "know" what set of functions to use for a
@@ -234,48 +220,11 @@ it with special cases.
         containing the various callbacks that the generic code will
         use to get to your platform specific code
 
-        c) Add a reference to your "ppc_md" structure in the
-        "machines" table in arch/powerpc/kernel/setup_64.c if you are
-        a 64-bit platform.
-
-        d) request and get assigned a platform number (see PLATFORM_*
-        constants in arch/powerpc/include/asm/processor.h
-
-32-bit embedded kernels:
-
-  Currently, board support is essentially an exclusive config option.
-  The kernel is configured for a single platform.  Part of the reason
-  for this is to keep kernels on embedded systems small and efficient;
-  part of this is due to the fact the code is already that way. In the
-  future, a kernel may support multiple platforms, but only if the
+  A kernel image may support multiple platforms, but only if the
   platforms feature the same core architecture.  A single kernel build
   cannot support both configurations with Book E and configurations
   with classic Powerpc architectures.
 
-  32-bit embedded platforms that are moved into arch/powerpc using a
-  flattened device tree should adopt the merged tree practice of
-  setting ppc_md up dynamically, even though the kernel is currently
-  built with support for only a single platform at a time.  This allows
-  unification of the setup code, and will make it easier to go to a
-  multiple-platform-support model in the future.
-
-NOTE: I believe the above will be true once Ben's done with the merge
-of the boot sequences.... someone speak up if this is wrong!
-
-  To add a 32-bit embedded platform support, follow the instructions
-  for 64-bit platforms above, with the exception that the Kconfig
-  option should be set up such that the kernel builds exclusively for
-  the platform selected.  The processor type for the platform should
-  enable another config option to select the specific board
-  supported.
-
-NOTE: If Ben doesn't merge the setup files, may need to change this to
-point to setup_32.c
-
-
-   I will describe later the boot process and various callbacks that
-   your platform should implement.
-
 
 II - The DT block format
 ========================
@@ -300,8 +249,8 @@ the block to RAM before passing it to the kernel.
 1) Header
 ---------
 
-   The kernel is entered with r3 pointing to an area of memory that is
-   roughly described in arch/powerpc/include/asm/prom.h by the structure
+   The kernel is passed the physical address pointing to an area of memory
+   that is roughly described in include/linux/of_fdt.h by the structure
    boot_param_header:
 
 struct boot_param_header {
@@ -339,7 +288,7 @@ struct boot_param_header {
    All values in this header are in big endian format, the various
    fields in this header are defined more precisely below. All
    "offset" values are in bytes from the start of the header; that is
-   from the value of r3.
+   from the physical base address of the device tree block.
 
    - magic
 
@@ -437,7 +386,7 @@ struct boot_param_header {
 
 
              ------------------------------
-       r3 -> |  struct boot_param_header  |
+     base -> |  struct boot_param_header  |
              ------------------------------
              |      (alignment gap) (*)   |
              ------------------------------
@@ -457,7 +406,7 @@ struct boot_param_header {
       -----> ------------------------------
       |
       |
-      --- (r3 + totalsize)
+      --- (base + totalsize)
 
   (*) The alignment gaps are not necessarily present; their presence
       and size are dependent on the various alignment requirements of
@@ -500,7 +449,7 @@ the device-tree structure. It is typically used to represent "path" in
 the device-tree. More details about the actual format of these will be
 below.
 
-The kernel powerpc generic code does not make any formal use of the
+The kernel generic code does not make any formal use of the
 unit address (though some board support code may do) so the only real
 requirement here for the unit address is to ensure uniqueness of
 the node unit name at a given level of the tree. Nodes with no notion
@@ -518,20 +467,21 @@ path to the root node is "/".
 
 Every node which actually represents an actual device (that is, a node
 which isn't only a virtual "container" for more nodes, like "/cpus"
-is) is also required to have a "device_type" property indicating the
-type of node .
+is) is also required to have a "compatible" property indicating the
+specific hardware and an optional list of devices it is fully
+backwards compatible with.
 
 Finally, every node that can be referenced from a property in another
-node is required to have a "linux,phandle" property. Real open
-firmware implementations provide a unique "phandle" value for every
-node that the "prom_init()" trampoline code turns into
-"linux,phandle" properties. However, this is made optional if the
-flattened device tree is used directly. An example of a node
+node is required to have either a "phandle" or a "linux,phandle"
+property. Real Open Firmware implementations provide a unique
+"phandle" value for every node that the "prom_init()" trampoline code
+turns into "linux,phandle" properties. However, this is made optional
+if the flattened device tree is used directly. An example of a node
 referencing another node via "phandle" is when laying out the
 interrupt tree which will be described in a further version of this
 document.
 
-This "linux, phandle" property is a 32-bit value that uniquely
+The "phandle" property is a 32-bit value that uniquely
 identifies a node. You are free to use whatever values or system of
 values, internal pointers, or whatever to generate these, the only
 requirement is that every node for which you provide that property has
@@ -694,7 +644,7 @@ made of 3 cells, the bottom two containing the actual address itself
 while the top cell contains address space indication, flags, and pci
 bus & device numbers.
 
-For busses that support dynamic allocation, it's the accepted practice
+For buses that support dynamic allocation, it's the accepted practice
 to then not provide the address in "reg" (keep it 0) though while
 providing a flag indicating the address is dynamically allocated, and
 then, to provide a separate "assigned-addresses" property that
@@ -711,7 +661,7 @@ prom_parse.c file of the recent kernels for your bus type.
 The "reg" property only defines addresses and sizes (if #size-cells is
 non-0) within a given bus. In order to translate addresses upward
 (that is into parent bus addresses, and possibly into CPU physical
-addresses), all busses must contain a "ranges" property. If the
+addresses), all buses must contain a "ranges" property. If the
 "ranges" property is missing at a given level, it's assumed that
 translation isn't possible, i.e., the registers are not visible on the
 parent bus.  The format of the "ranges" property for a bus is a list
@@ -727,9 +677,9 @@ example, for a PCI host controller, that would be a CPU address. For a
 PCI<->ISA bridge, that would be a PCI address. It defines the base
 address in the parent bus where the beginning of that range is mapped.
 
-For a new 64-bit powerpc board, I recommend either the 2/2 format or
+For new 64-bit board support, I recommend either the 2/2 format or
 Apple's 2/1 format which is slightly more compact since sizes usually
-fit in a single 32-bit word.   New 32-bit powerpc boards should use a
+fit in a single 32-bit word.   New 32-bit board support should use a
 1/1 format, unless the processor supports physical addresses greater
 than 32-bits, in which case a 2/1 format is recommended.
 
@@ -754,7 +704,7 @@ of their actual names.
 While earlier users of Open Firmware like OldWorld macintoshes tended
 to use the actual device name for the "name" property, it's nowadays
 considered a good practice to use a name that is closer to the device
-class (often equal to device_type). For example, nowadays, ethernet
+class (often equal to device_type). For example, nowadays, Ethernet
 controllers are named "ethernet", an additional "model" property
 defining precisely the chip type/model, and "compatible" property
 defining the family in case a single driver can driver more than one
@@ -772,7 +722,7 @@ is present).
 4) Note about node and property names and character set
 -------------------------------------------------------
 
-While open firmware provides more flexible usage of 8859-1, this
+While Open Firmware provides more flexible usage of 8859-1, this
 specification enforces more strict rules. Nodes and properties should
 be comprised only of ASCII characters 'a' to 'z', '0' to
 '9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally
@@ -792,7 +742,7 @@ address which can extend beyond that limit.
 --------------------------------
   These are all that are currently required. However, it is strongly
   recommended that you expose PCI host bridges as documented in the
-  PCI binding to open firmware, and your interrupt tree as documented
+  PCI binding to Open Firmware, and your interrupt tree as documented
   in OF interrupt tree specification.
 
   a) The root node
@@ -802,20 +752,12 @@ address which can extend beyond that limit.
     - model : this is your board name/model
     - #address-cells : address representation for "root" devices
     - #size-cells: the size representation for "root" devices
-    - device_type : This property shouldn't be necessary. However, if
-      you decide to create a device_type for your root node, make sure it
-      is _not_ "chrp" unless your platform is a pSeries or PAPR compliant
-      one for 64-bit, or a CHRP-type machine for 32-bit as this will
-      matched by the kernel this way.
-
-  Additionally, some recommended properties are:
-
     - compatible : the board "family" generally finds its way here,
       for example, if you have 2 board models with a similar layout,
       that typically get driven by the same platform code in the
-      kernel, you would use a different "model" property but put a
-      value in "compatible". The kernel doesn't directly use that
-      value but it is generally useful.
+      kernel, you would specify the exact board model in the
+      compatible property followed by an entry that represents the SoC
+      model.
 
   The root node is also generally where you add additional properties
   specific to your board like the serial number if any, that sort of
@@ -841,8 +783,11 @@ address which can extend beyond that limit.
 
   So under /cpus, you are supposed to create a node for every CPU on
   the machine. There is no specific restriction on the name of the
-  CPU, though It's common practice to call it PowerPC,<name>. For
+  CPU, though it's common to call it <architecture>,<core>. For
   example, Apple uses PowerPC,G5 while IBM uses PowerPC,970FX.
+  However, the Generic Names convention suggests that it would be
+  better to simply use 'cpu' for each cpu node and use the compatible
+  property to identify the specific cpu core.
 
   Required properties:
 
@@ -923,7 +868,7 @@ compatibility.
 
   e) The /chosen node
 
-  This node is a bit "special". Normally, that's where open firmware
+  This node is a bit "special". Normally, that's where Open Firmware
   puts some variable environment information, like the arguments, or
   the default input/output devices.
 
@@ -940,11 +885,7 @@ compatibility.
       console device if any. Typically, if you have serial devices on
       your board, you may want to put the full path to the one set as
       the default console in the firmware here, for the kernel to pick
-      it up as its own default console. If you look at the function
-      set_preferred_console() in arch/ppc64/kernel/setup.c, you'll see
-      that the kernel tries to find out the default console and has
-      knowledge of various types like 8250 serial ports. You may want
-      to extend this function to add your own.
+      it up as its own default console.
 
   Note that u-boot creates and fills in the chosen node for platforms
   that use it.
@@ -955,23 +896,23 @@ compatibility.
 
   f) the /soc<SOCname> node
 
-  This node is used to represent a system-on-a-chip (SOC) and must be
-  present if the processor is a SOC. The top-level soc node contains
-  information that is global to all devices on the SOC. The node name
-  should contain a unit address for the SOC, which is the base address
-  of the memory-mapped register set for the SOC. The name of an soc
+  This node is used to represent a system-on-a-chip (SoC) and must be
+  present if the processor is a SoC. The top-level soc node contains
+  information that is global to all devices on the SoC. The node name
+  should contain a unit address for the SoC, which is the base address
+  of the memory-mapped register set for the SoC. The name of an SoC
   node should start with "soc", and the remainder of the name should
   represent the part number for the soc.  For example, the MPC8540's
   soc node would be called "soc8540".
 
   Required properties:
 
-    - device_type : Should be "soc"
     - ranges : Should be defined as specified in 1) to describe the
-      translation of SOC addresses for memory mapped SOC registers.
-    - bus-frequency: Contains the bus frequency for the SOC node.
+      translation of SoC addresses for memory mapped SoC registers.
+    - bus-frequency: Contains the bus frequency for the SoC node.
       Typically, the value of this field is filled in by the boot
       loader.
+    - compatible : Exact model of the SoC
 
 
   Recommended properties:
@@ -1155,12 +1096,13 @@ while all this has been defined and implemented.
 
   - An example of code for iterating nodes & retrieving properties
     directly from the flattened tree format can be found in the kernel
-    file arch/ppc64/kernel/prom.c, look at scan_flat_dt() function,
+    file drivers/of/fdt.c.  Look at the of_scan_flat_dt() function,
     its usage in early_init_devtree(), and the corresponding various
     early_init_dt_scan_*() callbacks. That code can be re-used in a
     GPL bootloader, and as the author of that code, I would be happy
     to discuss possible free licensing to any vendor who wishes to
     integrate all or part of this code into a non-GPL bootloader.
+    (reference needed; who is 'I' here? ---gcl Jan 31, 2011)
 
 
 
@@ -1203,18 +1145,19 @@ MPC8540.
 2) Representing devices without a current OF specification
 ----------------------------------------------------------
 
-Currently, there are many devices on SOCs that do not have a standard
-representation pre-defined as part of the open firmware
-specifications, mainly because the boards that contain these SOCs are
-not currently booted using open firmware.   This section contains
-descriptions for the SOC devices for which new nodes have been
-defined; this list will expand as more and more SOC-containing
-platforms are moved over to use the flattened-device-tree model.
+Currently, there are many devices on SoCs that do not have a standard
+representation defined as part of the Open Firmware specifications,
+mainly because the boards that contain these SoCs are not currently
+booted using Open Firmware.  Binding documentation for new devices
+should be added to the Documentation/devicetree/bindings directory.
+That directory will expand as device tree support is added to more and
+more SoCs.
+
 
 VII - Specifying interrupt information for devices
 ===================================================
 
-The device tree represents the busses and devices of a hardware
+The device tree represents the buses and devices of a hardware
 system in a form similar to the physical bus topology of the
 hardware.
 
index 531c5cf..5dd6c75 100644 (file)
@@ -2126,6 +2126,7 @@ S:        Supported
 F:     fs/dlm/
 
 DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
+M:     Vinod Koul <vinod.koul@intel.com>
 M:     Dan Williams <dan.j.williams@intel.com>
 S:     Supported
 F:     drivers/dma/
@@ -2774,6 +2775,15 @@ F:       Documentation/isdn/README.gigaset
 F:     drivers/isdn/gigaset/
 F:     include/linux/gigaset_dev.h
 
+GPIO SUBSYSTEM
+M:     Grant Likely <grant.likely@secretlab.ca>
+L:     linux-kernel@vger.kernel.org
+S:     Maintained
+T:     git git://git.secretlab.ca/git/linux-2.6.git
+F:     Documentation/gpio/gpio.txt
+F:     drivers/gpio/
+F:     include/linux/gpio*
+
 GRETH 10/100/1G Ethernet MAC device driver
 M:     Kristoffer Glembo <kristoffer@gaisler.com>
 L:     netdev@vger.kernel.org
@@ -4591,7 +4601,7 @@ F:        drivers/i2c/busses/i2c-ocores.c
 
 OPEN FIRMWARE AND FLATTENED DEVICE TREE
 M:     Grant Likely <grant.likely@secretlab.ca>
-L:     devicetree-discuss@lists.ozlabs.org
+L:     devicetree-discuss@lists.ozlabs.org (moderated for non-subscribers)
 W:     http://fdt.secretlab.ca
 T:     git git://git.secretlab.ca/git/linux-2.6.git
 S:     Maintained
index c9c8c8f..5e40aa2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 38
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
index 5cff165..26d45e5 100644 (file)
@@ -1391,7 +1391,7 @@ config AEABI
 
 config OABI_COMPAT
        bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
-       depends on AEABI && EXPERIMENTAL
+       depends on AEABI && EXPERIMENTAL && !THUMB2_KERNEL
        default y
        help
          This option preserves the old syscall interface along with the
index c0225da..f06ff9f 100644 (file)
@@ -391,6 +391,7 @@ ENDPROC(__turn_mmu_on)
 
 
 #ifdef CONFIG_SMP_ON_UP
+       __INIT
 __fixup_smp:
        and     r3, r9, #0x000f0000     @ architecture version
        teq     r3, #0x000f0000         @ CPU ID supported?
@@ -415,18 +416,7 @@ __fixup_smp_on_up:
        sub     r3, r0, r3
        add     r4, r4, r3
        add     r5, r5, r3
-2:     cmp     r4, r5
-       movhs   pc, lr
-       ldmia   r4!, {r0, r6}
- ARM(  str     r6, [r0, r3]    )
- THUMB(        add     r0, r0, r3      )
-#ifdef __ARMEB__
- THUMB(        mov     r6, r6, ror #16 )       @ Convert word order for big-endian.
-#endif
- THUMB(        strh    r6, [r0], #2    )       @ For Thumb-2, store as two halfwords
- THUMB(        mov     r6, r6, lsr #16 )       @ to be robust against misaligned r3.
- THUMB(        strh    r6, [r0]        )
-       b       2b
+       b       __do_fixup_smp_on_up
 ENDPROC(__fixup_smp)
 
        .align
@@ -440,7 +430,31 @@ smp_on_up:
        ALT_SMP(.long   1)
        ALT_UP(.long    0)
        .popsection
+#endif
 
+       .text
+__do_fixup_smp_on_up:
+       cmp     r4, r5
+       movhs   pc, lr
+       ldmia   r4!, {r0, r6}
+ ARM(  str     r6, [r0, r3]    )
+ THUMB(        add     r0, r0, r3      )
+#ifdef __ARMEB__
+ THUMB(        mov     r6, r6, ror #16 )       @ Convert word order for big-endian.
 #endif
+ THUMB(        strh    r6, [r0], #2    )       @ For Thumb-2, store as two halfwords
+ THUMB(        mov     r6, r6, lsr #16 )       @ to be robust against misaligned r3.
+ THUMB(        strh    r6, [r0]        )
+       b       __do_fixup_smp_on_up
+ENDPROC(__do_fixup_smp_on_up)
+
+ENTRY(fixup_smp)
+       stmfd   sp!, {r4 - r6, lr}
+       mov     r4, r0
+       add     r5, r0, r1
+       mov     r3, #0
+       bl      __do_fixup_smp_on_up
+       ldmfd   sp!, {r4 - r6, pc}
+ENDPROC(fixup_smp)
 
 #include "head-common.S"
index c9f3f04..d600bd3 100644 (file)
@@ -137,11 +137,10 @@ static u8 get_debug_arch(void)
        u32 didr;
 
        /* Do we implement the extended CPUID interface? */
-       if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
-               pr_warning("CPUID feature registers not supported. "
-                               "Assuming v6 debug is present.\n");
+       if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf),
+           "CPUID feature registers not supported. "
+           "Assuming v6 debug is present.\n"))
                return ARM_DEBUG_ARCH_V6;
-       }
 
        ARM_DBG_READ(c0, 0, didr);
        return (didr >> 16) & 0xf;
@@ -152,6 +151,12 @@ u8 arch_get_debug_arch(void)
        return debug_arch;
 }
 
+static int debug_arch_supported(void)
+{
+       u8 arch = get_debug_arch();
+       return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14;
+}
+
 /* Determine number of BRP register available. */
 static int get_num_brp_resources(void)
 {
@@ -268,6 +273,9 @@ out:
 
 int hw_breakpoint_slots(int type)
 {
+       if (!debug_arch_supported())
+               return 0;
+
        /*
         * We can be called early, so don't rely on
         * our static variables being initialised.
@@ -834,11 +842,11 @@ static void reset_ctrl_regs(void *unused)
 
        /*
         * v7 debug contains save and restore registers so that debug state
-        * can be maintained across low-power modes without leaving
-        * the debug logic powered up. It is IMPLEMENTATION DEFINED whether
-        * we can write to the debug registers out of reset, so we must
-        * unlock the OS Lock Access Register to avoid taking undefined
-        * instruction exceptions later on.
+        * can be maintained across low-power modes without leaving the debug
+        * logic powered up. It is IMPLEMENTATION DEFINED whether we can access
+        * the debug registers out of reset, so we must unlock the OS Lock
+        * Access Register to avoid taking undefined instruction exceptions
+        * later on.
         */
        if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
                /*
@@ -882,7 +890,7 @@ static int __init arch_hw_breakpoint_init(void)
 
        debug_arch = get_debug_arch();
 
-       if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) {
+       if (!debug_arch_supported()) {
                pr_info("debug architecture 0x%x unsupported.\n", debug_arch);
                return 0;
        }
@@ -899,18 +907,18 @@ static int __init arch_hw_breakpoint_init(void)
                pr_info("%d breakpoint(s) reserved for watchpoint "
                                "single-step.\n", core_num_reserved_brps);
 
+       /*
+        * Reset the breakpoint resources. We assume that a halting
+        * debugger will leave the world in a nice state for us.
+        */
+       on_each_cpu(reset_ctrl_regs, NULL, 1);
+
        ARM_DBG_READ(c1, 0, dscr);
        if (dscr & ARM_DSCR_HDBGEN) {
+               max_watchpoint_len = 4;
                pr_warning("halting debug mode enabled. Assuming maximum "
-                               "watchpoint size of 4 bytes.");
+                          "watchpoint size of %u bytes.", max_watchpoint_len);
        } else {
-               /*
-                * Reset the breakpoint resources. We assume that a halting
-                * debugger will leave the world in a nice state for us.
-                */
-               smp_call_function(reset_ctrl_regs, NULL, 1);
-               reset_ctrl_regs(NULL);
-
                /* Work out the maximum supported watchpoint length. */
                max_watchpoint_len = get_max_wp_len();
                pr_info("maximum watchpoint size is %u bytes.\n",
index 2cfe816..6d4105e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/pgtable.h>
 #include <asm/sections.h>
+#include <asm/smp_plat.h>
 #include <asm/unwind.h>
 
 #ifdef CONFIG_XIP_KERNEL
@@ -268,12 +269,28 @@ struct mod_unwind_map {
        const Elf_Shdr *txt_sec;
 };
 
+static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr,
+       const Elf_Shdr *sechdrs, const char *name)
+{
+       const Elf_Shdr *s, *se;
+       const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+       for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++)
+               if (strcmp(name, secstrs + s->sh_name) == 0)
+                       return s;
+
+       return NULL;
+}
+
+extern void fixup_smp(const void *, unsigned long);
+
 int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
                    struct module *mod)
 {
+       const Elf_Shdr * __maybe_unused s = NULL;
 #ifdef CONFIG_ARM_UNWIND
        const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-       const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+       const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;
        struct mod_unwind_map maps[ARM_SEC_MAX];
        int i;
 
@@ -315,6 +332,9 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
                                                 maps[i].txt_sec->sh_addr,
                                                 maps[i].txt_sec->sh_size);
 #endif
+       s = find_mod_section(hdr, sechdrs, ".alt.smp.init");
+       if (s && !is_smp())
+               fixup_smp((void *)s->sh_addr, s->sh_size);
        return 0;
 }
 
index 5efa264..d150ad1 100644 (file)
@@ -700,7 +700,7 @@ user_backtrace(struct frame_tail __user *tail,
         * Frame pointers should strictly progress back up the stack
         * (towards higher addresses).
         */
-       if (tail >= buftail.fp)
+       if (tail + 1 >= buftail.fp)
                return NULL;
 
        return buftail.fp - 1;
index 6b2c800..28f667e 100644 (file)
@@ -50,7 +50,7 @@ static void __init colibri_mmc_init(void)
                        GPIO0_COLIBRI_PXA270_SD_DETECT;
        if (machine_is_colibri300())    /* PXA300 Colibri */
                colibri_mci_platform_data.gpio_card_detect =
-                       GPIO39_COLIBRI_PXA300_SD_DETECT;
+                       GPIO13_COLIBRI_PXA300_SD_DETECT;
        else                            /* PXA320 Colibri */
                colibri_mci_platform_data.gpio_card_detect =
                        GPIO28_COLIBRI_PXA320_SD_DETECT;
index fddb16d..66dd81c 100644 (file)
@@ -41,7 +41,7 @@ static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = {
        GPIO4_MMC1_DAT1,
        GPIO5_MMC1_DAT2,
        GPIO6_MMC1_DAT3,
-       GPIO39_GPIO,    /* SD detect */
+       GPIO13_GPIO,    /* GPIO13_COLIBRI_PXA300_SD_DETECT */
 
        /* UHC */
        GPIO0_2_USBH_PEN,
index 388a96f..cb4236e 100644 (file)
@@ -60,7 +60,7 @@ static inline void colibri_pxa3xx_init_nand(void) {}
 #define GPIO113_COLIBRI_PXA270_TS_IRQ  113
 
 /* GPIO definitions for Colibri PXA300/310 */
-#define GPIO39_COLIBRI_PXA300_SD_DETECT        39
+#define GPIO13_COLIBRI_PXA300_SD_DETECT        13
 
 /* GPIO definitions for Colibri PXA320 */
 #define GPIO28_COLIBRI_PXA320_SD_DETECT        28
index 405b92a..35572c4 100644 (file)
@@ -323,7 +323,7 @@ static struct platform_pwm_backlight_data palm27x_backlight_data = {
        .pwm_id         = 0,
        .max_brightness = 0xfe,
        .dft_brightness = 0x7e,
-       .pwm_period_ns  = 3500,
+       .pwm_period_ns  = 3500 * 1024,
        .init           = palm27x_backlight_init,
        .notify         = palm27x_backlight_notify,
        .exit           = palm27x_backlight_exit,
index 978e1b2..1807c9a 100644 (file)
@@ -33,7 +33,7 @@ int pxa_pm_enter(suspend_state_t state)
 #endif
 
        /* skip registers saving for standby */
-       if (state != PM_SUSPEND_STANDBY) {
+       if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->save) {
                pxa_cpu_pm_fns->save(sleep_save);
                /* before sleeping, calculate and save a checksum */
                for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
@@ -44,7 +44,7 @@ int pxa_pm_enter(suspend_state_t state)
        pxa_cpu_pm_fns->enter(state);
        cpu_init();
 
-       if (state != PM_SUSPEND_STANDBY) {
+       if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) {
                /* after sleeping, validate the checksum */
                for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
                        checksum += sleep_save[i];
index 09c4c21..b2a9acc 100644 (file)
@@ -122,6 +122,7 @@ config MACH_SMDKV310
        select S3C_DEV_HSMMC2
        select S3C_DEV_HSMMC3
        select S5PV310_DEV_PD
+       select S5PV310_DEV_SYSMMU
        select S5PV310_SETUP_I2C1
        select S5PV310_SETUP_SDHCI
        help
index 74d4006..3060f78 100644 (file)
 #define S5PV310_PA_SYSMMU_TV           0x12E20000
 #define S5PV310_PA_SYSMMU_MFC_L                0x13620000
 #define S5PV310_PA_SYSMMU_MFC_R                0x13630000
-#define S5PV310_SYSMMU_TOTAL_IPNUM     16
-#define S5P_SYSMMU_TOTAL_IPNUM         S5PV310_SYSMMU_TOTAL_IPNUM
 
 /* compatibiltiy defines. */
 #define S3C_PA_UART                    S5PV310_PA_UART
index 662fe85..598fc5c 100644 (file)
@@ -13,6 +13,9 @@
 #ifndef __ASM_ARM_ARCH_SYSMMU_H
 #define __ASM_ARM_ARCH_SYSMMU_H __FILE__
 
+#define S5PV310_SYSMMU_TOTAL_IPNUM     16
+#define S5P_SYSMMU_TOTAL_IPNUM         S5PV310_SYSMMU_TOTAL_IPNUM
+
 enum s5pv310_sysmmu_ips {
        SYSMMU_MDMA,
        SYSMMU_SSS,
@@ -32,7 +35,7 @@ enum s5pv310_sysmmu_ips {
        SYSMMU_MFC_R,
 };
 
-static char *sysmmu_ips_name[S5P_SYSMMU_TOTAL_IPNUM] = {
+static char *sysmmu_ips_name[S5PV310_SYSMMU_TOTAL_IPNUM] = {
        "SYSMMU_MDMA"   ,
        "SYSMMU_SSS"    ,
        "SYSMMU_FIMC0"  ,
index d43c5ef..bd3e1bf 100644 (file)
@@ -241,6 +241,9 @@ static struct locomo_platform_data locomo_info = {
 struct platform_device collie_locomo_device = {
        .name           = "locomo",
        .id             = 0,
+       .dev            = {
+               .platform_data  = &locomo_info,
+       },
        .num_resources  = ARRAY_SIZE(locomo_resources),
        .resource       = locomo_resources,
 };
index 9d30c6f..e4509ba 100644 (file)
@@ -405,7 +405,7 @@ config CPU_V6
 config CPU_32v6K
        bool "Support ARM V6K processor extensions" if !SMP
        depends on CPU_V6 || CPU_V7
-       default y if SMP && !(ARCH_MX3 || ARCH_OMAP2)
+       default y if SMP
        help
          Say Y here if your ARMv6 processor supports the 'K' extension.
          This enables the kernel to use some instructions not present
@@ -416,7 +416,7 @@ config CPU_32v6K
 # ARMv7
 config CPU_V7
        bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
-       select CPU_32v6K if !ARCH_OMAP2
+       select CPU_32v6K
        select CPU_32v7
        select CPU_ABRT_EV7
        select CPU_PABRT_V7
@@ -644,7 +644,7 @@ config ARM_THUMBEE
 
 config SWP_EMULATE
        bool "Emulate SWP/SWPB instructions"
-       depends on CPU_V7 && !CPU_V6
+       depends on !CPU_USE_DOMAINS && CPU_V7 && !CPU_V6
        select HAVE_PROC_CPU if PROC_FS
        default y if SMP
        help
index 8aa9744..c074e66 100644 (file)
@@ -10,8 +10,6 @@
  */
 
 #include <linux/cpumask.h>
-#include <linux/err.h>
-#include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/oprofile.h>
@@ -46,6 +44,7 @@ char *op_name_from_perf_id(void)
                return NULL;
        }
 }
+#endif
 
 static int report_trace(struct stackframe *frame, void *d)
 {
@@ -85,7 +84,7 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail)
 
        /* frame pointers should strictly progress back up the stack
         * (towards higher addresses) */
-       if (tail >= buftail[0].fp)
+       if (tail + 1 >= buftail[0].fp)
                return NULL;
 
        return buftail[0].fp-1;
@@ -111,6 +110,7 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
 
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
+       /* provide backtrace support also in timer mode: */
        ops->backtrace          = arm_backtrace;
 
        return oprofile_perf_init(ops);
@@ -120,11 +120,3 @@ void __exit oprofile_arch_exit(void)
 {
        oprofile_perf_exit();
 }
-#else
-int __init oprofile_arch_init(struct oprofile_operations *ops)
-{
-       pr_info("oprofile: hardware counters not available\n");
-       return -ENODEV;
-}
-void __exit oprofile_arch_exit(void) {}
-#endif /* CONFIG_HW_PERF_EVENTS */
index b77e018..a9aa5ad 100644 (file)
@@ -139,10 +139,11 @@ static const unsigned long mfpr_edge[] = {
 #define mfp_configured(p)      ((p)->config != -1)
 
 /*
- * perform a read-back of any MFPR register to make sure the
+ * perform a read-back of any valid MFPR register to make sure the
  * previous writings are finished
  */
-#define mfpr_sync()    (void)__raw_readl(mfpr_mmio_base + 0)
+static unsigned long mfpr_off_readback;
+#define mfpr_sync()    (void)__raw_readl(mfpr_mmio_base + mfpr_off_readback)
 
 static inline void __mfp_config_run(struct mfp_pin *p)
 {
@@ -248,6 +249,9 @@ void __init mfp_init_addr(struct mfp_addr_map *map)
 
        spin_lock_irqsave(&mfp_spin_lock, flags);
 
+       /* mfp offset for readback */
+       mfpr_off_readback = map[0].offset;
+
        for (p = map; p->start != MFP_PIN_INVALID; p++) {
                offset = p->offset;
                i = p->start;
index deb3995..557f8c5 100644 (file)
@@ -37,6 +37,14 @@ config S5P_GPIO_INT
        help
          Common code for the GPIO interrupts (other than external interrupts.)
 
+comment "System MMU"
+
+config S5P_SYSTEM_MMU
+       bool "S5P SYSTEM MMU"
+       depends on ARCH_S5PV310
+       help
+         Say Y here if you want to enable System MMU
+
 config S5P_DEV_FIMC0
        bool
        help
@@ -66,19 +74,3 @@ config S5P_DEV_CSIS1
        bool
        help
          Compile in platform device definitions for MIPI-CSIS channel 1
-
-menuconfig S5P_SYSMMU
-       bool "SYSMMU support"
-       depends on ARCH_S5PV310
-       help
-         This is a System MMU driver for Samsung ARM based Soc.
-
-if S5P_SYSMMU
-
-config S5P_SYSMMU_DEBUG
-       bool "Enables debug messages"
-       depends on S5P_SYSMMU
-       help
-         This enables SYSMMU driver debug massages.
-
-endif
index 92efe1a..4bd5cf9 100644 (file)
@@ -19,6 +19,7 @@ obj-y                         += clock.o
 obj-y                          += irq.o
 obj-$(CONFIG_S5P_EXT_INT)      += irq-eint.o
 obj-$(CONFIG_S5P_GPIO_INT)     += irq-gpioint.o
+obj-$(CONFIG_S5P_SYSTEM_MMU)   += sysmmu.o
 obj-$(CONFIG_PM)               += pm.o
 obj-$(CONFIG_PM)               += irq-pm.o
 
@@ -30,4 +31,3 @@ obj-$(CONFIG_S5P_DEV_FIMC2)   += dev-fimc2.o
 obj-$(CONFIG_S5P_DEV_ONENAND)  += dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)    += dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)    += dev-csis1.o
-obj-$(CONFIG_S5P_SYSMMU)       += sysmmu.o
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
deleted file mode 100644 (file)
index db298fc..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Samsung sysmmu driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_S5P_SYSMMU_H
-#define __ASM_PLAT_S5P_SYSMMU_H __FILE__
-
-/* debug macro */
-#ifdef CONFIG_S5P_SYSMMU_DEBUG
-#define sysmmu_debug(fmt, arg...)      printk(KERN_INFO "[%s] " fmt, __func__, ## arg)
-#else
-#define sysmmu_debug(fmt, arg...)      do { } while (0)
-#endif
-
-#endif /* __ASM_PLAT_S5P_SYSMMU_H */
index d804914..ffe8a48 100644 (file)
@@ -16,8 +16,6 @@
 #include <mach/regs-sysmmu.h>
 #include <mach/sysmmu.h>
 
-#include <plat/sysmmu.h>
-
 struct sysmmu_controller s5p_sysmmu_cntlrs[S5P_SYSMMU_TOTAL_IPNUM];
 
 void s5p_sysmmu_register(struct sysmmu_controller *sysmmuconp)
@@ -123,7 +121,7 @@ static int s5p_sysmmu_set_tablebase(sysmmu_ips ips)
                : "=r" (pg) : : "cc");          \
                pg &= ~0x3fff;
 
-       sysmmu_debug("CP15 TTBR0 : 0x%x\n", pg);
+       printk(KERN_INFO "%s: CP15 TTBR0 : 0x%x\n", __func__, pg);
 
        /* Set sysmmu page table base address */
        __raw_writel(pg, sysmmuconp->regs + S5P_PT_BASE_ADDR);
index d9025e3..30518cc 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <linux/irq.h>
 
+struct sys_device;
+
 #ifdef CONFIG_PM
 
 extern __init int s3c_pm_init(void);
index 1ff9f14..7dbc664 100644 (file)
@@ -10,6 +10,7 @@
 #define __BFIN_ASM_SERIAL_H__
 
 #include <linux/serial_core.h>
+#include <linux/spinlock.h>
 #include <mach/anomaly.h>
 #include <mach/bfin_serial.h>
 
@@ -41,6 +42,7 @@ struct bfin_serial_port {
        struct circ_buf rx_dma_buf;
        struct timer_list rx_dma_timer;
        int rx_dma_nrows;
+       spinlock_t rx_lock;
        unsigned int tx_dma_channel;
        unsigned int rx_dma_channel;
        struct work_struct tx_dma_workqueue;
index 65b1312..3219845 100644 (file)
@@ -99,14 +99,12 @@ static inline int strcmp(const char *cs, const char *ct)
                : "+a" (cs), "+a" (ct), "=d" (res));
        return res;
 }
+#endif /* CONFIG_COLDFIRE */
 
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *, const void *, __kernel_size_t);
 
-#define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *, const void *, __kernel_size_t);
 #define memcmp(d, s, n) __builtin_memcmp(d, s, n)
-#endif /* CONFIG_COLDFIRE */
 
 #define __HAVE_ARCH_MEMSET
 extern void *memset(void *, int, __kernel_size_t);
index 4253f87..d399c5f 100644 (file)
@@ -243,14 +243,3 @@ void *memmove(void *dest, const void *src, size_t n)
        return xdest;
 }
 EXPORT_SYMBOL(memmove);
-
-int memcmp(const void *cs, const void *ct, size_t count)
-{
-       const unsigned char *su1, *su2;
-
-       for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--)
-               if (*su1 != *su2)
-                       return *su1 < *su2 ? -1 : +1;
-       return 0;
-}
-EXPORT_SYMBOL(memcmp);
index ef33213..47e15eb 100644 (file)
@@ -141,6 +141,12 @@ SECTIONS {
                *(__param)
                __stop___param = .;
 
+               /* Built-in module versions */
+               . = ALIGN(4) ;
+               __start___modver = .;
+               *(__modver)
+               __stop___modver = .;
+
                . = ALIGN(4) ;
                _etext = . ;
        } > TEXT
index d94d709..32d852e 100644 (file)
@@ -4,4 +4,4 @@
 
 lib-y  := ashldi3.o ashrdi3.o lshrdi3.o \
           muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
-          checksum.o memcpy.o memset.o delay.o
+          checksum.o memcpy.o memmove.o memset.o delay.o
diff --git a/arch/m68knommu/lib/memmove.c b/arch/m68knommu/lib/memmove.c
new file mode 100644 (file)
index 0000000..b3dcfe9
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#define __IN_STRING_C
+
+#include <linux/module.h>
+#include <linux/string.h>
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+       void *xdest = dest;
+       size_t temp;
+
+       if (!n)
+               return xdest;
+
+       if (dest < src) {
+               if ((long)dest & 1) {
+                       char *cdest = dest;
+                       const char *csrc = src;
+                       *cdest++ = *csrc++;
+                       dest = cdest;
+                       src = csrc;
+                       n--;
+               }
+               if (n > 2 && (long)dest & 2) {
+                       short *sdest = dest;
+                       const short *ssrc = src;
+                       *sdest++ = *ssrc++;
+                       dest = sdest;
+                       src = ssrc;
+                       n -= 2;
+               }
+               temp = n >> 2;
+               if (temp) {
+                       long *ldest = dest;
+                       const long *lsrc = src;
+                       temp--;
+                       do
+                               *ldest++ = *lsrc++;
+                       while (temp--);
+                       dest = ldest;
+                       src = lsrc;
+               }
+               if (n & 2) {
+                       short *sdest = dest;
+                       const short *ssrc = src;
+                       *sdest++ = *ssrc++;
+                       dest = sdest;
+                       src = ssrc;
+               }
+               if (n & 1) {
+                       char *cdest = dest;
+                       const char *csrc = src;
+                       *cdest = *csrc;
+               }
+       } else {
+               dest = (char *)dest + n;
+               src = (const char *)src + n;
+               if ((long)dest & 1) {
+                       char *cdest = dest;
+                       const char *csrc = src;
+                       *--cdest = *--csrc;
+                       dest = cdest;
+                       src = csrc;
+                       n--;
+               }
+               if (n > 2 && (long)dest & 2) {
+                       short *sdest = dest;
+                       const short *ssrc = src;
+                       *--sdest = *--ssrc;
+                       dest = sdest;
+                       src = ssrc;
+                       n -= 2;
+               }
+               temp = n >> 2;
+               if (temp) {
+                       long *ldest = dest;
+                       const long *lsrc = src;
+                       temp--;
+                       do
+                               *--ldest = *--lsrc;
+                       while (temp--);
+                       dest = ldest;
+                       src = lsrc;
+               }
+               if (n & 2) {
+                       short *sdest = dest;
+                       const short *ssrc = src;
+                       *--sdest = *--ssrc;
+                       dest = sdest;
+                       src = ssrc;
+               }
+               if (n & 1) {
+                       char *cdest = dest;
+                       const char *csrc = src;
+                       *--cdest = *--csrc;
+               }
+       }
+       return xdest;
+}
+EXPORT_SYMBOL(memmove);
index d09d9da..c5151f8 100644 (file)
@@ -50,8 +50,10 @@ static int __init mcf_intc2_init(void)
        int irq;
 
        /* GPIO interrupt sources */
-       for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++)
+       for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) {
                irq_desc[irq].chip = &intc2_irq_gpio_chip;
+               set_irq_handler(irq, handle_edge_irq);
+       }
 
        return 0;
 }
index 240a7a6..676960c 100644 (file)
@@ -108,7 +108,6 @@ Luser_return:
        movel   %d1,%a2
 1:
        move    %a2@(TI_FLAGS),%d1      /* thread_info->flags */
-       andl    #_TIF_WORK_MASK,%d1
        jne     Lwork_to_do
        RESTORE_ALL
 
index f27e688..8e4e10c 100644 (file)
@@ -210,7 +210,7 @@ void
 cpm_install_handler(int vec, void (*handler)(), void *dev_id)
 {
 
-       request_irq(vec, handler, IRQ_FLG_LOCK, "timer", dev_id);
+       request_irq(vec, handler, 0, "timer", dev_id);
 
 /*     if (cpm_vecs[vec].handler != 0) */
 /*             printk(KERN_INFO "CPM interrupt %x replacing %x\n", */
index ac629fa..9dd5bca 100644 (file)
@@ -75,7 +75,7 @@ void hw_timer_init(void)
   /* Set compare register  32Khz / 32 / 10 = 100 */
   TCMP = 10;                                                              
 
-  request_irq(IRQ_MACHSPEC | 1, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
+  request_irq(IRQ_MACHSPEC | 1, timer_routine, 0, "timer", NULL);
 #endif
 
   /* General purpose quicc timers: MC68360UM p7-20 */
index 8a28788..46c1b18 100644 (file)
@@ -104,7 +104,6 @@ Luser_return:
        movel   %d1,%a2
 1:
        move    %a2@(TI_FLAGS),%d1      /* thread_info->flags */
-       andl    #_TIF_WORK_MASK,%d1
        jne     Lwork_to_do
        RESTORE_ALL
 
index ad96ab1..a29041c 100644 (file)
@@ -132,8 +132,8 @@ void init_IRQ(void)
        pquicc->intr_cimr = 0x00000000;
 
        for (i = 0; (i < NR_IRQS); i++) {
-               set_irq_chip(irq, &intc_irq_chip);
-               set_irq_handler(irq, handle_level_irq);
+               set_irq_chip(i, &intc_irq_chip);
+               set_irq_handler(i, handle_level_irq);
        }
 }
 
index 4ddfc3d..5837cf0 100644 (file)
@@ -138,7 +138,6 @@ Luser_return:
        andl    #-THREAD_SIZE,%d1       /* at base of kernel stack */
        movel   %d1,%a0
        movel   %a0@(TI_FLAGS),%d1      /* get thread_info->flags */
-       andl    #0xefff,%d1
        jne     Lwork_to_do             /* still work to do */
 
 Lreturn:
index 5fd3190..c4532f0 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/types.h>
 #include <asm/registers.h>
 
-#ifdef CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
 
 static inline unsigned long arch_local_irq_save(void)
 {
index b23f680..885574a 100644 (file)
@@ -411,20 +411,19 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 static inline unsigned long pte_update(pte_t *p, unsigned long clr,
                                unsigned long set)
 {
-       unsigned long old, tmp, msr;
-
-       __asm__ __volatile__("\
-       msrclr  %2, 0x2\n\
-       nop\n\
-       lw      %0, %4, r0\n\
-       andn    %1, %0, %5\n\
-       or      %1, %1, %6\n\
-       sw      %1, %4, r0\n\
-       mts     rmsr, %2\n\
-       nop"
-       : "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p)
-       : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p)
-       : "cc");
+       unsigned long flags, old, tmp;
+
+       raw_local_irq_save(flags);
+
+       __asm__ __volatile__(   "lw     %0, %2, r0      \n"
+                               "andn   %1, %0, %3      \n"
+                               "or     %1, %1, %4      \n"
+                               "sw     %1, %2, r0      \n"
+                       : "=&r" (old), "=&r" (tmp)
+                       : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set)
+                       : "cc");
+
+       raw_local_irq_restore(flags);
 
        return old;
 }
index e01afa6..488c1ed 100644 (file)
@@ -27,7 +27,7 @@
        register unsigned tmp __asm__("r3");                    \
        tmp = 0x0;      /* Prevent warning about unused */      \
        __asm__ __volatile__ (                                  \
-                       "mfs    %0, rpvr" #pvrid ";"    \
+                       "mfs    %0, rpvr" #pvrid ";"            \
                        : "=r" (tmp) : : "memory");             \
        val = tmp;                                              \
 }
@@ -54,7 +54,7 @@ int cpu_has_pvr(void)
        if (!(flags & PVR_MSR_BIT))
                return 0;
 
-       get_single_pvr(0x00, pvr0);
+       get_single_pvr(0, pvr0);
        pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
 
        if (pvr0 & PVR0_PVR_FULL_MASK)
index 0db20b5..778a5ce 100644 (file)
@@ -62,15 +62,14 @@ real_start:
        andi    r1, r1, ~2
        mts     rmsr, r1
 /*
- * Here is checking mechanism which check if Microblaze has msr instructions
- * We load msr and compare it with previous r1 value - if is the same,
- * msr instructions works if not - cpu don't have them.
+ * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
+ * if the msrclr instruction is not enabled. We use this to detect
+ * if the opcode is available, by issuing msrclr and then testing the result.
+ * r8 == 0 - msr instructions are implemented
+ * r8 != 0 - msr instructions are not implemented
  */
-       /* r8=0 - I have msr instr, 1 - I don't have them */
-       rsubi   r0, r0, 1       /* set the carry bit */
-       msrclr  r0, 0x4         /* try to clear it */
-       /* read the carry bit, r8 will be '0' if msrclr exists */
-       addik   r8, r0, 0
+       msrclr  r8, 0 /* clear nothing - just read msr for test */
+       cmpu    r8, r8, r1 /* r1 must contain msr reg content */
 
 /* r7 may point to an FDT, or there may be one linked in.
    if it's in r7, we've got to save it away ASAP.
index bb1558e..9312fbb 100644 (file)
@@ -161,11 +161,11 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
 #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
        if (msr)
                eprintk("!!!Your kernel has setup MSR instruction but "
-                               "CPU don't have it %d\n", msr);
+                               "CPU don't have it %x\n", msr);
 #else
        if (!msr)
                eprintk("!!!Your kernel not setup MSR instruction but "
-                               "CPU have it %d\n", msr);
+                               "CPU have it %x\n", msr);
 #endif
 
        for (src = __ivt_start; src < __ivt_end; src++, dst++)
index bf3de04..2c79b64 100644 (file)
@@ -148,11 +148,6 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
  */
 extern unsigned long thread_saved_pc(struct task_struct *t);
 
-/*
- * Print register of task into buffer. Used in fs/proc/array.c.
- */
-extern void task_show_regs(struct seq_file *m, struct task_struct *task);
-
 extern void show_code(struct pt_regs *regs);
 
 unsigned long get_wchan(struct task_struct *p);
index 5eb78dd..b5a4a73 100644 (file)
@@ -237,43 +237,6 @@ void show_regs(struct pt_regs *regs)
        show_last_breaking_event(regs);
 }
 
-/* This is called from fs/proc/array.c */
-void task_show_regs(struct seq_file *m, struct task_struct *task)
-{
-       struct pt_regs *regs;
-
-       regs = task_pt_regs(task);
-       seq_printf(m, "task: %p, ksp: %p\n",
-                      task, (void *)task->thread.ksp);
-       seq_printf(m, "User PSW : %p %p\n",
-                      (void *) regs->psw.mask, (void *)regs->psw.addr);
-
-       seq_printf(m, "User GPRS: " FOURLONG,
-                         regs->gprs[0], regs->gprs[1],
-                         regs->gprs[2], regs->gprs[3]);
-       seq_printf(m, "           " FOURLONG,
-                         regs->gprs[4], regs->gprs[5],
-                         regs->gprs[6], regs->gprs[7]);
-       seq_printf(m, "           " FOURLONG,
-                         regs->gprs[8], regs->gprs[9],
-                         regs->gprs[10], regs->gprs[11]);
-       seq_printf(m, "           " FOURLONG,
-                         regs->gprs[12], regs->gprs[13],
-                         regs->gprs[14], regs->gprs[15]);
-       seq_printf(m, "User ACRS: %08x %08x %08x %08x\n",
-                         task->thread.acrs[0], task->thread.acrs[1],
-                         task->thread.acrs[2], task->thread.acrs[3]);
-       seq_printf(m, "           %08x %08x %08x %08x\n",
-                         task->thread.acrs[4], task->thread.acrs[5],
-                         task->thread.acrs[6], task->thread.acrs[7]);
-       seq_printf(m, "           %08x %08x %08x %08x\n",
-                         task->thread.acrs[8], task->thread.acrs[9],
-                         task->thread.acrs[10], task->thread.acrs[11]);
-       seq_printf(m, "           %08x %08x %08x %08x\n",
-                         task->thread.acrs[12], task->thread.acrs[13],
-                         task->thread.acrs[14], task->thread.acrs[15]);
-}
-
 static DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * regs, long err)
index 5e3969c..3c89694 100644 (file)
@@ -233,6 +233,7 @@ extern void sync_Arb_IDs(void);
 extern void init_bsp_APIC(void);
 extern void setup_local_APIC(void);
 extern void end_local_APIC_setup(void);
+extern void bsp_end_local_APIC_setup(void);
 extern void init_apic_mappings(void);
 void register_lapic_address(unsigned long address);
 extern void setup_boot_APIC_clock(void);
index 6e6e755..4564c8e 100644 (file)
@@ -32,6 +32,6 @@ extern void arch_unregister_cpu(int);
 
 DECLARE_PER_CPU(int, cpu_state);
 
-int __cpuinit mwait_usable(const struct cpuinfo_x86 *);
+int mwait_usable(const struct cpuinfo_x86 *);
 
 #endif /* _ASM_X86_CPU_H */
index e2f6a99..cc29086 100644 (file)
@@ -22,6 +22,7 @@
 
 #define ARCH_P4_CNTRVAL_BITS   (40)
 #define ARCH_P4_CNTRVAL_MASK   ((1ULL << ARCH_P4_CNTRVAL_BITS) - 1)
+#define ARCH_P4_UNFLAGGED_BIT  ((1ULL) << (ARCH_P4_CNTRVAL_BITS - 1))
 
 #define P4_ESCR_EVENT_MASK     0x7e000000U
 #define P4_ESCR_EVENT_SHIFT    25
index 1236085..7038b95 100644 (file)
@@ -671,7 +671,7 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n)
 
        atomic_set(&stop_machine_first, 1);
        wrote_text = 0;
-       stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+       __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
 }
 
 #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
index 06c196d..76b96d7 100644 (file)
@@ -1381,12 +1381,17 @@ void __cpuinit end_local_APIC_setup(void)
 #endif
 
        apic_pm_activate();
+}
+
+void __init bsp_end_local_APIC_setup(void)
+{
+       end_local_APIC_setup();
 
        /*
         * Now that local APIC setup is completed for BP, configure the fault
         * handling for interrupt remapping.
         */
-       if (!smp_processor_id() && intr_remapping_enabled)
+       if (intr_remapping_enabled)
                enable_drhd_fault_handling();
 
 }
@@ -1756,7 +1761,7 @@ int __init APIC_init_uniprocessor(void)
                enable_IO_APIC();
 #endif
 
-       end_local_APIC_setup();
+       bsp_end_local_APIC_setup();
 
 #ifdef CONFIG_X86_IO_APIC
        if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
index 697dc34..ca9e2a3 100644 (file)
@@ -4002,6 +4002,9 @@ int mp_find_ioapic(u32 gsi)
 {
        int i = 0;
 
+       if (nr_ioapics == 0)
+               return -1;
+
        /* Find the IOAPIC that manages this GSI. */
        for (i = 0; i < nr_ioapics; i++) {
                if ((gsi >= mp_gsi_routing[i].gsi_base)
index f7a0993..ff751a9 100644 (file)
@@ -770,9 +770,14 @@ static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
                return 1;
        }
 
-       /* it might be unflagged overflow */
-       rdmsrl(hwc->event_base + hwc->idx, v);
-       if (!(v & ARCH_P4_CNTRVAL_MASK))
+       /*
+        * In some circumstances the overflow might issue an NMI but did
+        * not set P4_CCCR_OVF bit. Because a counter holds a negative value
+        * we simply check for high bit being set, if it's cleared it means
+        * the counter has reached zero value and continued counting before
+        * real NMI signal was received:
+        */
+       if (!(v & ARCH_P4_UNFLAGGED_BIT))
                return 1;
 
        return 0;
index 52945da..387b6a0 100644 (file)
@@ -367,7 +367,8 @@ void fixup_irqs(void)
                if (irr  & (1 << (vector % 32))) {
                        irq = __this_cpu_read(vector_irq[vector]);
 
-                       data = irq_get_irq_data(irq);
+                       desc = irq_to_desc(irq);
+                       data = &desc->irq_data;
                        raw_spin_lock(&desc->lock);
                        if (data->chip->irq_retrigger)
                                data->chip->irq_retrigger(data);
index e764fc0..ff45541 100644 (file)
@@ -92,21 +92,31 @@ void show_regs(struct pt_regs *regs)
 
 void show_regs_common(void)
 {
-       const char *board, *product;
+       const char *vendor, *product, *board;
 
-       board = dmi_get_system_info(DMI_BOARD_NAME);
-       if (!board)
-               board = "";
+       vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+       if (!vendor)
+               vendor = "";
        product = dmi_get_system_info(DMI_PRODUCT_NAME);
        if (!product)
                product = "";
 
+       /* Board Name is optional */
+       board = dmi_get_system_info(DMI_BOARD_NAME);
+
        printk(KERN_CONT "\n");
-       printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n",
+       printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s",
                current->pid, current->comm, print_tainted(),
                init_utsname()->release,
                (int)strcspn(init_utsname()->version, " "),
-               init_utsname()->version, board, product);
+               init_utsname()->version);
+       printk(KERN_CONT " ");
+       printk(KERN_CONT "%s %s", vendor, product);
+       if (board) {
+               printk(KERN_CONT "/");
+               printk(KERN_CONT "%s", board);
+       }
+       printk(KERN_CONT "\n");
 }
 
 void flush_thread(void)
@@ -506,7 +516,7 @@ static void poll_idle(void)
 #define MWAIT_ECX_EXTENDED_INFO                0x01
 #define MWAIT_EDX_C1                   0xf0
 
-int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
+int mwait_usable(const struct cpuinfo_x86 *c)
 {
        u32 eax, ebx, ecx, edx;
 
index 03273b6..08776a9 100644 (file)
@@ -1060,7 +1060,7 @@ static int __init smp_sanity_check(unsigned max_cpus)
 
                connect_bsp_APIC();
                setup_local_APIC();
-               end_local_APIC_setup();
+               bsp_end_local_APIC_setup();
                return -1;
        }
 
@@ -1137,7 +1137,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
        if (!skip_ioapic_setup && nr_ioapics)
                enable_IO_APIC();
 
-       end_local_APIC_setup();
+       bsp_end_local_APIC_setup();
 
        map_cpu_to_logical_apicid();
 
index 25bd1bc..54ce246 100644 (file)
@@ -1150,8 +1150,8 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
        kvm_load_ldt(svm->host.ldt);
 #ifdef CONFIG_X86_64
        loadsegment(fs, svm->host.fs);
-       load_gs_index(svm->host.gs);
        wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
+       load_gs_index(svm->host.gs);
 #else
        loadsegment(gs, svm->host.gs);
 #endif
index 381b09b..a89043a 100644 (file)
@@ -168,7 +168,15 @@ static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td,
         * tree of blkg (instead of traversing through hash list all
         * the time.
         */
-       tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key));
+
+       /*
+        * This is the common case when there are no blkio cgroups.
+        * Avoid lookup in this case
+        */
+       if (blkcg == &blkio_root_cgroup)
+               tg = &td->root_tg;
+       else
+               tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key));
 
        /* Fill in device details for root group */
        if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
index 501ffdf..7be4c79 100644 (file)
@@ -599,7 +599,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg)
 }
 
 static inline unsigned
-cfq_scaled_group_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+cfq_scaled_cfqq_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
        unsigned slice = cfq_prio_to_slice(cfqd, cfqq);
        if (cfqd->cfq_latency) {
@@ -631,7 +631,7 @@ cfq_scaled_group_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 static inline void
 cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
-       unsigned slice = cfq_scaled_group_slice(cfqd, cfqq);
+       unsigned slice = cfq_scaled_cfqq_slice(cfqd, cfqq);
 
        cfqq->slice_start = jiffies;
        cfqq->slice_end = jiffies + slice;
@@ -1671,7 +1671,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
         */
        if (timed_out) {
                if (cfq_cfqq_slice_new(cfqq))
-                       cfqq->slice_resid = cfq_scaled_group_slice(cfqd, cfqq);
+                       cfqq->slice_resid = cfq_scaled_cfqq_slice(cfqd, cfqq);
                else
                        cfqq->slice_resid = cfqq->slice_end - jiffies;
                cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid);
@@ -3432,6 +3432,10 @@ static bool cfq_should_wait_busy(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
        struct cfq_io_context *cic = cfqd->active_cic;
 
+       /* If the queue already has requests, don't wait */
+       if (!RB_EMPTY_ROOT(&cfqq->sort_list))
+               return false;
+
        /* If there are other queues in the group, don't wait */
        if (cfqq->cfqg->nr_cfqq > 1)
                return false;
index e9562a7..3b20a34 100644 (file)
@@ -212,37 +212,40 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
-       /* Validate wake_device is of type Device */
-
-       device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
-       if (device_node->type != ACPI_TYPE_DEVICE) {
-               return_ACPI_STATUS(AE_BAD_PARAMETER);
-       }
-
        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
        /* Ensure that we have a valid GPE number */
 
        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
-       if (gpe_event_info) {
-               /*
-                * If there is no method or handler for this GPE, then the
-                * wake_device will be notified whenever this GPE fires (aka
-                * "implicit notify") Note: The GPE is assumed to be
-                * level-triggered (for windows compatibility).
-                */
-               if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
-                   ACPI_GPE_DISPATCH_NONE) {
-                       gpe_event_info->flags =
-                           (ACPI_GPE_DISPATCH_NOTIFY |
-                            ACPI_GPE_LEVEL_TRIGGERED);
-                       gpe_event_info->dispatch.device_node = device_node;
-               }
+       if (!gpe_event_info) {
+               goto unlock_and_exit;
+       }
+
+       /*
+        * If there is no method or handler for this GPE, then the
+        * wake_device will be notified whenever this GPE fires (aka
+        * "implicit notify") Note: The GPE is assumed to be
+        * level-triggered (for windows compatibility).
+        */
+       if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+             ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) {
 
-               gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
-               status = AE_OK;
+               /* Validate wake_device is of type Device */
+
+               device_node = ACPI_CAST_PTR(struct acpi_namespace_node,
+                                           wake_device);
+               if (device_node->type != ACPI_TYPE_DEVICE) {
+                       goto unlock_and_exit;
+               }
+               gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
+                                        ACPI_GPE_LEVEL_TRIGGERED);
+               gpe_event_info->dispatch.device_node = device_node;
        }
 
+       gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
+       status = AE_OK;
+
+ unlock_and_exit:
        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
        return_ACPI_STATUS(status);
 }
index b093181..c90c76a 100644 (file)
@@ -636,17 +636,21 @@ EXPORT_SYMBOL(acpi_os_write_port);
 acpi_status
 acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
 {
-       u32 dummy;
        void __iomem *virt_addr;
-       int size = width / 8, unmap = 0;
+       unsigned int size = width / 8;
+       bool unmap = false;
+       u32 dummy;
 
        rcu_read_lock();
        virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
-       rcu_read_unlock();
        if (!virt_addr) {
+               rcu_read_unlock();
                virt_addr = acpi_os_ioremap(phys_addr, size);
-               unmap = 1;
+               if (!virt_addr)
+                       return AE_BAD_ADDRESS;
+               unmap = true;
        }
+
        if (!value)
                value = &dummy;
 
@@ -666,6 +670,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
 
        if (unmap)
                iounmap(virt_addr);
+       else
+               rcu_read_unlock();
 
        return AE_OK;
 }
@@ -674,14 +680,17 @@ acpi_status
 acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
 {
        void __iomem *virt_addr;
-       int size = width / 8, unmap = 0;
+       unsigned int size = width / 8;
+       bool unmap = false;
 
        rcu_read_lock();
        virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
-       rcu_read_unlock();
        if (!virt_addr) {
+               rcu_read_unlock();
                virt_addr = acpi_os_ioremap(phys_addr, size);
-               unmap = 1;
+               if (!virt_addr)
+                       return AE_BAD_ADDRESS;
+               unmap = true;
        }
 
        switch (width) {
@@ -700,6 +709,8 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
 
        if (unmap)
                iounmap(virt_addr);
+       else
+               rcu_read_unlock();
 
        return AE_OK;
 }
index 42d3d72..5af3479 100644 (file)
@@ -82,6 +82,11 @@ long acpi_is_video_device(struct acpi_device *device)
        if (!device)
                return 0;
 
+       /* Is this device able to support video switching ? */
+       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) ||
+           ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
+               video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
+
        /* Is this device able to retrieve a video ROM ? */
        if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
                video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
index ed65014..7bfbe40 100644 (file)
@@ -86,8 +86,12 @@ int __init acpi_wakeup_device_init(void)
                struct acpi_device *dev = container_of(node,
                                                       struct acpi_device,
                                                       wakeup_list);
-               if (device_can_wakeup(&dev->dev))
+               if (device_can_wakeup(&dev->dev)) {
+                       /* Button GPEs are supposed to be always enabled. */
+                       acpi_enable_gpe(dev->wakeup.gpe_device,
+                                       dev->wakeup.gpe_number);
                        device_set_wakeup_enable(&dev->dev, true);
+               }
        }
        mutex_unlock(&acpi_device_lock);
        return 0;
index d7f463d..40528ba 100644 (file)
@@ -39,4 +39,4 @@ obj-$(CONFIG_XEN_BLKDEV_FRONTEND)     += xen-blkfront.o
 obj-$(CONFIG_BLK_DEV_DRBD)     += drbd/
 obj-$(CONFIG_BLK_DEV_RBD)     += rbd.o
 
-swim_mod-objs  := swim.o swim_asm.o
+swim_mod-y     := swim.o swim_asm.o
index e76d997..06ea82c 100644 (file)
@@ -3,4 +3,4 @@
 #
 
 obj-$(CONFIG_ATA_OVER_ETH)     += aoe.o
-aoe-objs := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o
+aoe-y := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o
index 516d5bb..9279272 100644 (file)
@@ -2833,7 +2833,7 @@ static int cciss_revalidate(struct gendisk *disk)
        sector_t total_size;
        InquiryData_struct *inq_buff = NULL;
 
-       for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
+       for (logvol = 0; logvol <= h->highest_lun; logvol++) {
                if (!h->drv[logvol])
                        continue;
                if (memcmp(h->drv[logvol]->LunID, drv->LunID,
index 44e18c0..49e6a54 100644 (file)
@@ -1641,6 +1641,9 @@ out:
 
 static void loop_free(struct loop_device *lo)
 {
+       if (!lo->lo_queue->queue_lock)
+               lo->lo_queue->queue_lock = &lo->lo_queue->__queue_lock;
+
        blk_cleanup_queue(lo->lo_queue);
        put_disk(lo->lo_disk);
        list_del(&lo->lo_list);
index a32fb41..e6fc716 100644 (file)
@@ -53,7 +53,6 @@
 #define DBG_BLKDEV      0x0100
 #define DBG_RX          0x0200
 #define DBG_TX          0x0400
-static DEFINE_MUTEX(nbd_mutex);
 static unsigned int debugflags;
 #endif /* NDEBUG */
 
@@ -718,11 +717,9 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
        dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
                        lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
 
-       mutex_lock(&nbd_mutex);
        mutex_lock(&lo->tx_lock);
        error = __nbd_ioctl(bdev, lo, cmd, arg);
        mutex_unlock(&lo->tx_lock);
-       mutex_unlock(&nbd_mutex);
 
        return error;
 }
index 14033a3..e2c48a7 100644 (file)
@@ -409,7 +409,8 @@ int register_cdrom(struct cdrom_device_info *cdi)
        }
 
        ENSURE(drive_status, CDC_DRIVE_STATUS );
-       ENSURE(media_changed, CDC_MEDIA_CHANGED);
+       if (cdo->check_events == NULL && cdo->media_changed == NULL)
+               *change_capability = ~(CDC_MEDIA_CHANGED | CDC_SELECT_DISC);
        ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
        ENSURE(lock_door, CDC_LOCK);
        ENSURE(select_speed, CDC_SELECT_SPEED);
index 5bc765d..8238f89 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_SYNCLINK_GT)     += synclink_gt.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
 obj-$(CONFIG_SX)               += sx.o generic_serial.o
 obj-$(CONFIG_RIO)              += rio/ generic_serial.o
+obj-$(CONFIG_VIRTIO_CONSOLE)   += virtio_console.o
 obj-$(CONFIG_RAW_DRIVER)       += raw.o
 obj-$(CONFIG_SGI_SNSC)         += snsc.o snsc_event.o
 obj-$(CONFIG_MSPEC)            += mspec.o
index b6ae6e9..7855f9f 100644 (file)
@@ -320,6 +320,7 @@ static int unload_when_empty = 1;
 static int add_smi(struct smi_info *smi);
 static int try_smi_init(struct smi_info *smi);
 static void cleanup_one_si(struct smi_info *to_clean);
+static void cleanup_ipmi_si(void);
 
 static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
 static int register_xaction_notifier(struct notifier_block *nb)
@@ -3450,16 +3451,7 @@ static int __devinit init_ipmi_si(void)
        mutex_lock(&smi_infos_lock);
        if (unload_when_empty && list_empty(&smi_infos)) {
                mutex_unlock(&smi_infos_lock);
-#ifdef CONFIG_PCI
-               if (pci_registered)
-                       pci_unregister_driver(&ipmi_pci_driver);
-#endif
-
-#ifdef CONFIG_PPC_OF
-               if (of_registered)
-                       of_unregister_platform_driver(&ipmi_of_platform_driver);
-#endif
-               driver_unregister(&ipmi_driver.driver);
+               cleanup_ipmi_si();
                printk(KERN_WARNING PFX
                       "Unable to find any System Interface(s)\n");
                return -ENODEV;
index 36e0fa1..faf5a2c 100644 (file)
@@ -577,9 +577,11 @@ duration:
        if (rc)
                return;
 
-       if (be32_to_cpu(tpm_cmd.header.out.return_code)
-           != 3 * sizeof(u32))
+       if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 ||
+           be32_to_cpu(tpm_cmd.header.out.length)
+           != sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32))
                return;
+
        duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
        chip->vendor.duration[TPM_SHORT] =
            usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
@@ -939,6 +941,18 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
 
+ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d %d %d\n",
+                      jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
+                      jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
+                      jiffies_to_usecs(chip->vendor.duration[TPM_LONG]));
+}
+EXPORT_SYMBOL_GPL(tpm_show_timeouts);
+
 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
index 72ddb03..d84ff77 100644 (file)
@@ -56,6 +56,8 @@ extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
                                char *);
 extern ssize_t tpm_show_temp_deactivated(struct device *,
                                         struct device_attribute *attr, char *);
+extern ssize_t tpm_show_timeouts(struct device *,
+                                struct device_attribute *attr, char *);
 
 struct tpm_chip;
 
index dd21df5..0d1d38e 100644 (file)
@@ -376,6 +376,7 @@ static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
                   NULL);
 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
 static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
 
 static struct attribute *tis_attrs[] = {
        &dev_attr_pubek.attr,
@@ -385,7 +386,8 @@ static struct attribute *tis_attrs[] = {
        &dev_attr_owned.attr,
        &dev_attr_temp_deactivated.attr,
        &dev_attr_caps.attr,
-       &dev_attr_cancel.attr, NULL,
+       &dev_attr_cancel.attr,
+       &dev_attr_timeouts.attr, NULL,
 };
 
 static struct attribute_group tis_attr_grp = {
similarity index 99%
rename from drivers/tty/hvc/virtio_console.c
rename to drivers/char/virtio_console.c
index 896a2ce..4903931 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006, 2007, 2009 Rusty Russell, IBM Corporation
- * Copyright (C) 2009, 2010 Red Hat, Inc.
+ * Copyright (C) 2009, 2010, 2011 Red Hat, Inc.
+ * Copyright (C) 2009, 2010, 2011 Amit Shah <amit.shah@redhat.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +32,7 @@
 #include <linux/virtio_console.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
-#include "hvc_console.h"
+#include "../tty/hvc/hvc_console.h"
 
 /*
  * This is a global struct for storing common data for all the devices
@@ -1462,6 +1463,17 @@ static void control_work_handler(struct work_struct *work)
        spin_unlock(&portdev->cvq_lock);
 }
 
+static void out_intr(struct virtqueue *vq)
+{
+       struct port *port;
+
+       port = find_port_by_vq(vq->vdev->priv, vq);
+       if (!port)
+               return;
+
+       wake_up_interruptible(&port->waitqueue);
+}
+
 static void in_intr(struct virtqueue *vq)
 {
        struct port *port;
@@ -1566,7 +1578,7 @@ static int init_vqs(struct ports_device *portdev)
         */
        j = 0;
        io_callbacks[j] = in_intr;
-       io_callbacks[j + 1] = NULL;
+       io_callbacks[j + 1] = out_intr;
        io_names[j] = "input";
        io_names[j + 1] = "output";
        j += 2;
@@ -1580,7 +1592,7 @@ static int init_vqs(struct ports_device *portdev)
                for (i = 1; i < nr_ports; i++) {
                        j += 2;
                        io_callbacks[j] = in_intr;
-                       io_callbacks[j + 1] = NULL;
+                       io_callbacks[j + 1] = out_intr;
                        io_names[j] = "input";
                        io_names[j + 1] = "output";
                }
index 297f48b..07bca49 100644 (file)
@@ -79,6 +79,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <linux/dmapool.h>
 #include <linux/dmaengine.h>
 #include <linux/amba/bus.h>
@@ -235,16 +236,19 @@ static void pl08x_start_txd(struct pl08x_dma_chan *plchan,
 }
 
 /*
- * Overall DMAC remains enabled always.
+ * Pause the channel by setting the HALT bit.
  *
- * Disabling individual channels could lose data.
+ * For M->P transfers, pause the DMAC first and then stop the peripheral -
+ * the FIFO can only drain if the peripheral is still requesting data.
+ * (note: this can still timeout if the DMAC FIFO never drains of data.)
  *
- * Disable the peripheral DMA after disabling the DMAC in order to allow
- * the DMAC FIFO to drain, and hence allow the channel to show inactive
+ * For P->M transfers, disable the peripheral first to stop it filling
+ * the DMAC FIFO, and then pause the DMAC.
  */
 static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch)
 {
        u32 val;
+       int timeout;
 
        /* Set the HALT bit and wait for the FIFO to drain */
        val = readl(ch->base + PL080_CH_CONFIG);
@@ -252,8 +256,13 @@ static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch)
        writel(val, ch->base + PL080_CH_CONFIG);
 
        /* Wait for channel inactive */
-       while (pl08x_phy_channel_busy(ch))
-               cpu_relax();
+       for (timeout = 1000; timeout; timeout--) {
+               if (!pl08x_phy_channel_busy(ch))
+                       break;
+               udelay(1);
+       }
+       if (pl08x_phy_channel_busy(ch))
+               pr_err("pl08x: channel%u timeout waiting for pause\n", ch->id);
 }
 
 static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch)
@@ -267,19 +276,24 @@ static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch)
 }
 
 
-/* Stops the channel */
-static void pl08x_stop_phy_chan(struct pl08x_phy_chan *ch)
+/*
+ * pl08x_terminate_phy_chan() stops the channel, clears the FIFO and
+ * clears any pending interrupt status.  This should not be used for
+ * an on-going transfer, but as a method of shutting down a channel
+ * (eg, when it's no longer used) or terminating a transfer.
+ */
+static void pl08x_terminate_phy_chan(struct pl08x_driver_data *pl08x,
+       struct pl08x_phy_chan *ch)
 {
-       u32 val;
+       u32 val = readl(ch->base + PL080_CH_CONFIG);
 
-       pl08x_pause_phy_chan(ch);
+       val &= ~(PL080_CONFIG_ENABLE | PL080_CONFIG_ERR_IRQ_MASK |
+                PL080_CONFIG_TC_IRQ_MASK);
 
-       /* Disable channel */
-       val = readl(ch->base + PL080_CH_CONFIG);
-       val &= ~PL080_CONFIG_ENABLE;
-       val &= ~PL080_CONFIG_ERR_IRQ_MASK;
-       val &= ~PL080_CONFIG_TC_IRQ_MASK;
        writel(val, ch->base + PL080_CH_CONFIG);
+
+       writel(1 << ch->id, pl08x->base + PL080_ERR_CLEAR);
+       writel(1 << ch->id, pl08x->base + PL080_TC_CLEAR);
 }
 
 static inline u32 get_bytes_in_cctl(u32 cctl)
@@ -404,13 +418,12 @@ static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x,
 {
        unsigned long flags;
 
+       spin_lock_irqsave(&ch->lock, flags);
+
        /* Stop the channel and clear its interrupts */
-       pl08x_stop_phy_chan(ch);
-       writel((1 << ch->id), pl08x->base + PL080_ERR_CLEAR);
-       writel((1 << ch->id), pl08x->base + PL080_TC_CLEAR);
+       pl08x_terminate_phy_chan(pl08x, ch);
 
        /* Mark it as free */
-       spin_lock_irqsave(&ch->lock, flags);
        ch->serving = NULL;
        spin_unlock_irqrestore(&ch->lock, flags);
 }
@@ -1449,7 +1462,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
                plchan->state = PL08X_CHAN_IDLE;
 
                if (plchan->phychan) {
-                       pl08x_stop_phy_chan(plchan->phychan);
+                       pl08x_terminate_phy_chan(pl08x, plchan->phychan);
 
                        /*
                         * Mark physical channel as free and free any slave
index e53d438..e18eaab 100644 (file)
@@ -49,6 +49,7 @@ struct imxdma_channel {
 
 struct imxdma_engine {
        struct device                   *dev;
+       struct device_dma_parameters    dma_parms;
        struct dma_device               dma_device;
        struct imxdma_channel           channel[MAX_DMA_CHANNELS];
 };
@@ -242,6 +243,21 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg(
        else
                dmamode = DMA_MODE_WRITE;
 
+       switch (imxdmac->word_size) {
+       case DMA_SLAVE_BUSWIDTH_4_BYTES:
+               if (sgl->length & 3 || sgl->dma_address & 3)
+                       return NULL;
+               break;
+       case DMA_SLAVE_BUSWIDTH_2_BYTES:
+               if (sgl->length & 1 || sgl->dma_address & 1)
+                       return NULL;
+               break;
+       case DMA_SLAVE_BUSWIDTH_1_BYTE:
+               break;
+       default:
+               return NULL;
+       }
+
        ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len,
                 dma_length, imxdmac->per_address, dmamode);
        if (ret)
@@ -329,6 +345,9 @@ static int __init imxdma_probe(struct platform_device *pdev)
 
        INIT_LIST_HEAD(&imxdma->dma_device.channels);
 
+       dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask);
+       dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask);
+
        /* Initialize channel parameters */
        for (i = 0; i < MAX_DMA_CHANNELS; i++) {
                struct imxdma_channel *imxdmac = &imxdma->channel[i];
@@ -346,11 +365,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
                imxdmac->imxdma = imxdma;
                spin_lock_init(&imxdmac->lock);
 
-               dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask);
-               dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask);
-
                imxdmac->chan.device = &imxdma->dma_device;
-               imxdmac->chan.chan_id = i;
                imxdmac->channel = i;
 
                /* Add the channel to the DMAC list */
@@ -370,6 +385,9 @@ static int __init imxdma_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, imxdma);
 
+       imxdma->dma_device.dev->dma_parms = &imxdma->dma_parms;
+       dma_set_max_seg_size(imxdma->dma_device.dev, 0xffffff);
+
        ret = dma_async_device_register(&imxdma->dma_device);
        if (ret) {
                dev_err(&pdev->dev, "unable to register\n");
index d5a5d4d..b6d1455 100644 (file)
@@ -230,7 +230,7 @@ struct sdma_engine;
  * struct sdma_channel - housekeeping for a SDMA channel
  *
  * @sdma               pointer to the SDMA engine for this channel
- * @channel            the channel number, matches dmaengine chan_id
+ * @channel            the channel number, matches dmaengine chan_id + 1
  * @direction          transfer type. Needed for setting SDMA script
  * @peripheral_type    Peripheral type. Needed for setting SDMA script
  * @event_id0          aka dma request line
@@ -301,6 +301,7 @@ struct sdma_firmware_header {
 
 struct sdma_engine {
        struct device                   *dev;
+       struct device_dma_parameters    dma_parms;
        struct sdma_channel             channel[MAX_DMA_CHANNELS];
        struct sdma_channel_control     *channel_control;
        void __iomem                    *regs;
@@ -449,7 +450,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
                if (bd->mode.status & BD_RROR)
                        sdmac->status = DMA_ERROR;
                else
-                       sdmac->status = DMA_SUCCESS;
+                       sdmac->status = DMA_IN_PROGRESS;
 
                bd->mode.status |= BD_DONE;
                sdmac->buf_tail++;
@@ -770,15 +771,15 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
        __raw_writel(1 << channel, sdma->regs + SDMA_H_START);
 }
 
-static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdma)
+static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac)
 {
-       dma_cookie_t cookie = sdma->chan.cookie;
+       dma_cookie_t cookie = sdmac->chan.cookie;
 
        if (++cookie < 0)
                cookie = 1;
 
-       sdma->chan.cookie = cookie;
-       sdma->desc.cookie = cookie;
+       sdmac->chan.cookie = cookie;
+       sdmac->desc.cookie = cookie;
 
        return cookie;
 }
@@ -798,7 +799,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
 
        cookie = sdma_assign_cookie(sdmac);
 
-       sdma_enable_channel(sdma, tx->chan->chan_id);
+       sdma_enable_channel(sdma, sdmac->channel);
 
        spin_unlock_irq(&sdmac->lock);
 
@@ -811,10 +812,6 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
        struct imx_dma_data *data = chan->private;
        int prio, ret;
 
-       /* No need to execute this for internal channel 0 */
-       if (chan->chan_id == 0)
-               return 0;
-
        if (!data)
                return -EINVAL;
 
@@ -879,7 +876,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
        struct sdma_channel *sdmac = to_sdma_chan(chan);
        struct sdma_engine *sdma = sdmac->sdma;
        int ret, i, count;
-       int channel = chan->chan_id;
+       int channel = sdmac->channel;
        struct scatterlist *sg;
 
        if (sdmac->status == DMA_IN_PROGRESS)
@@ -924,22 +921,33 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
                        ret =  -EINVAL;
                        goto err_out;
                }
-               if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES)
+
+               switch (sdmac->word_size) {
+               case DMA_SLAVE_BUSWIDTH_4_BYTES:
                        bd->mode.command = 0;
-               else
-                       bd->mode.command = sdmac->word_size;
+                       if (count & 3 || sg->dma_address & 3)
+                               return NULL;
+                       break;
+               case DMA_SLAVE_BUSWIDTH_2_BYTES:
+                       bd->mode.command = 2;
+                       if (count & 1 || sg->dma_address & 1)
+                               return NULL;
+                       break;
+               case DMA_SLAVE_BUSWIDTH_1_BYTE:
+                       bd->mode.command = 1;
+                       break;
+               default:
+                       return NULL;
+               }
 
                param = BD_DONE | BD_EXTD | BD_CONT;
 
-               if (sdmac->flags & IMX_DMA_SG_LOOP) {
+               if (i + 1 == sg_len) {
                        param |= BD_INTR;
-                       if (i + 1 == sg_len)
-                               param |= BD_WRAP;
+                       param |= BD_LAST;
+                       param &= ~BD_CONT;
                }
 
-               if (i + 1 == sg_len)
-                       param |= BD_INTR;
-
                dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%08x %s%s\n",
                                i, count, sg->dma_address,
                                param & BD_WRAP ? "wrap" : "",
@@ -953,6 +961,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
 
        return &sdmac->desc;
 err_out:
+       sdmac->status = DMA_ERROR;
        return NULL;
 }
 
@@ -963,7 +972,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
        struct sdma_channel *sdmac = to_sdma_chan(chan);
        struct sdma_engine *sdma = sdmac->sdma;
        int num_periods = buf_len / period_len;
-       int channel = chan->chan_id;
+       int channel = sdmac->channel;
        int ret, i = 0, buf = 0;
 
        dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
@@ -1066,14 +1075,12 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
 {
        struct sdma_channel *sdmac = to_sdma_chan(chan);
        dma_cookie_t last_used;
-       enum dma_status ret;
 
        last_used = chan->cookie;
 
-       ret = dma_async_is_complete(cookie, sdmac->last_completed, last_used);
        dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0);
 
-       return ret;
+       return sdmac->status;
 }
 
 static void sdma_issue_pending(struct dma_chan *chan)
@@ -1135,7 +1142,7 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
        /* download the RAM image for SDMA */
        sdma_load_script(sdma, ram_code,
                        header->ram_code_size,
-                       sdma->script_addrs->ram_code_start_addr);
+                       addr->ram_code_start_addr);
        clk_disable(sdma->clk);
 
        sdma_add_scripts(sdma, addr);
@@ -1237,7 +1244,6 @@ static int __init sdma_probe(struct platform_device *pdev)
        struct resource *iores;
        struct sdma_platform_data *pdata = pdev->dev.platform_data;
        int i;
-       dma_cap_mask_t mask;
        struct sdma_engine *sdma;
 
        sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
@@ -1280,6 +1286,9 @@ static int __init sdma_probe(struct platform_device *pdev)
 
        sdma->version = pdata->sdma_version;
 
+       dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
+       dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
+
        INIT_LIST_HEAD(&sdma->dma_device.channels);
        /* Initialize channel parameters */
        for (i = 0; i < MAX_DMA_CHANNELS; i++) {
@@ -1288,15 +1297,17 @@ static int __init sdma_probe(struct platform_device *pdev)
                sdmac->sdma = sdma;
                spin_lock_init(&sdmac->lock);
 
-               dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
-               dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
-
                sdmac->chan.device = &sdma->dma_device;
-               sdmac->chan.chan_id = i;
                sdmac->channel = i;
 
-               /* Add the channel to the DMAC list */
-               list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels);
+               /*
+                * Add the channel to the DMAC list. Do not add channel 0 though
+                * because we need it internally in the SDMA driver. This also means
+                * that channel 0 in dmaengine counting matches sdma channel 1.
+                */
+               if (i)
+                       list_add_tail(&sdmac->chan.device_node,
+                                       &sdma->dma_device.channels);
        }
 
        ret = sdma_init(sdma);
@@ -1317,6 +1328,8 @@ static int __init sdma_probe(struct platform_device *pdev)
        sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic;
        sdma->dma_device.device_control = sdma_control;
        sdma->dma_device.device_issue_pending = sdma_issue_pending;
+       sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
+       dma_set_max_seg_size(sdma->dma_device.dev, 65535);
 
        ret = dma_async_device_register(&sdma->dma_device);
        if (ret) {
@@ -1324,13 +1337,6 @@ static int __init sdma_probe(struct platform_device *pdev)
                goto err_init;
        }
 
-       /* request channel 0. This is an internal control channel
-        * to the SDMA engine and not available to clients.
-        */
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       dma_request_channel(mask, NULL, NULL);
-
        dev_info(sdma->dev, "initialized\n");
 
        return 0;
@@ -1348,7 +1354,7 @@ err_clk:
 err_request_region:
 err_irq:
        kfree(sdma);
-       return 0;
+       return ret;
 }
 
 static int __exit sdma_remove(struct platform_device *pdev)
index cb26ee9..c1a125e 100644 (file)
@@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
        reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
        idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN);
 
-       /*
-        * Problem (observed with channel DMAIC_7): after enabling the channel
-        * and initialising buffers, there comes an interrupt with current still
-        * pointing at buffer 0, whereas it should use buffer 0 first and only
-        * generate an interrupt when it is done, then current should already
-        * point to buffer 1. This spurious interrupt also comes on channel
-        * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the
-        * first interrupt, there comes the second with current correctly
-        * pointing to buffer 1 this time. But sometimes this second interrupt
-        * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling
-        * the channel seems to prevent the channel from hanging, but it doesn't
-        * prevent the spurious interrupt. This might also be unsafe. Think
-        * about the IDMAC controller trying to switch to a buffer, when we
-        * clear the ready bit, and re-enable it a moment later.
-        */
-       reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY);
-       idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY);
-       idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY);
-
-       reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY);
-       idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY);
-       idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY);
-
        spin_unlock_irqrestore(&ipu->lock, flags);
 
        return 0;
@@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 
        /* Other interrupts do not interfere with this channel */
        spin_lock(&ichan->lock);
-       if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
-                    ((curbuf >> chan_id) & 1) == ichan->active_buffer &&
-                    !list_is_last(ichan->queue.next, &ichan->queue))) {
-               int i = 100;
-
-               /* This doesn't help. See comment in ipu_disable_channel() */
-               while (--i) {
-                       curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
-                       if (((curbuf >> chan_id) & 1) != ichan->active_buffer)
-                               break;
-                       cpu_relax();
-               }
-
-               if (!i) {
-                       spin_unlock(&ichan->lock);
-                       dev_dbg(dev,
-                               "IRQ on active buffer on channel %x, active "
-                               "%d, ready %x, %x, current %x!\n", chan_id,
-                               ichan->active_buffer, ready0, ready1, curbuf);
-                       return IRQ_NONE;
-               } else
-                       dev_dbg(dev,
-                               "Buffer deactivated on channel %x, active "
-                               "%d, ready %x, %x, current %x, rest %d!\n", chan_id,
-                               ichan->active_buffer, ready0, ready1, curbuf, i);
-       }
-
        if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
                     (!ichan->active_buffer && (ready0 >> chan_id) & 1)
                     )) {
index 4a5ecc5..23e0355 100644 (file)
@@ -826,8 +826,6 @@ static void amd64_dump_dramcfg_low(u32 dclr, int chan)
 /* Display and decode various NB registers for debug purposes. */
 static void amd64_dump_misc_regs(struct amd64_pvt *pvt)
 {
-       int ganged;
-
        debugf1("F3xE8 (NB Cap): 0x%08x\n", pvt->nbcap);
 
        debugf1("  NB two channel DRAM capable: %s\n",
@@ -851,28 +849,19 @@ static void amd64_dump_misc_regs(struct amd64_pvt *pvt)
        debugf1("  DramHoleValid: %s\n",
                (pvt->dhar & DHAR_VALID) ? "yes" : "no");
 
+       amd64_debug_display_dimm_sizes(0, pvt);
+
        /* everything below this point is Fam10h and above */
-       if (boot_cpu_data.x86 == 0xf) {
-               amd64_debug_display_dimm_sizes(0, pvt);
+       if (boot_cpu_data.x86 == 0xf)
                return;
-       }
+
+       amd64_debug_display_dimm_sizes(1, pvt);
 
        amd64_info("using %s syndromes.\n", ((pvt->syn_type == 8) ? "x8" : "x4"));
 
        /* Only if NOT ganged does dclr1 have valid info */
        if (!dct_ganging_enabled(pvt))
                amd64_dump_dramcfg_low(pvt->dclr1, 1);
-
-       /*
-        * Determine if ganged and then dump memory sizes for first controller,
-        * and if NOT ganged dump info for 2nd controller.
-        */
-       ganged = dct_ganging_enabled(pvt);
-
-       amd64_debug_display_dimm_sizes(0, pvt);
-
-       if (!ganged)
-               amd64_debug_display_dimm_sizes(1, pvt);
 }
 
 /* Read in both of DBAM registers */
@@ -1644,11 +1633,10 @@ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt)
                       WARN_ON(ctrl != 0);
        }
 
-       debugf1("F2x%d80 (DRAM Bank Address Mapping): 0x%08x\n",
-               ctrl, ctrl ? pvt->dbam1 : pvt->dbam0);
+       dbam = (ctrl && !dct_ganging_enabled(pvt)) ? pvt->dbam1 : pvt->dbam0;
+       dcsb = (ctrl && !dct_ganging_enabled(pvt)) ? pvt->dcsb1 : pvt->dcsb0;
 
-       dbam = ctrl ? pvt->dbam1 : pvt->dbam0;
-       dcsb = ctrl ? pvt->dcsb1 : pvt->dcsb0;
+       debugf1("F2x%d80 (DRAM Bank Address Mapping): 0x%08x\n", ctrl, dbam);
 
        edac_printk(KERN_DEBUG, EDAC_MC, "DCT%d chip selects:\n", ctrl);
 
index e28e416..bcb1126 100644 (file)
@@ -378,10 +378,17 @@ static void __init print_filtered(const char *info)
 
 static void __init dmi_dump_ids(void)
 {
+       const char *board;      /* Board Name is optional */
+
        printk(KERN_DEBUG "DMI: ");
-       print_filtered(dmi_get_system_info(DMI_BOARD_NAME));
-       printk(KERN_CONT "/");
+       print_filtered(dmi_get_system_info(DMI_SYS_VENDOR));
+       printk(KERN_CONT " ");
        print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME));
+       board = dmi_get_system_info(DMI_BOARD_NAME);
+       if (board) {
+               printk(KERN_CONT "/");
+               print_filtered(board);
+       }
        printk(KERN_CONT ", BIOS ");
        print_filtered(dmi_get_system_info(DMI_BIOS_VERSION));
        printk(KERN_CONT " ");
index a261972..b473429 100644 (file)
@@ -60,6 +60,7 @@ struct pca953x_chip {
        unsigned gpio_start;
        uint16_t reg_output;
        uint16_t reg_direction;
+       struct mutex i2c_lock;
 
 #ifdef CONFIG_GPIO_PCA953X_IRQ
        struct mutex irq_lock;
@@ -119,13 +120,17 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        reg_val = chip->reg_direction | (1u << off);
        ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
        if (ret)
-               return ret;
+               goto exit;
 
        chip->reg_direction = reg_val;
-       return 0;
+       ret = 0;
+exit:
+       mutex_unlock(&chip->i2c_lock);
+       return ret;
 }
 
 static int pca953x_gpio_direction_output(struct gpio_chip *gc,
@@ -137,6 +142,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        /* set output level */
        if (val)
                reg_val = chip->reg_output | (1u << off);
@@ -145,7 +151,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
 
        ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
        if (ret)
-               return ret;
+               goto exit;
 
        chip->reg_output = reg_val;
 
@@ -153,10 +159,13 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
        reg_val = chip->reg_direction & ~(1u << off);
        ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
        if (ret)
-               return ret;
+               goto exit;
 
        chip->reg_direction = reg_val;
-       return 0;
+       ret = 0;
+exit:
+       mutex_unlock(&chip->i2c_lock);
+       return ret;
 }
 
 static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
@@ -167,7 +176,9 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
+       mutex_unlock(&chip->i2c_lock);
        if (ret < 0) {
                /* NOTE:  diagnostic already emitted; that's all we should
                 * do unless gpio_*_value_cansleep() calls become different
@@ -187,6 +198,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
 
        chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
+       mutex_lock(&chip->i2c_lock);
        if (val)
                reg_val = chip->reg_output | (1u << off);
        else
@@ -194,9 +206,11 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
 
        ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
        if (ret)
-               return;
+               goto exit;
 
        chip->reg_output = reg_val;
+exit:
+       mutex_unlock(&chip->i2c_lock);
 }
 
 static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
@@ -517,6 +531,8 @@ static int __devinit pca953x_probe(struct i2c_client *client,
 
        chip->names = pdata->names;
 
+       mutex_init(&chip->i2c_lock);
+
        /* initialize cached registers from their original values.
         * we can't share this chip with another i2c master.
         */
index 3cdbaf3..be9a9c0 100644 (file)
@@ -283,17 +283,18 @@ int drm_vma_info(struct seq_file *m, void *data)
 #endif
 
        mutex_lock(&dev->struct_mutex);
-       seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08llx\n",
+       seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n",
                   atomic_read(&dev->vma_count),
-                  high_memory, (u64)virt_to_phys(high_memory));
+                  high_memory, (void *)virt_to_phys(high_memory));
 
        list_for_each_entry(pt, &dev->vmalist, head) {
                vma = pt->vma;
                if (!vma)
                        continue;
                seq_printf(m,
-                          "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
-                          pt->pid, vma->vm_start, vma->vm_end,
+                          "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000",
+                          pt->pid,
+                          (void *)vma->vm_start, (void *)vma->vm_end,
                           vma->vm_flags & VM_READ ? 'r' : '-',
                           vma->vm_flags & VM_WRITE ? 'w' : '-',
                           vma->vm_flags & VM_EXEC ? 'x' : '-',
index cfb56d0..0ad533f 100644 (file)
@@ -46,6 +46,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
 unsigned int i915_powersave = 1;
 module_param_named(powersave, i915_powersave, int, 0600);
 
+unsigned int i915_enable_rc6 = 0;
+module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
+
 unsigned int i915_lvds_downclock = 0;
 module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
 
@@ -360,7 +363,7 @@ static int i915_drm_thaw(struct drm_device *dev)
                /* Resume the modeset for every activated CRTC */
                drm_helper_resume_force_mode(dev);
 
-               if (dev_priv->renderctx && dev_priv->pwrctx)
+               if (IS_IRONLAKE_M(dev))
                        ironlake_enable_rc6(dev);
        }
 
index a0149c6..65dfe81 100644 (file)
@@ -958,6 +958,7 @@ extern unsigned int i915_fbpercrtc;
 extern unsigned int i915_powersave;
 extern unsigned int i915_lvds_downclock;
 extern unsigned int i915_panel_use_ssc;
+extern unsigned int i915_enable_rc6;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
index 5cfc689..15d94c6 100644 (file)
  *   address/value pairs. Don't overdue it, though, x <= 2^4 must hold!
  */
 #define MI_LOAD_REGISTER_IMM(x)        MI_INSTR(0x22, 2*x-1)
-#define MI_FLUSH_DW            MI_INSTR(0x26, 2) /* for GEN6 */
+#define MI_FLUSH_DW            MI_INSTR(0x26, 1) /* for GEN6 */
+#define   MI_INVALIDATE_TLB    (1<<18)
+#define   MI_INVALIDATE_BSD    (1<<7)
 #define MI_BATCH_BUFFER                MI_INSTR(0x30, 1)
 #define   MI_BATCH_NON_SECURE  (1)
 #define   MI_BATCH_NON_SECURE_I965 (1<<8)
index 7e42aa5..3b00653 100644 (file)
@@ -5558,9 +5558,7 @@ static void intel_crtc_reset(struct drm_crtc *crtc)
        /* Reset flags back to the 'unknown' status so that they
         * will be correctly set on the initial modeset.
         */
-       intel_crtc->cursor_addr = 0;
        intel_crtc->dpms_mode = -1;
-       intel_crtc->active = true; /* force the pipe off on setup_init_config */
 }
 
 static struct drm_crtc_helper_funcs intel_helper_funcs = {
@@ -5666,6 +5664,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
        dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
 
        intel_crtc_reset(&intel_crtc->base);
+       intel_crtc->active = true; /* force the pipe off on setup_init_config */
 
        if (HAS_PCH_SPLIT(dev)) {
                intel_helper_funcs.prepare = ironlake_crtc_prepare;
@@ -6463,52 +6462,60 @@ void intel_enable_clock_gating(struct drm_device *dev)
        }
 }
 
-void intel_disable_clock_gating(struct drm_device *dev)
+static void ironlake_teardown_rc6(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
        if (dev_priv->renderctx) {
-               struct drm_i915_gem_object *obj = dev_priv->renderctx;
-
-               I915_WRITE(CCID, 0);
-               POSTING_READ(CCID);
-
-               i915_gem_object_unpin(obj);
-               drm_gem_object_unreference(&obj->base);
+               i915_gem_object_unpin(dev_priv->renderctx);
+               drm_gem_object_unreference(&dev_priv->renderctx->base);
                dev_priv->renderctx = NULL;
        }
 
        if (dev_priv->pwrctx) {
-               struct drm_i915_gem_object *obj = dev_priv->pwrctx;
+               i915_gem_object_unpin(dev_priv->pwrctx);
+               drm_gem_object_unreference(&dev_priv->pwrctx->base);
+               dev_priv->pwrctx = NULL;
+       }
+}
+
+static void ironlake_disable_rc6(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (I915_READ(PWRCTXA)) {
+               /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */
+               I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT);
+               wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON),
+                        50);
 
                I915_WRITE(PWRCTXA, 0);
                POSTING_READ(PWRCTXA);
 
-               i915_gem_object_unpin(obj);
-               drm_gem_object_unreference(&obj->base);
-               dev_priv->pwrctx = NULL;
+               I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT);
+               POSTING_READ(RSTDBYCTL);
        }
+
+       ironlake_disable_rc6(dev);
 }
 
-static void ironlake_disable_rc6(struct drm_device *dev)
+static int ironlake_setup_rc6(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */
-       I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT);
-       wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON),
-                10);
-       POSTING_READ(CCID);
-       I915_WRITE(PWRCTXA, 0);
-       POSTING_READ(PWRCTXA);
-       I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT);
-       POSTING_READ(RSTDBYCTL);
-       i915_gem_object_unpin(dev_priv->renderctx);
-       drm_gem_object_unreference(&dev_priv->renderctx->base);
-       dev_priv->renderctx = NULL;
-       i915_gem_object_unpin(dev_priv->pwrctx);
-       drm_gem_object_unreference(&dev_priv->pwrctx->base);
-       dev_priv->pwrctx = NULL;
+       if (dev_priv->renderctx == NULL)
+               dev_priv->renderctx = intel_alloc_context_page(dev);
+       if (!dev_priv->renderctx)
+               return -ENOMEM;
+
+       if (dev_priv->pwrctx == NULL)
+               dev_priv->pwrctx = intel_alloc_context_page(dev);
+       if (!dev_priv->pwrctx) {
+               ironlake_teardown_rc6(dev);
+               return -ENOMEM;
+       }
+
+       return 0;
 }
 
 void ironlake_enable_rc6(struct drm_device *dev)
@@ -6516,15 +6523,26 @@ void ironlake_enable_rc6(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
 
+       /* rc6 disabled by default due to repeated reports of hanging during
+        * boot and resume.
+        */
+       if (!i915_enable_rc6)
+               return;
+
+       ret = ironlake_setup_rc6(dev);
+       if (ret)
+               return;
+
        /*
         * GPU can automatically power down the render unit if given a page
         * to save state.
         */
        ret = BEGIN_LP_RING(6);
        if (ret) {
-               ironlake_disable_rc6(dev);
+               ironlake_teardown_rc6(dev);
                return;
        }
+
        OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN);
        OUT_RING(MI_SET_CONTEXT);
        OUT_RING(dev_priv->renderctx->gtt_offset |
@@ -6541,6 +6559,7 @@ void ironlake_enable_rc6(struct drm_device *dev)
        I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT);
 }
 
+
 /* Set up chip specific display functions */
 static void intel_init_display(struct drm_device *dev)
 {
@@ -6783,21 +6802,9 @@ void intel_modeset_init(struct drm_device *dev)
        if (IS_GEN6(dev))
                gen6_enable_rps(dev_priv);
 
-       if (IS_IRONLAKE_M(dev)) {
-               dev_priv->renderctx = intel_alloc_context_page(dev);
-               if (!dev_priv->renderctx)
-                       goto skip_rc6;
-               dev_priv->pwrctx = intel_alloc_context_page(dev);
-               if (!dev_priv->pwrctx) {
-                       i915_gem_object_unpin(dev_priv->renderctx);
-                       drm_gem_object_unreference(&dev_priv->renderctx->base);
-                       dev_priv->renderctx = NULL;
-                       goto skip_rc6;
-               }
+       if (IS_IRONLAKE_M(dev))
                ironlake_enable_rc6(dev);
-       }
 
-skip_rc6:
        INIT_WORK(&dev_priv->idle_work, intel_idle_update);
        setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
                    (unsigned long)dev);
index 1f4242b..51cb4e3 100644 (file)
@@ -1639,6 +1639,24 @@ static int intel_dp_get_modes(struct drm_connector *connector)
        return 0;
 }
 
+static bool
+intel_dp_detect_audio(struct drm_connector *connector)
+{
+       struct intel_dp *intel_dp = intel_attached_dp(connector);
+       struct edid *edid;
+       bool has_audio = false;
+
+       edid = drm_get_edid(connector, &intel_dp->adapter);
+       if (edid) {
+               has_audio = drm_detect_monitor_audio(edid);
+
+               connector->display_info.raw_edid = NULL;
+               kfree(edid);
+       }
+
+       return has_audio;
+}
+
 static int
 intel_dp_set_property(struct drm_connector *connector,
                      struct drm_property *property,
@@ -1652,17 +1670,23 @@ intel_dp_set_property(struct drm_connector *connector,
                return ret;
 
        if (property == intel_dp->force_audio_property) {
-               if (val == intel_dp->force_audio)
+               int i = val;
+               bool has_audio;
+
+               if (i == intel_dp->force_audio)
                        return 0;
 
-               intel_dp->force_audio = val;
+               intel_dp->force_audio = i;
 
-               if (val > 0 && intel_dp->has_audio)
-                       return 0;
-               if (val < 0 && !intel_dp->has_audio)
+               if (i == 0)
+                       has_audio = intel_dp_detect_audio(connector);
+               else
+                       has_audio = i > 0;
+
+               if (has_audio == intel_dp->has_audio)
                        return 0;
 
-               intel_dp->has_audio = val > 0;
+               intel_dp->has_audio = has_audio;
                goto done;
        }
 
index 74db255..2c43104 100644 (file)
@@ -298,7 +298,6 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
 extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
                                    u16 *blue, int regno);
 extern void intel_enable_clock_gating(struct drm_device *dev);
-extern void intel_disable_clock_gating(struct drm_device *dev);
 extern void ironlake_enable_drps(struct drm_device *dev);
 extern void ironlake_disable_drps(struct drm_device *dev);
 extern void gen6_enable_rps(struct drm_i915_private *dev_priv);
index 0d0273e..c635c9e 100644 (file)
@@ -251,6 +251,27 @@ static int intel_hdmi_get_modes(struct drm_connector *connector)
                                   &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter);
 }
 
+static bool
+intel_hdmi_detect_audio(struct drm_connector *connector)
+{
+       struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+       struct drm_i915_private *dev_priv = connector->dev->dev_private;
+       struct edid *edid;
+       bool has_audio = false;
+
+       edid = drm_get_edid(connector,
+                           &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter);
+       if (edid) {
+               if (edid->input & DRM_EDID_INPUT_DIGITAL)
+                       has_audio = drm_detect_monitor_audio(edid);
+
+               connector->display_info.raw_edid = NULL;
+               kfree(edid);
+       }
+
+       return has_audio;
+}
+
 static int
 intel_hdmi_set_property(struct drm_connector *connector,
                      struct drm_property *property,
@@ -264,17 +285,23 @@ intel_hdmi_set_property(struct drm_connector *connector,
                return ret;
 
        if (property == intel_hdmi->force_audio_property) {
-               if (val == intel_hdmi->force_audio)
+               int i = val;
+               bool has_audio;
+
+               if (i == intel_hdmi->force_audio)
                        return 0;
 
-               intel_hdmi->force_audio = val;
+               intel_hdmi->force_audio = i;
 
-               if (val > 0 && intel_hdmi->has_audio)
-                       return 0;
-               if (val < 0 && !intel_hdmi->has_audio)
+               if (i == 0)
+                       has_audio = intel_hdmi_detect_audio(connector);
+               else
+                       has_audio = i > 0;
+
+               if (has_audio == intel_hdmi->has_audio)
                        return 0;
 
-               intel_hdmi->has_audio = val > 0;
+               intel_hdmi->has_audio = has_audio;
                goto done;
        }
 
index ace8d5d..bcdba7b 100644 (file)
@@ -261,12 +261,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
                return true;
        }
 
-       /* Make sure pre-965s set dither correctly */
-       if (INTEL_INFO(dev)->gen < 4) {
-               if (dev_priv->lvds_dither)
-                       pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-       }
-
        /* Native modes don't need fitting */
        if (adjusted_mode->hdisplay == mode->hdisplay &&
            adjusted_mode->vdisplay == mode->vdisplay)
@@ -374,10 +368,16 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        }
 
 out:
+       /* If not enabling scaling, be consistent and always use 0. */
        if ((pfit_control & PFIT_ENABLE) == 0) {
                pfit_control = 0;
                pfit_pgm_ratios = 0;
        }
+
+       /* Make sure pre-965 set dither correctly */
+       if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither)
+               pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+
        if (pfit_control != intel_lvds->pfit_control ||
            pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) {
                intel_lvds->pfit_control = pfit_control;
index 6218fa9..445f27e 100644 (file)
@@ -1059,22 +1059,25 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring,
 }
 
 static int gen6_ring_flush(struct intel_ring_buffer *ring,
-                          u32 invalidate_domains,
-                          u32 flush_domains)
+                          u32 invalidate, u32 flush)
 {
+       uint32_t cmd;
        int ret;
 
-       if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0)
+       if (((invalidate | flush) & I915_GEM_GPU_DOMAINS) == 0)
                return 0;
 
        ret = intel_ring_begin(ring, 4);
        if (ret)
                return ret;
 
-       intel_ring_emit(ring, MI_FLUSH_DW);
-       intel_ring_emit(ring, 0);
+       cmd = MI_FLUSH_DW;
+       if (invalidate & I915_GEM_GPU_DOMAINS)
+               cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD;
+       intel_ring_emit(ring, cmd);
        intel_ring_emit(ring, 0);
        intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, MI_NOOP);
        intel_ring_advance(ring);
        return 0;
 }
@@ -1230,22 +1233,25 @@ static int blt_ring_begin(struct intel_ring_buffer *ring,
 }
 
 static int blt_ring_flush(struct intel_ring_buffer *ring,
-                          u32 invalidate_domains,
-                          u32 flush_domains)
+                         u32 invalidate, u32 flush)
 {
+       uint32_t cmd;
        int ret;
 
-       if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0)
+       if (((invalidate | flush) & I915_GEM_DOMAIN_RENDER) == 0)
                return 0;
 
        ret = blt_ring_begin(ring, 4);
        if (ret)
                return ret;
 
-       intel_ring_emit(ring, MI_FLUSH_DW);
-       intel_ring_emit(ring, 0);
+       cmd = MI_FLUSH_DW;
+       if (invalidate & I915_GEM_DOMAIN_RENDER)
+               cmd |= MI_INVALIDATE_TLB;
+       intel_ring_emit(ring, cmd);
        intel_ring_emit(ring, 0);
        intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, MI_NOOP);
        intel_ring_advance(ring);
        return 0;
 }
index 6a09c14..7c50cdc 100644 (file)
@@ -46,6 +46,7 @@
                          SDVO_TV_MASK)
 
 #define IS_TV(c)       (c->output_flag & SDVO_TV_MASK)
+#define IS_TMDS(c)     (c->output_flag & SDVO_TMDS_MASK)
 #define IS_LVDS(c)     (c->output_flag & SDVO_LVDS_MASK)
 #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
 
@@ -1359,7 +1360,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
                                intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
                                intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
                        }
-               }
+               } else
+                       status = connector_status_disconnected;
                connector->display_info.raw_edid = NULL;
                kfree(edid);
        }
@@ -1407,10 +1409,25 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
 
        if ((intel_sdvo_connector->output_flag & response) == 0)
                ret = connector_status_disconnected;
-       else if (response & SDVO_TMDS_MASK)
+       else if (IS_TMDS(intel_sdvo_connector))
                ret = intel_sdvo_hdmi_sink_detect(connector);
-       else
-               ret = connector_status_connected;
+       else {
+               struct edid *edid;
+
+               /* if we have an edid check it matches the connection */
+               edid = intel_sdvo_get_edid(connector);
+               if (edid == NULL)
+                       edid = intel_sdvo_get_analog_edid(connector);
+               if (edid != NULL) {
+                       if (edid->input & DRM_EDID_INPUT_DIGITAL)
+                               ret = connector_status_disconnected;
+                       else
+                               ret = connector_status_connected;
+                       connector->display_info.raw_edid = NULL;
+                       kfree(edid);
+               } else
+                       ret = connector_status_connected;
+       }
 
        /* May update encoder flag for like clock for SDVO TV, etc.*/
        if (ret == connector_status_connected) {
@@ -1446,10 +1463,15 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
                edid = intel_sdvo_get_analog_edid(connector);
 
        if (edid != NULL) {
-               if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+               struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+               bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
+               bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector);
+
+               if (connector_is_digital == monitor_is_digital) {
                        drm_mode_connector_update_edid_property(connector, edid);
                        drm_add_edid_modes(connector, edid);
                }
+
                connector->display_info.raw_edid = NULL;
                kfree(edid);
        }
@@ -1668,6 +1690,22 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
        kfree(connector);
 }
 
+static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
+{
+       struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+       struct edid *edid;
+       bool has_audio = false;
+
+       if (!intel_sdvo->is_hdmi)
+               return false;
+
+       edid = intel_sdvo_get_edid(connector);
+       if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)
+               has_audio = drm_detect_monitor_audio(edid);
+
+       return has_audio;
+}
+
 static int
 intel_sdvo_set_property(struct drm_connector *connector,
                        struct drm_property *property,
@@ -1684,17 +1722,23 @@ intel_sdvo_set_property(struct drm_connector *connector,
                return ret;
 
        if (property == intel_sdvo_connector->force_audio_property) {
-               if (val == intel_sdvo_connector->force_audio)
+               int i = val;
+               bool has_audio;
+
+               if (i == intel_sdvo_connector->force_audio)
                        return 0;
 
-               intel_sdvo_connector->force_audio = val;
+               intel_sdvo_connector->force_audio = i;
 
-               if (val > 0 && intel_sdvo->has_hdmi_audio)
-                       return 0;
-               if (val < 0 && !intel_sdvo->has_hdmi_audio)
+               if (i == 0)
+                       has_audio = intel_sdvo_detect_hdmi_audio(connector);
+               else
+                       has_audio = i > 0;
+
+               if (has_audio == intel_sdvo->has_hdmi_audio)
                        return 0;
 
-               intel_sdvo->has_hdmi_audio = val > 0;
+               intel_sdvo->has_hdmi_audio = has_audio;
                goto done;
        }
 
index 93206e4..fe4a53a 100644 (file)
@@ -1234,7 +1234,8 @@ static const struct drm_display_mode reported_modes[] = {
  * \return false if TV is disconnected.
  */
 static int
-intel_tv_detect_type (struct intel_tv *intel_tv)
+intel_tv_detect_type (struct intel_tv *intel_tv,
+                     struct drm_connector *connector)
 {
        struct drm_encoder *encoder = &intel_tv->base.base;
        struct drm_device *dev = encoder->dev;
@@ -1245,11 +1246,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
        int type;
 
        /* Disable TV interrupts around load detect or we'll recurse */
-       spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
-       i915_disable_pipestat(dev_priv, 0,
-                             PIPE_HOTPLUG_INTERRUPT_ENABLE |
-                             PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
-       spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+       if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
+               spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+               i915_disable_pipestat(dev_priv, 0,
+                                     PIPE_HOTPLUG_INTERRUPT_ENABLE |
+                                     PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
+               spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+       }
 
        save_tv_dac = tv_dac = I915_READ(TV_DAC);
        save_tv_ctl = tv_ctl = I915_READ(TV_CTL);
@@ -1302,11 +1305,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
        I915_WRITE(TV_CTL, save_tv_ctl);
 
        /* Restore interrupt config */
-       spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
-       i915_enable_pipestat(dev_priv, 0,
-                            PIPE_HOTPLUG_INTERRUPT_ENABLE |
-                            PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
-       spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+       if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
+               spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+               i915_enable_pipestat(dev_priv, 0,
+                                    PIPE_HOTPLUG_INTERRUPT_ENABLE |
+                                    PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
+               spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+       }
 
        return type;
 }
@@ -1356,7 +1361,7 @@ intel_tv_detect(struct drm_connector *connector, bool force)
        drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
 
        if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) {
-               type = intel_tv_detect_type(intel_tv);
+               type = intel_tv_detect_type(intel_tv, connector);
        } else if (force) {
                struct drm_crtc *crtc;
                int dpms_mode;
@@ -1364,7 +1369,7 @@ intel_tv_detect(struct drm_connector *connector, bool force)
                crtc = intel_get_load_detect_pipe(&intel_tv->base, connector,
                                                  &mode, &dpms_mode);
                if (crtc) {
-                       type = intel_tv_detect_type(intel_tv);
+                       type = intel_tv_detect_type(intel_tv, connector);
                        intel_release_load_detect_pipe(&intel_tv->base, connector,
                                                       dpms_mode);
                } else
@@ -1658,6 +1663,18 @@ intel_tv_init(struct drm_device *dev)
        intel_encoder = &intel_tv->base;
        connector = &intel_connector->base;
 
+       /* The documentation, for the older chipsets at least, recommend
+        * using a polling method rather than hotplug detection for TVs.
+        * This is because in order to perform the hotplug detection, the PLLs
+        * for the TV must be kept alive increasing power drain and starving
+        * bandwidth from other encoders. Notably for instance, it causes
+        * pipe underruns on Crestline when this encoder is supposedly idle.
+        *
+        * More recent chipsets favour HDMI rather than integrated S-Video.
+        */
+       connector->polled =
+               DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
+
        drm_connector_init(dev, connector, &intel_tv_connector_funcs,
                           DRM_MODE_CONNECTOR_SVIDEO);
 
index b153700..095bc50 100644 (file)
@@ -48,29 +48,29 @@ static void atombios_overscan_setup(struct drm_crtc *crtc,
 
        switch (radeon_crtc->rmx_type) {
        case RMX_CENTER:
-               args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
-               args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
-               args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
-               args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
+               args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
+               args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
+               args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
+               args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
                break;
        case RMX_ASPECT:
                a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
                a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
 
                if (a1 > a2) {
-                       args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
-                       args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
+                       args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
+                       args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
                } else if (a2 > a1) {
-                       args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
-                       args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
+                       args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
+                       args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
                }
                break;
        case RMX_FULL:
        default:
-               args.usOverscanRight = radeon_crtc->h_border;
-               args.usOverscanLeft = radeon_crtc->h_border;
-               args.usOverscanBottom = radeon_crtc->v_border;
-               args.usOverscanTop = radeon_crtc->v_border;
+               args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border);
+               args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border);
+               args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border);
+               args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border);
                break;
        }
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
@@ -419,23 +419,23 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
        memset(&args, 0, sizeof(args));
 
        if (ASIC_IS_DCE5(rdev)) {
-               args.v3.usSpreadSpectrumAmountFrac = 0;
+               args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0);
                args.v3.ucSpreadSpectrumType = ss->type;
                switch (pll_id) {
                case ATOM_PPLL1:
                        args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
-                       args.v3.usSpreadSpectrumAmount = ss->amount;
-                       args.v3.usSpreadSpectrumStep = ss->step;
+                       args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
+                       args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
                        break;
                case ATOM_PPLL2:
                        args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
-                       args.v3.usSpreadSpectrumAmount = ss->amount;
-                       args.v3.usSpreadSpectrumStep = ss->step;
+                       args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
+                       args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
                        break;
                case ATOM_DCPLL:
                        args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
-                       args.v3.usSpreadSpectrumAmount = 0;
-                       args.v3.usSpreadSpectrumStep = 0;
+                       args.v3.usSpreadSpectrumAmount = cpu_to_le16(0);
+                       args.v3.usSpreadSpectrumStep = cpu_to_le16(0);
                        break;
                case ATOM_PPLL_INVALID:
                        return;
@@ -447,18 +447,18 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
                switch (pll_id) {
                case ATOM_PPLL1:
                        args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL;
-                       args.v2.usSpreadSpectrumAmount = ss->amount;
-                       args.v2.usSpreadSpectrumStep = ss->step;
+                       args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
+                       args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
                        break;
                case ATOM_PPLL2:
                        args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL;
-                       args.v2.usSpreadSpectrumAmount = ss->amount;
-                       args.v2.usSpreadSpectrumStep = ss->step;
+                       args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
+                       args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
                        break;
                case ATOM_DCPLL:
                        args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL;
-                       args.v2.usSpreadSpectrumAmount = 0;
-                       args.v2.usSpreadSpectrumStep = 0;
+                       args.v2.usSpreadSpectrumAmount = cpu_to_le16(0);
+                       args.v2.usSpreadSpectrumStep = cpu_to_le16(0);
                        break;
                case ATOM_PPLL_INVALID:
                        return;
@@ -538,7 +538,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                        pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
                else
                        pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
-
        }
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -555,29 +554,28 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                        dp_clock = dig_connector->dp_clock;
                                }
                        }
-/* this might work properly with the new pll algo */
-#if 0 /* doesn't work properly on some laptops */
+
                        /* use recommended ref_div for ss */
                        if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
                                if (ss_enabled) {
                                        if (ss->refdiv) {
                                                pll->flags |= RADEON_PLL_USE_REF_DIV;
                                                pll->reference_div = ss->refdiv;
+                                               if (ASIC_IS_AVIVO(rdev))
+                                                       pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                                        }
                                }
                        }
-#endif
+
                        if (ASIC_IS_AVIVO(rdev)) {
                                /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
                                if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
                                        adjusted_clock = mode->clock * 2;
                                if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
                                        pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
-                               /* rv515 needs more testing with this option */
-                               if (rdev->family != CHIP_RV515) {
-                                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                                               pll->flags |= RADEON_PLL_IS_LCD;
-                               }
+                               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                                       pll->flags |= RADEON_PLL_IS_LCD;
                        } else {
                                if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
                                        pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
@@ -721,14 +719,14 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc,
                         * SetPixelClock provides the dividers
                         */
                        args.v5.ucCRTC = ATOM_CRTC_INVALID;
-                       args.v5.usPixelClock = dispclk;
+                       args.v5.usPixelClock = cpu_to_le16(dispclk);
                        args.v5.ucPpll = ATOM_DCPLL;
                        break;
                case 6:
                        /* if the default dcpll clock is specified,
                         * SetPixelClock provides the dividers
                         */
-                       args.v6.ulDispEngClkFreq = dispclk;
+                       args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
                        args.v6.ucPpll = ATOM_DCPLL;
                        break;
                default:
@@ -957,11 +955,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        /* adjust pixel clock as needed */
        adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
 
-       /* rv515 seems happier with the old algo */
-       if (rdev->family == CHIP_RV515)
-               radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-                                         &ref_div, &post_div);
-       else if (ASIC_IS_AVIVO(rdev))
+       if (ASIC_IS_AVIVO(rdev))
                radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
                                         &ref_div, &post_div);
        else
@@ -995,9 +989,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        }
 }
 
-static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
-                                     struct drm_framebuffer *fb,
-                                     int x, int y, int atomic)
+static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
+                                struct drm_framebuffer *fb,
+                                int x, int y, int atomic)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
@@ -1137,12 +1131,6 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
               (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
 
-       if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
-               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
-                      EVERGREEN_INTERLEAVE_EN);
-       else
-               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
-
        if (!atomic && fb && fb != crtc->fb) {
                radeon_fb = to_radeon_framebuffer(fb);
                rbo = radeon_fb->obj->driver_private;
@@ -1300,12 +1288,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
               (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
 
-       if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
-               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
-                      AVIVO_D1MODE_INTERLEAVE_EN);
-       else
-               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
-
        if (!atomic && fb && fb != crtc->fb) {
                radeon_fb = to_radeon_framebuffer(fb);
                rbo = radeon_fb->obj->driver_private;
@@ -1329,7 +1311,7 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
        struct radeon_device *rdev = dev->dev_private;
 
        if (ASIC_IS_DCE4(rdev))
-               return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0);
+               return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
        else if (ASIC_IS_AVIVO(rdev))
                return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
        else
@@ -1344,7 +1326,7 @@ int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
        struct radeon_device *rdev = dev->dev_private;
 
        if (ASIC_IS_DCE4(rdev))
-               return evergreen_crtc_do_set_base(crtc, fb, x, y, 1);
+               return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
        else if (ASIC_IS_AVIVO(rdev))
                return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
        else
index ffdc833..d270b3f 100644 (file)
@@ -1192,7 +1192,11 @@ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
        radeon_ring_write(rdev, 1);
        /* FIXME: implement */
        radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
-       radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC);
+       radeon_ring_write(rdev,
+#ifdef __BIG_ENDIAN
+                         (2 << 0) |
+#endif
+                         (ib->gpu_addr & 0xFFFFFFFC));
        radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF);
        radeon_ring_write(rdev, ib->length_dw);
 }
@@ -1207,7 +1211,11 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev)
                return -EINVAL;
 
        r700_cp_stop(rdev);
-       WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0));
+       WREG32(CP_RB_CNTL,
+#ifdef __BIG_ENDIAN
+              BUF_SWAP_32BIT |
+#endif
+              RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
 
        fw_data = (const __be32 *)rdev->pfp_fw->data;
        WREG32(CP_PFP_UCODE_ADDR, 0);
@@ -1326,7 +1334,11 @@ int evergreen_cp_resume(struct radeon_device *rdev)
        WREG32(CP_RB_WPTR, 0);
 
        /* set the wb address wether it's enabled or not */
-       WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
+       WREG32(CP_RB_RPTR_ADDR,
+#ifdef __BIG_ENDIAN
+              RB_RPTR_SWAP(2) |
+#endif
+              ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC));
        WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
        WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
 
@@ -2627,8 +2639,8 @@ restart_ih:
        while (rptr != wptr) {
                /* wptr/rptr are in bytes! */
                ring_index = rptr / 4;
-               src_id =  rdev->ih.ring[ring_index] & 0xff;
-               src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff;
+               src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
+               src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
 
                switch (src_id) {
                case 1: /* D1 vblank/vline */
index a1ba4b3..2adfb03 100644 (file)
@@ -55,7 +55,7 @@ set_render_target(struct radeon_device *rdev, int format,
        if (h < 8)
                h = 8;
 
-       cb_color_info = ((format << 2) | (1 << 24));
+       cb_color_info = ((format << 2) | (1 << 24) | (1 << 8));
        pitch = (w / 8) - 1;
        slice = ((w * h) / 64) - 1;
 
@@ -133,6 +133,9 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
 
        /* high addr, stride */
        sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8));
+#ifdef __BIG_ENDIAN
+       sq_vtx_constant_word2 |= (2 << 30);
+#endif
        /* xyzw swizzles */
        sq_vtx_constant_word3 = (0 << 3) | (1 << 6) | (2 << 9) | (3 << 12);
 
@@ -173,7 +176,7 @@ set_tex_resource(struct radeon_device *rdev,
        sq_tex_resource_word0 = (1 << 0); /* 2D */
        sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 6) |
                                  ((w - 1) << 18));
-       sq_tex_resource_word1 = ((h - 1) << 0);
+       sq_tex_resource_word1 = ((h - 1) << 0) | (1 << 28);
        /* xyzw swizzles */
        sq_tex_resource_word4 = (0 << 16) | (1 << 19) | (2 << 22) | (3 << 25);
 
@@ -221,7 +224,11 @@ draw_auto(struct radeon_device *rdev)
        radeon_ring_write(rdev, DI_PT_RECTLIST);
 
        radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0));
-       radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT);
+       radeon_ring_write(rdev,
+#ifdef __BIG_ENDIAN
+                         (2 << 2) |
+#endif
+                         DI_INDEX_SIZE_16_BIT);
 
        radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0));
        radeon_ring_write(rdev, 1);
@@ -541,7 +548,7 @@ static inline uint32_t i2f(uint32_t input)
 int evergreen_blit_init(struct radeon_device *rdev)
 {
        u32 obj_size;
-       int r, dwords;
+       int i, r, dwords;
        void *ptr;
        u32 packet2s[16];
        int num_packet2s = 0;
@@ -557,7 +564,7 @@ int evergreen_blit_init(struct radeon_device *rdev)
 
        dwords = rdev->r600_blit.state_len;
        while (dwords & 0xf) {
-               packet2s[num_packet2s++] = PACKET2(0);
+               packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0));
                dwords++;
        }
 
@@ -598,8 +605,10 @@ int evergreen_blit_init(struct radeon_device *rdev)
        if (num_packet2s)
                memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
                            packet2s, num_packet2s * 4);
-       memcpy(ptr + rdev->r600_blit.vs_offset, evergreen_vs, evergreen_vs_size * 4);
-       memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4);
+       for (i = 0; i < evergreen_vs_size; i++)
+               *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]);
+       for (i = 0; i < evergreen_ps_size; i++)
+               *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]);
        radeon_bo_kunmap(rdev->r600_blit.shader_obj);
        radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 
index ef1d28c..3a10399 100644 (file)
@@ -311,11 +311,19 @@ const u32 evergreen_vs[] =
        0x00000000,
        0x3c000000,
        0x67961001,
+#ifdef __BIG_ENDIAN
+       0x000a0000,
+#else
        0x00080000,
+#endif
        0x00000000,
        0x1c000000,
        0x67961000,
+#ifdef __BIG_ENDIAN
+       0x00020008,
+#else
        0x00000008,
+#endif
        0x00000000,
 };
 
index afec1ac..eb4acf4 100644 (file)
@@ -98,6 +98,7 @@
 #define                BUF_SWAP_32BIT                                  (2 << 16)
 #define        CP_RB_RPTR                                      0x8700
 #define        CP_RB_RPTR_ADDR                                 0xC10C
+#define                RB_RPTR_SWAP(x)                                 ((x) << 0)
 #define        CP_RB_RPTR_ADDR_HI                              0xC110
 #define        CP_RB_RPTR_WR                                   0xC108
 #define        CP_RB_WPTR                                      0xC114
index 607241c..5a82b6b 100644 (file)
@@ -673,8 +673,10 @@ static int parser_auth(struct table *t, const char *filename)
        last_reg = strtol(last_reg_s, NULL, 16);
 
        do {
-               if (fgets(buf, 1024, file) == NULL)
+               if (fgets(buf, 1024, file) == NULL) {
+                       fclose(file);
                        return -1;
+               }
                len = strlen(buf);
                if (ftell(file) == end)
                        done = 1;
@@ -685,6 +687,7 @@ static int parser_auth(struct table *t, const char *filename)
                                fprintf(stderr,
                                        "Error matching regular expression %d in %s\n",
                                        r, filename);
+                               fclose(file);
                                return -1;
                        } else {
                                buf[match[0].rm_eo] = 0;
index 5f15820..56deae5 100644 (file)
@@ -1427,6 +1427,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                }
                track->zb.robj = reloc->robj;
                track->zb.offset = idx_value;
+               track->zb_dirty = true;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                break;
        case RADEON_RB3D_COLOROFFSET:
@@ -1439,6 +1440,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                }
                track->cb[0].robj = reloc->robj;
                track->cb[0].offset = idx_value;
+               track->cb_dirty = true;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                break;
        case RADEON_PP_TXOFFSET_0:
@@ -1454,6 +1456,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                }
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                track->textures[i].robj = reloc->robj;
+               track->tex_dirty = true;
                break;
        case RADEON_PP_CUBIC_OFFSET_T0_0:
        case RADEON_PP_CUBIC_OFFSET_T0_1:
@@ -1471,6 +1474,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                track->textures[0].cube_info[i].offset = idx_value;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                track->textures[0].cube_info[i].robj = reloc->robj;
+               track->tex_dirty = true;
                break;
        case RADEON_PP_CUBIC_OFFSET_T1_0:
        case RADEON_PP_CUBIC_OFFSET_T1_1:
@@ -1488,6 +1492,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                track->textures[1].cube_info[i].offset = idx_value;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                track->textures[1].cube_info[i].robj = reloc->robj;
+               track->tex_dirty = true;
                break;
        case RADEON_PP_CUBIC_OFFSET_T2_0:
        case RADEON_PP_CUBIC_OFFSET_T2_1:
@@ -1505,9 +1510,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                track->textures[2].cube_info[i].offset = idx_value;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                track->textures[2].cube_info[i].robj = reloc->robj;
+               track->tex_dirty = true;
                break;
        case RADEON_RE_WIDTH_HEIGHT:
                track->maxy = ((idx_value >> 16) & 0x7FF);
+               track->cb_dirty = true;
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_COLORPITCH:
                r = r100_cs_packet_next_reloc(p, &reloc);
@@ -1528,9 +1536,11 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                ib[idx] = tmp;
 
                track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
+               track->cb_dirty = true;
                break;
        case RADEON_RB3D_DEPTHPITCH:
                track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_CNTL:
                switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
@@ -1555,6 +1565,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                        return -EINVAL;
                }
                track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
+               track->cb_dirty = true;
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_ZSTENCILCNTL:
                switch (idx_value & 0xf) {
@@ -1572,6 +1584,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                default:
                        break;
                }
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_ZPASS_ADDR:
                r = r100_cs_packet_next_reloc(p, &reloc);
@@ -1588,6 +1601,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                        uint32_t temp = idx_value >> 4;
                        for (i = 0; i < track->num_texture; i++)
                                track->textures[i].enabled = !!(temp & (1 << i));
+                       track->tex_dirty = true;
                }
                break;
        case RADEON_SE_VF_CNTL:
@@ -1602,12 +1616,14 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                i = (reg - RADEON_PP_TEX_SIZE_0) / 8;
                track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
                track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
+               track->tex_dirty = true;
                break;
        case RADEON_PP_TEX_PITCH_0:
        case RADEON_PP_TEX_PITCH_1:
        case RADEON_PP_TEX_PITCH_2:
                i = (reg - RADEON_PP_TEX_PITCH_0) / 8;
                track->textures[i].pitch = idx_value + 32;
+               track->tex_dirty = true;
                break;
        case RADEON_PP_TXFILTER_0:
        case RADEON_PP_TXFILTER_1:
@@ -1621,6 +1637,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                tmp = (idx_value >> 27) & 0x7;
                if (tmp == 2 || tmp == 6)
                        track->textures[i].roundup_h = false;
+               track->tex_dirty = true;
                break;
        case RADEON_PP_TXFORMAT_0:
        case RADEON_PP_TXFORMAT_1:
@@ -1673,6 +1690,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                }
                track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
                track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
+               track->tex_dirty = true;
                break;
        case RADEON_PP_CUBIC_FACES_0:
        case RADEON_PP_CUBIC_FACES_1:
@@ -1683,6 +1701,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
                        track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
                }
+               track->tex_dirty = true;
                break;
        default:
                printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
@@ -3318,9 +3337,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
        unsigned long size;
        unsigned prim_walk;
        unsigned nverts;
-       unsigned num_cb = track->num_cb;
+       unsigned num_cb = track->cb_dirty ? track->num_cb : 0;
 
-       if (!track->zb_cb_clear && !track->color_channel_mask &&
+       if (num_cb && !track->zb_cb_clear && !track->color_channel_mask &&
            !track->blend_read_enable)
                num_cb = 0;
 
@@ -3341,7 +3360,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
                        return -EINVAL;
                }
        }
-       if (track->z_enabled) {
+       track->cb_dirty = false;
+
+       if (track->zb_dirty && track->z_enabled) {
                if (track->zb.robj == NULL) {
                        DRM_ERROR("[drm] No buffer for z buffer !\n");
                        return -EINVAL;
@@ -3358,6 +3379,28 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
                        return -EINVAL;
                }
        }
+       track->zb_dirty = false;
+
+       if (track->aa_dirty && track->aaresolve) {
+               if (track->aa.robj == NULL) {
+                       DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i);
+                       return -EINVAL;
+               }
+               /* I believe the format comes from colorbuffer0. */
+               size = track->aa.pitch * track->cb[0].cpp * track->maxy;
+               size += track->aa.offset;
+               if (size > radeon_bo_size(track->aa.robj)) {
+                       DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d "
+                                 "(need %lu have %lu) !\n", i, size,
+                                 radeon_bo_size(track->aa.robj));
+                       DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n",
+                                 i, track->aa.pitch, track->cb[0].cpp,
+                                 track->aa.offset, track->maxy);
+                       return -EINVAL;
+               }
+       }
+       track->aa_dirty = false;
+
        prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
        if (track->vap_vf_cntl & (1 << 14)) {
                nverts = track->vap_alt_nverts;
@@ -3417,13 +3460,23 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
                          prim_walk);
                return -EINVAL;
        }
-       return r100_cs_track_texture_check(rdev, track);
+
+       if (track->tex_dirty) {
+               track->tex_dirty = false;
+               return r100_cs_track_texture_check(rdev, track);
+       }
+       return 0;
 }
 
 void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track)
 {
        unsigned i, face;
 
+       track->cb_dirty = true;
+       track->zb_dirty = true;
+       track->tex_dirty = true;
+       track->aa_dirty = true;
+
        if (rdev->family < CHIP_R300) {
                track->num_cb = 1;
                if (rdev->family <= CHIP_RS200)
@@ -3437,6 +3490,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
                track->num_texture = 16;
                track->maxy = 4096;
                track->separate_cube = 0;
+               track->aaresolve = true;
+               track->aa.robj = NULL;
        }
 
        for (i = 0; i < track->num_cb; i++) {
index af65600..2fef9de 100644 (file)
@@ -52,14 +52,7 @@ struct r100_cs_track_texture {
        unsigned                compress_format;
 };
 
-struct r100_cs_track_limits {
-       unsigned num_cb;
-       unsigned num_texture;
-       unsigned max_levels;
-};
-
 struct r100_cs_track {
-       struct radeon_device *rdev;
        unsigned                        num_cb;
        unsigned                        num_texture;
        unsigned                        maxy;
@@ -73,11 +66,17 @@ struct r100_cs_track {
        struct r100_cs_track_array      arrays[11];
        struct r100_cs_track_cb         cb[R300_MAX_CB];
        struct r100_cs_track_cb         zb;
+       struct r100_cs_track_cb         aa;
        struct r100_cs_track_texture    textures[R300_TRACK_MAX_TEXTURE];
        bool                            z_enabled;
        bool                            separate_cube;
        bool                            zb_cb_clear;
        bool                            blend_read_enable;
+       bool                            cb_dirty;
+       bool                            zb_dirty;
+       bool                            tex_dirty;
+       bool                            aa_dirty;
+       bool                            aaresolve;
 };
 
 int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
index d2408c3..f240583 100644 (file)
@@ -184,6 +184,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                }
                track->zb.robj = reloc->robj;
                track->zb.offset = idx_value;
+               track->zb_dirty = true;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                break;
        case RADEON_RB3D_COLOROFFSET:
@@ -196,6 +197,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                }
                track->cb[0].robj = reloc->robj;
                track->cb[0].offset = idx_value;
+               track->cb_dirty = true;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                break;
        case R200_PP_TXOFFSET_0:
@@ -214,6 +216,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                }
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                track->textures[i].robj = reloc->robj;
+               track->tex_dirty = true;
                break;
        case R200_PP_CUBIC_OFFSET_F1_0:
        case R200_PP_CUBIC_OFFSET_F2_0:
@@ -257,9 +260,12 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                track->textures[i].cube_info[face - 1].offset = idx_value;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                track->textures[i].cube_info[face - 1].robj = reloc->robj;
+               track->tex_dirty = true;
                break;
        case RADEON_RE_WIDTH_HEIGHT:
                track->maxy = ((idx_value >> 16) & 0x7FF);
+               track->cb_dirty = true;
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_COLORPITCH:
                r = r100_cs_packet_next_reloc(p, &reloc);
@@ -280,9 +286,11 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                ib[idx] = tmp;
 
                track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
+               track->cb_dirty = true;
                break;
        case RADEON_RB3D_DEPTHPITCH:
                track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_CNTL:
                switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
@@ -312,6 +320,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                }
 
                track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
+               track->cb_dirty = true;
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_ZSTENCILCNTL:
                switch (idx_value & 0xf) {
@@ -329,6 +339,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                default:
                        break;
                }
+               track->zb_dirty = true;
                break;
        case RADEON_RB3D_ZPASS_ADDR:
                r = r100_cs_packet_next_reloc(p, &reloc);
@@ -345,6 +356,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                        uint32_t temp = idx_value >> 4;
                        for (i = 0; i < track->num_texture; i++)
                                track->textures[i].enabled = !!(temp & (1 << i));
+                       track->tex_dirty = true;
                }
                break;
        case RADEON_SE_VF_CNTL:
@@ -369,6 +381,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                i = (reg - R200_PP_TXSIZE_0) / 32;
                track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
                track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
+               track->tex_dirty = true;
                break;
        case R200_PP_TXPITCH_0:
        case R200_PP_TXPITCH_1:
@@ -378,6 +391,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
        case R200_PP_TXPITCH_5:
                i = (reg - R200_PP_TXPITCH_0) / 32;
                track->textures[i].pitch = idx_value + 32;
+               track->tex_dirty = true;
                break;
        case R200_PP_TXFILTER_0:
        case R200_PP_TXFILTER_1:
@@ -394,6 +408,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                tmp = (idx_value >> 27) & 0x7;
                if (tmp == 2 || tmp == 6)
                        track->textures[i].roundup_h = false;
+               track->tex_dirty = true;
                break;
        case R200_PP_TXMULTI_CTL_0:
        case R200_PP_TXMULTI_CTL_1:
@@ -432,6 +447,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].tex_coord_type = 1;
                        break;
                }
+               track->tex_dirty = true;
                break;
        case R200_PP_TXFORMAT_0:
        case R200_PP_TXFORMAT_1:
@@ -488,6 +504,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                }
                track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
                track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
+               track->tex_dirty = true;
                break;
        case R200_PP_CUBIC_FACES_0:
        case R200_PP_CUBIC_FACES_1:
@@ -501,6 +518,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
                        track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
                }
+               track->tex_dirty = true;
                break;
        default:
                printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
index 55fe5ba..768c60e 100644 (file)
@@ -667,6 +667,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                }
                track->cb[i].robj = reloc->robj;
                track->cb[i].offset = idx_value;
+               track->cb_dirty = true;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                break;
        case R300_ZB_DEPTHOFFSET:
@@ -679,6 +680,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                }
                track->zb.robj = reloc->robj;
                track->zb.offset = idx_value;
+               track->zb_dirty = true;
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                break;
        case R300_TX_OFFSET_0:
@@ -717,6 +719,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                tmp |= tile_flags;
                ib[idx] = tmp;
                track->textures[i].robj = reloc->robj;
+               track->tex_dirty = true;
                break;
        /* Tracked registers */
        case 0x2084:
@@ -743,6 +746,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                if (p->rdev->family < CHIP_RV515) {
                        track->maxy -= 1440;
                }
+               track->cb_dirty = true;
+               track->zb_dirty = true;
                break;
        case 0x4E00:
                /* RB3D_CCTL */
@@ -752,6 +757,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        return -EINVAL;
                }
                track->num_cb = ((idx_value >> 5) & 0x3) + 1;
+               track->cb_dirty = true;
                break;
        case 0x4E38:
        case 0x4E3C:
@@ -814,6 +820,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                                  ((idx_value >> 21) & 0xF));
                        return -EINVAL;
                }
+               track->cb_dirty = true;
                break;
        case 0x4F00:
                /* ZB_CNTL */
@@ -822,6 +829,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                } else {
                        track->z_enabled = false;
                }
+               track->zb_dirty = true;
                break;
        case 0x4F10:
                /* ZB_FORMAT */
@@ -838,6 +846,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                                  (idx_value & 0xF));
                        return -EINVAL;
                }
+               track->zb_dirty = true;
                break;
        case 0x4F24:
                /* ZB_DEPTHPITCH */
@@ -861,14 +870,17 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                ib[idx] = tmp;
 
                track->zb.pitch = idx_value & 0x3FFC;
+               track->zb_dirty = true;
                break;
        case 0x4104:
+               /* TX_ENABLE */
                for (i = 0; i < 16; i++) {
                        bool enabled;
 
                        enabled = !!(idx_value & (1 << i));
                        track->textures[i].enabled = enabled;
                }
+               track->tex_dirty = true;
                break;
        case 0x44C0:
        case 0x44C4:
@@ -951,8 +963,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        DRM_ERROR("Invalid texture format %u\n",
                                  (idx_value & 0x1F));
                        return -EINVAL;
-                       break;
                }
+               track->tex_dirty = true;
                break;
        case 0x4400:
        case 0x4404:
@@ -980,6 +992,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                if (tmp == 2 || tmp == 4 || tmp == 6) {
                        track->textures[i].roundup_h = false;
                }
+               track->tex_dirty = true;
                break;
        case 0x4500:
        case 0x4504:
@@ -1017,6 +1030,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        DRM_ERROR("Forbidden bit TXFORMAT_MSB\n");
                        return -EINVAL;
                }
+               track->tex_dirty = true;
                break;
        case 0x4480:
        case 0x4484:
@@ -1046,6 +1060,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                track->textures[i].use_pitch = !!tmp;
                tmp = (idx_value >> 22) & 0xF;
                track->textures[i].txdepth = tmp;
+               track->tex_dirty = true;
                break;
        case R300_ZB_ZPASS_ADDR:
                r = r100_cs_packet_next_reloc(p, &reloc);
@@ -1060,6 +1075,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
        case 0x4e0c:
                /* RB3D_COLOR_CHANNEL_MASK */
                track->color_channel_mask = idx_value;
+               track->cb_dirty = true;
                break;
        case 0x43a4:
                /* SC_HYPERZ_EN */
@@ -1073,6 +1089,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
        case 0x4f1c:
                /* ZB_BW_CNTL */
                track->zb_cb_clear = !!(idx_value & (1 << 5));
+               track->cb_dirty = true;
+               track->zb_dirty = true;
                if (p->rdev->hyperz_filp != p->filp) {
                        if (idx_value & (R300_HIZ_ENABLE |
                                         R300_RD_COMP_ENABLE |
@@ -1084,8 +1102,28 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
        case 0x4e04:
                /* RB3D_BLENDCNTL */
                track->blend_read_enable = !!(idx_value & (1 << 2));
+               track->cb_dirty = true;
+               break;
+       case R300_RB3D_AARESOLVE_OFFSET:
+               r = r100_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                 idx, reg);
+                       r100_cs_dump_packet(p, pkt);
+                       return r;
+               }
+               track->aa.robj = reloc->robj;
+               track->aa.offset = idx_value;
+               track->aa_dirty = true;
+               ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
+               break;
+       case R300_RB3D_AARESOLVE_PITCH:
+               track->aa.pitch = idx_value & 0x3FFE;
+               track->aa_dirty = true;
                break;
-       case 0x4f28: /* ZB_DEPTHCLEARVALUE */
+       case R300_RB3D_AARESOLVE_CTL:
+               track->aaresolve = idx_value & 0x1;
+               track->aa_dirty = true;
                break;
        case 0x4f30: /* ZB_MASK_OFFSET */
        case 0x4f34: /* ZB_ZMASK_PITCH */
index 1a0d536..f0bce39 100644 (file)
 #define R300_RB3D_COLORPITCH2               0x4E40 /* GUESS */
 #define R300_RB3D_COLORPITCH3               0x4E44 /* GUESS */
 
+#define R300_RB3D_AARESOLVE_OFFSET          0x4E80
+#define R300_RB3D_AARESOLVE_PITCH           0x4E84
 #define R300_RB3D_AARESOLVE_CTL             0x4E88
 /* gap */
 
index 650672a..de88624 100644 (file)
@@ -2105,7 +2105,11 @@ static int r600_cp_load_microcode(struct radeon_device *rdev)
 
        r600_cp_stop(rdev);
 
-       WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
+       WREG32(CP_RB_CNTL,
+#ifdef __BIG_ENDIAN
+              BUF_SWAP_32BIT |
+#endif
+              RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
 
        /* Reset cp */
        WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
@@ -2192,7 +2196,11 @@ int r600_cp_resume(struct radeon_device *rdev)
        WREG32(CP_RB_WPTR, 0);
 
        /* set the wb address whether it's enabled or not */
-       WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
+       WREG32(CP_RB_RPTR_ADDR,
+#ifdef __BIG_ENDIAN
+              RB_RPTR_SWAP(2) |
+#endif
+              ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC));
        WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
        WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
 
@@ -2628,7 +2636,11 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
 {
        /* FIXME: implement */
        radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
-       radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC);
+       radeon_ring_write(rdev,
+#ifdef __BIG_ENDIAN
+                         (2 << 0) |
+#endif
+                         (ib->gpu_addr & 0xFFFFFFFC));
        radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF);
        radeon_ring_write(rdev, ib->length_dw);
 }
@@ -3297,8 +3309,8 @@ restart_ih:
        while (rptr != wptr) {
                /* wptr/rptr are in bytes! */
                ring_index = rptr / 4;
-               src_id =  rdev->ih.ring[ring_index] & 0xff;
-               src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff;
+               src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
+               src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
 
                switch (src_id) {
                case 1: /* D1 vblank/vline */
index ca5c29f..7f10434 100644 (file)
@@ -137,9 +137,9 @@ set_shaders(struct drm_device *dev)
        ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256);
 
        for (i = 0; i < r6xx_vs_size; i++)
-               vs[i] = r6xx_vs[i];
+               vs[i] = cpu_to_le32(r6xx_vs[i]);
        for (i = 0; i < r6xx_ps_size; i++)
-               ps[i] = r6xx_ps[i];
+               ps[i] = cpu_to_le32(r6xx_ps[i]);
 
        dev_priv->blit_vb->used = 512;
 
@@ -192,6 +192,9 @@ set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr)
        DRM_DEBUG("\n");
 
        sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8));
+#ifdef __BIG_ENDIAN
+       sq_vtx_constant_word2 |= (2 << 30);
+#endif
 
        BEGIN_RING(9);
        OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
@@ -291,7 +294,11 @@ draw_auto(drm_radeon_private_t *dev_priv)
        OUT_RING(DI_PT_RECTLIST);
 
        OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
+#ifdef __BIG_ENDIAN
+       OUT_RING((2 << 2) | DI_INDEX_SIZE_16_BIT);
+#else
        OUT_RING(DI_INDEX_SIZE_16_BIT);
+#endif
 
        OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
        OUT_RING(1);
index 86e5aa0..41f7aaf 100644 (file)
@@ -54,7 +54,7 @@ set_render_target(struct radeon_device *rdev, int format,
        if (h < 8)
                h = 8;
 
-       cb_color_info = ((format << 2) | (1 << 27));
+       cb_color_info = ((format << 2) | (1 << 27) | (1 << 8));
        pitch = (w / 8) - 1;
        slice = ((w * h) / 64) - 1;
 
@@ -165,6 +165,9 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
        u32 sq_vtx_constant_word2;
 
        sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8));
+#ifdef __BIG_ENDIAN
+       sq_vtx_constant_word2 |= (2 << 30);
+#endif
 
        radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
        radeon_ring_write(rdev, 0x460);
@@ -199,7 +202,7 @@ set_tex_resource(struct radeon_device *rdev,
        if (h < 1)
                h = 1;
 
-       sq_tex_resource_word0 = (1 << 0);
+       sq_tex_resource_word0 = (1 << 0) | (1 << 3);
        sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
                                  ((w - 1) << 19));
 
@@ -253,7 +256,11 @@ draw_auto(struct radeon_device *rdev)
        radeon_ring_write(rdev, DI_PT_RECTLIST);
 
        radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0));
-       radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT);
+       radeon_ring_write(rdev,
+#ifdef __BIG_ENDIAN
+                         (2 << 2) |
+#endif
+                         DI_INDEX_SIZE_16_BIT);
 
        radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0));
        radeon_ring_write(rdev, 1);
@@ -424,7 +431,11 @@ set_default_state(struct radeon_device *rdev)
        dwords = ALIGN(rdev->r600_blit.state_len, 0x10);
        gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
        radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
-       radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC);
+       radeon_ring_write(rdev,
+#ifdef __BIG_ENDIAN
+                         (2 << 0) |
+#endif
+                         (gpu_addr & 0xFFFFFFFC));
        radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
        radeon_ring_write(rdev, dwords);
 
@@ -467,7 +478,7 @@ static inline uint32_t i2f(uint32_t input)
 int r600_blit_init(struct radeon_device *rdev)
 {
        u32 obj_size;
-       int r, dwords;
+       int i, r, dwords;
        void *ptr;
        u32 packet2s[16];
        int num_packet2s = 0;
@@ -486,7 +497,7 @@ int r600_blit_init(struct radeon_device *rdev)
 
        dwords = rdev->r600_blit.state_len;
        while (dwords & 0xf) {
-               packet2s[num_packet2s++] = PACKET2(0);
+               packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0));
                dwords++;
        }
 
@@ -529,8 +540,10 @@ int r600_blit_init(struct radeon_device *rdev)
        if (num_packet2s)
                memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
                            packet2s, num_packet2s * 4);
-       memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4);
-       memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
+       for (i = 0; i < r6xx_vs_size; i++)
+               *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(r6xx_vs[i]);
+       for (i = 0; i < r6xx_ps_size; i++)
+               *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(r6xx_ps[i]);
        radeon_bo_kunmap(rdev->r600_blit.shader_obj);
        radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 
index e8151c1..2d1f6c5 100644 (file)
@@ -684,7 +684,11 @@ const u32 r6xx_vs[] =
        0x00000000,
        0x3c000000,
        0x68cd1000,
+#ifdef __BIG_ENDIAN
+       0x000a0000,
+#else
        0x00080000,
+#endif
        0x00000000,
 };
 
index 4f4cd8b..c3ab959 100644 (file)
@@ -396,6 +396,9 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
        r600_do_cp_stop(dev_priv);
 
        RADEON_WRITE(R600_CP_RB_CNTL,
+#ifdef __BIG_ENDIAN
+                    R600_BUF_SWAP_32BIT |
+#endif
                     R600_RB_NO_UPDATE |
                     R600_RB_BLKSZ(15) |
                     R600_RB_BUFSZ(3));
@@ -486,9 +489,12 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
        r600_do_cp_stop(dev_priv);
 
        RADEON_WRITE(R600_CP_RB_CNTL,
+#ifdef __BIG_ENDIAN
+                    R600_BUF_SWAP_32BIT |
+#endif
                     R600_RB_NO_UPDATE |
-                    (15 << 8) |
-                    (3 << 0));
+                    R600_RB_BLKSZ(15) |
+                    R600_RB_BUFSZ(3));
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
@@ -550,8 +556,12 @@ static void r600_test_writeback(drm_radeon_private_t *dev_priv)
 
        if (!dev_priv->writeback_works) {
                /* Disable writeback to avoid unnecessary bus master transfer */
-               RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) |
-                            RADEON_RB_NO_UPDATE);
+               RADEON_WRITE(R600_CP_RB_CNTL,
+#ifdef __BIG_ENDIAN
+                            R600_BUF_SWAP_32BIT |
+#endif
+                            RADEON_READ(R600_CP_RB_CNTL) |
+                            R600_RB_NO_UPDATE);
                RADEON_WRITE(R600_SCRATCH_UMSK, 0);
        }
 }
@@ -575,7 +585,11 @@ int r600_do_engine_reset(struct drm_device *dev)
 
        RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
        cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL);
-       RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA);
+       RADEON_WRITE(R600_CP_RB_CNTL,
+#ifdef __BIG_ENDIAN
+                    R600_BUF_SWAP_32BIT |
+#endif
+                    R600_RB_RPTR_WR_ENA);
 
        RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr);
        RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr);
@@ -1838,7 +1852,10 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
                        + dev_priv->gart_vm_start;
        }
        RADEON_WRITE(R600_CP_RB_RPTR_ADDR,
-                    rptr_addr & 0xffffffff);
+#ifdef __BIG_ENDIAN
+                    (2 << 0) |
+#endif
+                    (rptr_addr & 0xfffffffc));
        RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI,
                     upper_32_bits(rptr_addr));
 
@@ -1889,7 +1906,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
        {
                u64 scratch_addr;
 
-               scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR);
+               scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR) & 0xFFFFFFFC;
                scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32;
                scratch_addr += R600_SCRATCH_REG_OFFSET;
                scratch_addr >>= 8;
index 7831e08..153095f 100644 (file)
@@ -295,17 +295,18 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
        }
 
        if (!IS_ALIGNED(pitch, pitch_align)) {
-               dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                        __func__, __LINE__, pitch);
+               dev_warn(p->dev, "%s:%d cb pitch (%d, 0x%x, %d) invalid\n",
+                        __func__, __LINE__, pitch, pitch_align, array_mode);
                return -EINVAL;
        }
        if (!IS_ALIGNED(height, height_align)) {
-               dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
-                        __func__, __LINE__, height);
+               dev_warn(p->dev, "%s:%d cb height (%d, 0x%x, %d) invalid\n",
+                        __func__, __LINE__, height, height_align, array_mode);
                return -EINVAL;
        }
        if (!IS_ALIGNED(base_offset, base_align)) {
-               dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+               dev_warn(p->dev, "%s offset[%d] 0x%llx 0x%llx, %d not aligned\n", __func__, i,
+                        base_offset, base_align, array_mode);
                return -EINVAL;
        }
 
@@ -320,7 +321,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                         * broken userspace.
                         */
                } else {
-                       dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
+                       dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i,
+                                array_mode,
+                                track->cb_color_bo_offset[i], tmp,
+                                radeon_bo_size(track->cb_color_bo[i]));
                        return -EINVAL;
                }
        }
@@ -455,17 +459,18 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                        }
 
                        if (!IS_ALIGNED(pitch, pitch_align)) {
-                               dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
-                                        __func__, __LINE__, pitch);
+                               dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
+                                        __func__, __LINE__, pitch, pitch_align, array_mode);
                                return -EINVAL;
                        }
                        if (!IS_ALIGNED(height, height_align)) {
-                               dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
-                                        __func__, __LINE__, height);
+                               dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
+                                        __func__, __LINE__, height, height_align, array_mode);
                                return -EINVAL;
                        }
                        if (!IS_ALIGNED(base_offset, base_align)) {
-                               dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+                               dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i,
+                                        base_offset, base_align, array_mode);
                                return -EINVAL;
                        }
 
@@ -473,9 +478,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                        nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
                        tmp = ntiles * bpe * 64 * nviews;
                        if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
-                               dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n",
-                                               track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
-                                               radeon_bo_size(track->db_bo));
+                               dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
+                                        array_mode,
+                                        track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
+                                        radeon_bo_size(track->db_bo));
                                return -EINVAL;
                        }
                }
@@ -1227,18 +1233,18 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
        /* XXX check height as well... */
 
        if (!IS_ALIGNED(pitch, pitch_align)) {
-               dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
-                        __func__, __LINE__, pitch);
+               dev_warn(p->dev, "%s:%d tex pitch (%d, 0x%x, %d) invalid\n",
+                        __func__, __LINE__, pitch, pitch_align, G_038000_TILE_MODE(word0));
                return -EINVAL;
        }
        if (!IS_ALIGNED(base_offset, base_align)) {
-               dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n",
-                        __func__, __LINE__, base_offset);
+               dev_warn(p->dev, "%s:%d tex base offset (0x%llx, 0x%llx, %d) invalid\n",
+                        __func__, __LINE__, base_offset, base_align, G_038000_TILE_MODE(word0));
                return -EINVAL;
        }
        if (!IS_ALIGNED(mip_offset, base_align)) {
-               dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n",
-                        __func__, __LINE__, mip_offset);
+               dev_warn(p->dev, "%s:%d tex mip offset (0x%llx, 0x%llx, %d) invalid\n",
+                        __func__, __LINE__, mip_offset, base_align, G_038000_TILE_MODE(word0));
                return -EINVAL;
        }
 
index a5d898b..04bac0b 100644 (file)
 #define                ROQ_IB2_START(x)                                ((x) << 8)
 #define        CP_RB_BASE                                      0xC100
 #define        CP_RB_CNTL                                      0xC104
-#define                RB_BUFSZ(x)                                     ((x)<<0)
-#define                RB_BLKSZ(x)                                     ((x)<<8)
-#define                RB_NO_UPDATE                                    (1<<27)
-#define                RB_RPTR_WR_ENA                                  (1<<31)
+#define                RB_BUFSZ(x)                                     ((x) << 0)
+#define                RB_BLKSZ(x)                                     ((x) << 8)
+#define                RB_NO_UPDATE                                    (1 << 27)
+#define                RB_RPTR_WR_ENA                                  (1 << 31)
 #define                BUF_SWAP_32BIT                                  (2 << 16)
 #define        CP_RB_RPTR                                      0x8700
 #define        CP_RB_RPTR_ADDR                                 0xC10C
+#define                RB_RPTR_SWAP(x)                                 ((x) << 0)
 #define        CP_RB_RPTR_ADDR_HI                              0xC110
 #define        CP_RB_RPTR_WR                                   0xC108
 #define        CP_RB_WPTR                                      0xC114
index 5c1cc7a..02d5c41 100644 (file)
@@ -88,7 +88,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
                        /* some evergreen boards have bad data for this entry */
                        if (ASIC_IS_DCE4(rdev)) {
                                if ((i == 7) &&
-                                   (gpio->usClkMaskRegisterIndex == 0x1936) &&
+                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
                                    (gpio->sucI2cId.ucAccess == 0)) {
                                        gpio->sucI2cId.ucAccess = 0x97;
                                        gpio->ucDataMaskShift = 8;
@@ -101,7 +101,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
                        /* some DCE3 boards have bad data for this entry */
                        if (ASIC_IS_DCE3(rdev)) {
                                if ((i == 4) &&
-                                   (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
                                    (gpio->sucI2cId.ucAccess == 0x94))
                                        gpio->sucI2cId.ucAccess = 0x14;
                        }
@@ -172,7 +172,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
                        /* some evergreen boards have bad data for this entry */
                        if (ASIC_IS_DCE4(rdev)) {
                                if ((i == 7) &&
-                                   (gpio->usClkMaskRegisterIndex == 0x1936) &&
+                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
                                    (gpio->sucI2cId.ucAccess == 0)) {
                                        gpio->sucI2cId.ucAccess = 0x97;
                                        gpio->ucDataMaskShift = 8;
@@ -185,7 +185,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
                        /* some DCE3 boards have bad data for this entry */
                        if (ASIC_IS_DCE3(rdev)) {
                                if ((i == 4) &&
-                                   (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
                                    (gpio->sucI2cId.ucAccess == 0x94))
                                        gpio->sucI2cId.ucAccess = 0x14;
                        }
@@ -252,7 +252,7 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd
                        pin = &gpio_info->asGPIO_Pin[i];
                        if (id == pin->ucGPIO_ID) {
                                gpio.id = pin->ucGPIO_ID;
-                               gpio.reg = pin->usGpioPin_AIndex * 4;
+                               gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4;
                                gpio.mask = (1 << pin->ucGpioPinBitShift);
                                gpio.valid = true;
                                break;
@@ -1274,11 +1274,11 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)
                                      data_offset);
                switch (crev) {
                case 1:
-                       if (igp_info->info.ulBootUpMemoryClock)
+                       if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock))
                                return true;
                        break;
                case 2:
-                       if (igp_info->info_2.ulBootUpSidePortClock)
+                       if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock))
                                return true;
                        break;
                default:
@@ -1442,7 +1442,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
 
                        for (i = 0; i < num_indices; i++) {
                                if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) &&
-                                   (clock <= ss_info->info.asSpreadSpectrum[i].ulTargetClockRange)) {
+                                   (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) {
                                        ss->percentage =
                                                le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage);
                                        ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode;
@@ -1456,7 +1456,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
                                sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);
                        for (i = 0; i < num_indices; i++) {
                                if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) &&
-                                   (clock <= ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange)) {
+                                   (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) {
                                        ss->percentage =
                                                le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage);
                                        ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode;
@@ -1470,7 +1470,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
                                sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
                        for (i = 0; i < num_indices; i++) {
                                if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) &&
-                                   (clock <= ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange)) {
+                                   (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) {
                                        ss->percentage =
                                                le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage);
                                        ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode;
@@ -1553,8 +1553,8 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
                if (misc & ATOM_DOUBLE_CLOCK_MODE)
                        lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;
 
-               lvds->native_mode.width_mm = lvds_info->info.sLCDTiming.usImageHSize;
-               lvds->native_mode.height_mm = lvds_info->info.sLCDTiming.usImageVSize;
+               lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize);
+               lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize);
 
                /* set crtc values */
                drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
@@ -1569,13 +1569,13 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
                        lvds->linkb = false;
 
                /* parse the lcd record table */
-               if (lvds_info->info.usModePatchTableOffset) {
+               if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) {
                        ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record;
                        ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record;
                        bool bad_record = false;
                        u8 *record = (u8 *)(mode_info->atom_context->bios +
                                            data_offset +
-                                           lvds_info->info.usModePatchTableOffset);
+                                           le16_to_cpu(lvds_info->info.usModePatchTableOffset));
                        while (*record != ATOM_RECORD_END_TYPE) {
                                switch (*record) {
                                case LCD_MODE_PATCH_RECORD_MODE_TYPE:
@@ -2189,7 +2189,7 @@ static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev)
                firmware_info =
                        (union firmware_info *)(mode_info->atom_context->bios +
                                                data_offset);
-               vddc = firmware_info->info_14.usBootUpVDDCVoltage;
+               vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
        }
 
        return vddc;
@@ -2284,7 +2284,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
                rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
                        VOLTAGE_SW;
                rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
-                       clock_info->evergreen.usVDDC;
+                       le16_to_cpu(clock_info->evergreen.usVDDC);
        } else {
                sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
                sclk |= clock_info->r600.ucEngineClockHigh << 16;
@@ -2295,7 +2295,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
                rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
                        VOLTAGE_SW;
                rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
-                       clock_info->r600.usVDDC;
+                       le16_to_cpu(clock_info->r600.usVDDC);
        }
 
        if (rdev->flags & RADEON_IS_IGP) {
@@ -2408,13 +2408,13 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
        radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
        state_array = (struct StateArray *)
                (mode_info->atom_context->bios + data_offset +
-                power_info->pplib.usStateArrayOffset);
+                le16_to_cpu(power_info->pplib.usStateArrayOffset));
        clock_info_array = (struct ClockInfoArray *)
                (mode_info->atom_context->bios + data_offset +
-                power_info->pplib.usClockInfoArrayOffset);
+                le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
        non_clock_info_array = (struct NonClockInfoArray *)
                (mode_info->atom_context->bios + data_offset +
-                power_info->pplib.usNonClockInfoArrayOffset);
+                le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
        rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
                                       state_array->ucNumEntries, GFP_KERNEL);
        if (!rdev->pm.power_state)
@@ -2533,7 +2533,7 @@ uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev)
        int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-       return args.ulReturnEngineClock;
+       return le32_to_cpu(args.ulReturnEngineClock);
 }
 
 uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev)
@@ -2542,7 +2542,7 @@ uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev)
        int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-       return args.ulReturnMemoryClock;
+       return le32_to_cpu(args.ulReturnMemoryClock);
 }
 
 void radeon_atom_set_engine_clock(struct radeon_device *rdev,
@@ -2551,7 +2551,7 @@ void radeon_atom_set_engine_clock(struct radeon_device *rdev,
        SET_ENGINE_CLOCK_PS_ALLOCATION args;
        int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock);
 
-       args.ulTargetEngineClock = eng_clock;   /* 10 khz */
+       args.ulTargetEngineClock = cpu_to_le32(eng_clock);      /* 10 khz */
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
@@ -2565,7 +2565,7 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev,
        if (rdev->flags & RADEON_IS_IGP)
                return;
 
-       args.ulTargetMemoryClock = mem_clock;   /* 10 khz */
+       args.ulTargetMemoryClock = cpu_to_le32(mem_clock);      /* 10 khz */
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
index d27ef74..cf7c8d5 100644 (file)
@@ -1504,6 +1504,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                           (rdev->pdev->subsystem_device == 0x4a48)) {
                        /* Mac X800 */
                        rdev->mode_info.connector_table = CT_MAC_X800;
+               } else if ((rdev->pdev->device == 0x4150) &&
+                          (rdev->pdev->subsystem_vendor == 0x1002) &&
+                          (rdev->pdev->subsystem_device == 0x4150)) {
+                       /* Mac G5 9600 */
+                       rdev->mode_info.connector_table = CT_MAC_G5_9600;
                } else
 #endif /* CONFIG_PPC_PMAC */
 #ifdef CONFIG_PPC64
@@ -2022,6 +2027,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
                                            CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
                                            &hpd);
                break;
+       case CT_MAC_G5_9600:
+               DRM_INFO("Connector Table: %d (mac g5 9600)\n",
+                        rdev->mode_info.connector_table);
+               /* DVI - tv dac, dvo */
+               ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
+               hpd.hpd = RADEON_HPD_1; /* ??? */
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_DFP2_SUPPORT,
+                                                                 0),
+                                         ATOM_DEVICE_DFP2_SUPPORT);
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_CRT2_SUPPORT,
+                                                                 2),
+                                         ATOM_DEVICE_CRT2_SUPPORT);
+               radeon_add_legacy_connector(dev, 0,
+                                           ATOM_DEVICE_DFP2_SUPPORT |
+                                           ATOM_DEVICE_CRT2_SUPPORT,
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                           &hpd);
+               /* ADC - primary dac, internal tmds */
+               ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
+               hpd.hpd = RADEON_HPD_2; /* ??? */
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_DFP1_SUPPORT,
+                                                                 0),
+                                         ATOM_DEVICE_DFP1_SUPPORT);
+               radeon_add_legacy_encoder(dev,
+                                         radeon_get_encoder_enum(dev,
+                                                                 ATOM_DEVICE_CRT1_SUPPORT,
+                                                                 1),
+                                         ATOM_DEVICE_CRT1_SUPPORT);
+               radeon_add_legacy_connector(dev, 1,
+                                           ATOM_DEVICE_DFP1_SUPPORT |
+                                           ATOM_DEVICE_CRT1_SUPPORT,
+                                           DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
+                                           CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+                                           &hpd);
+               break;
        default:
                DRM_INFO("Connector table: %d (invalid)\n",
                         rdev->mode_info.connector_table);
index 0d47893..4954e2d 100644 (file)
@@ -936,8 +936,11 @@ int radeon_resume_kms(struct drm_device *dev)
 int radeon_gpu_reset(struct radeon_device *rdev)
 {
        int r;
+       int resched;
 
        radeon_save_bios_scratch_regs(rdev);
+       /* block TTM */
+       resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
        radeon_suspend(rdev);
 
        r = radeon_asic_reset(rdev);
@@ -946,6 +949,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
                radeon_resume(rdev);
                radeon_restore_bios_scratch_regs(rdev);
                drm_helper_resume_force_mode(rdev->ddev);
+               ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
                return 0;
        }
        /* bad news, how to tell it to userspace ? */
index 2eff98c..0e65709 100644 (file)
@@ -793,6 +793,11 @@ static void avivo_get_fb_div(struct radeon_pll *pll,
        tmp *= target_clock;
        *fb_div = tmp / pll->reference_freq;
        *frac_fb_div = tmp % pll->reference_freq;
+
+        if (*fb_div > pll->max_feedback_div)
+               *fb_div = pll->max_feedback_div;
+        else if (*fb_div < pll->min_feedback_div)
+                *fb_div = pll->min_feedback_div;
 }
 
 static u32 avivo_get_post_div(struct radeon_pll *pll,
@@ -826,6 +831,11 @@ static u32 avivo_get_post_div(struct radeon_pll *pll,
                        post_div--;
        }
 
+       if (post_div > pll->max_post_div)
+               post_div = pll->max_post_div;
+       else if (post_div < pll->min_post_div)
+               post_div = pll->min_post_div;
+
        return post_div;
 }
 
index 448eba8..5cba46b 100644 (file)
@@ -1524,6 +1524,7 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
 #define R600_CP_RB_CNTL                                        0xc104
 #       define R600_RB_BUFSZ(x)                                ((x) << 0)
 #       define R600_RB_BLKSZ(x)                                ((x) << 8)
+#      define R600_BUF_SWAP_32BIT                             (2 << 16)
 #       define R600_RB_NO_UPDATE                               (1 << 27)
 #       define R600_RB_RPTR_WR_ENA                             (1 << 31)
 #define R600_CP_RB_RPTR_WR                                     0xc108
index d4a5422..b427488 100644 (file)
@@ -910,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
 
        args.v1.ucAction = action;
        if (action == ATOM_TRANSMITTER_ACTION_INIT) {
-               args.v1.usInitInfo = connector_object_id;
+               args.v1.usInitInfo = cpu_to_le16(connector_object_id);
        } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
                args.v1.asMode.ucLaneSel = lane_num;
                args.v1.asMode.ucLaneSet = lane_set;
@@ -1140,7 +1140,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
                case 3:
                        args.v3.sExtEncoder.ucAction = action;
                        if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
-                               args.v3.sExtEncoder.usConnectorId = connector_object_id;
+                               args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id);
                        else
                                args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
                        args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
@@ -1570,11 +1570,21 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
        }
 
        /* set scaler clears this on some chips */
-       /* XXX check DCE4 */
-       if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) {
-               if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
-                       WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
-                              AVIVO_D1MODE_INTERLEAVE_EN);
+       if (ASIC_IS_AVIVO(rdev) &&
+           (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {
+               if (ASIC_IS_DCE4(rdev)) {
+                       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+                               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
+                                      EVERGREEN_INTERLEAVE_EN);
+                       else
+                               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
+               } else {
+                       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+                               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
+                                      AVIVO_D1MODE_INTERLEAVE_EN);
+                       else
+                               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
+               }
        }
 }
 
index 6794cdf..a670caa 100644 (file)
@@ -209,6 +209,7 @@ enum radeon_connector_table {
        CT_EMAC,
        CT_RN50_POWER,
        CT_MAC_X800,
+       CT_MAC_G5_9600,
 };
 
 enum radeon_dvo_chip {
index 1272e4b..e5b2cf1 100644 (file)
@@ -787,9 +787,9 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
                radeon_mem_types_list[i].show = &radeon_mm_dump_table;
                radeon_mem_types_list[i].driver_features = 0;
                if (i == 0)
-                       radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].priv;
+                       radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv;
                else
-                       radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].priv;
+                       radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv;
 
        }
        /* Add ttm page pool to debugfs */
index b506ec1..e8a1786 100644 (file)
@@ -683,9 +683,7 @@ r300 0x4f60
 0x4DF4 US_ALU_CONST_G_31
 0x4DF8 US_ALU_CONST_B_31
 0x4DFC US_ALU_CONST_A_31
-0x4E04 RB3D_BLENDCNTL_R3
 0x4E08 RB3D_ABLENDCNTL_R3
-0x4E0C RB3D_COLOR_CHANNEL_MASK
 0x4E10 RB3D_CONSTANT_COLOR
 0x4E14 RB3D_COLOR_CLEAR_VALUE
 0x4E18 RB3D_ROPCNTL_R3
@@ -706,13 +704,11 @@ r300 0x4f60
 0x4E74 RB3D_CMASK_WRINDEX
 0x4E78 RB3D_CMASK_DWORD
 0x4E7C RB3D_CMASK_RDINDEX
-0x4E80 RB3D_AARESOLVE_OFFSET
-0x4E84 RB3D_AARESOLVE_PITCH
-0x4E88 RB3D_AARESOLVE_CTL
 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
 0x4F04 ZB_ZSTENCILCNTL
 0x4F08 ZB_STENCILREFMASK
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
+0x4F28 ZB_DEPTHCLEARVALUE
 0x4F58 ZB_ZPASS_DATA
index 8c1214c..722074e 100644 (file)
@@ -130,7 +130,6 @@ r420 0x4f60
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
-0x4028 GB_Z_PEQ_CONFIG
 0x4100 TX_INVALTAGS
 0x4200 GA_POINT_S0
 0x4204 GA_POINT_T0
@@ -750,9 +749,7 @@ r420 0x4f60
 0x4DF4 US_ALU_CONST_G_31
 0x4DF8 US_ALU_CONST_B_31
 0x4DFC US_ALU_CONST_A_31
-0x4E04 RB3D_BLENDCNTL_R3
 0x4E08 RB3D_ABLENDCNTL_R3
-0x4E0C RB3D_COLOR_CHANNEL_MASK
 0x4E10 RB3D_CONSTANT_COLOR
 0x4E14 RB3D_COLOR_CLEAR_VALUE
 0x4E18 RB3D_ROPCNTL_R3
@@ -773,13 +770,11 @@ r420 0x4f60
 0x4E74 RB3D_CMASK_WRINDEX
 0x4E78 RB3D_CMASK_DWORD
 0x4E7C RB3D_CMASK_RDINDEX
-0x4E80 RB3D_AARESOLVE_OFFSET
-0x4E84 RB3D_AARESOLVE_PITCH
-0x4E88 RB3D_AARESOLVE_CTL
 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
 0x4F04 ZB_ZSTENCILCNTL
 0x4F08 ZB_STENCILREFMASK
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
+0x4F28 ZB_DEPTHCLEARVALUE
 0x4F58 ZB_ZPASS_DATA
index 0828d80..d9f6286 100644 (file)
@@ -749,9 +749,7 @@ rs600 0x6d40
 0x4DF4 US_ALU_CONST_G_31
 0x4DF8 US_ALU_CONST_B_31
 0x4DFC US_ALU_CONST_A_31
-0x4E04 RB3D_BLENDCNTL_R3
 0x4E08 RB3D_ABLENDCNTL_R3
-0x4E0C RB3D_COLOR_CHANNEL_MASK
 0x4E10 RB3D_CONSTANT_COLOR
 0x4E14 RB3D_COLOR_CLEAR_VALUE
 0x4E18 RB3D_ROPCNTL_R3
@@ -772,13 +770,11 @@ rs600 0x6d40
 0x4E74 RB3D_CMASK_WRINDEX
 0x4E78 RB3D_CMASK_DWORD
 0x4E7C RB3D_CMASK_RDINDEX
-0x4E80 RB3D_AARESOLVE_OFFSET
-0x4E84 RB3D_AARESOLVE_PITCH
-0x4E88 RB3D_AARESOLVE_CTL
 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
 0x4F04 ZB_ZSTENCILCNTL
 0x4F08 ZB_STENCILREFMASK
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
+0x4F28 ZB_DEPTHCLEARVALUE
 0x4F58 ZB_ZPASS_DATA
index ef422bb..911a8fb 100644 (file)
@@ -164,7 +164,6 @@ rv515 0x6d40
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
-0x4028 GB_Z_PEQ_CONFIG
 0x4100 TX_INVALTAGS
 0x4114 SU_TEX_WRAP_PS3
 0x4118 PS3_ENABLE
@@ -461,9 +460,7 @@ rv515 0x6d40
 0x4DF4 US_ALU_CONST_G_31
 0x4DF8 US_ALU_CONST_B_31
 0x4DFC US_ALU_CONST_A_31
-0x4E04 RB3D_BLENDCNTL_R3
 0x4E08 RB3D_ABLENDCNTL_R3
-0x4E0C RB3D_COLOR_CHANNEL_MASK
 0x4E10 RB3D_CONSTANT_COLOR
 0x4E14 RB3D_COLOR_CLEAR_VALUE
 0x4E18 RB3D_ROPCNTL_R3
@@ -484,9 +481,6 @@ rv515 0x6d40
 0x4E74 RB3D_CMASK_WRINDEX
 0x4E78 RB3D_CMASK_DWORD
 0x4E7C RB3D_CMASK_RDINDEX
-0x4E80 RB3D_AARESOLVE_OFFSET
-0x4E84 RB3D_AARESOLVE_PITCH
-0x4E88 RB3D_AARESOLVE_CTL
 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
 0x4EF8 RB3D_CONSTANT_COLOR_AR
@@ -496,4 +490,5 @@ rv515 0x6d40
 0x4F14 ZB_ZTOP
 0x4F18 ZB_ZCACHE_CTLSTAT
 0x4F58 ZB_ZPASS_DATA
+0x4F28 ZB_DEPTHCLEARVALUE
 0x4FD4 ZB_STENCILREFMASK_BF
index 0137d3e..6638c8e 100644 (file)
@@ -77,9 +77,9 @@ void rs690_pm_info(struct radeon_device *rdev)
                switch (crev) {
                case 1:
                        tmp.full = dfixed_const(100);
-                       rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info.ulBootUpMemoryClock);
+                       rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info.ulBootUpMemoryClock));
                        rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp);
-                       if (info->info.usK8MemoryClock)
+                       if (le16_to_cpu(info->info.usK8MemoryClock))
                                rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock));
                        else if (rdev->clock.default_mclk) {
                                rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk);
@@ -91,16 +91,16 @@ void rs690_pm_info(struct radeon_device *rdev)
                        break;
                case 2:
                        tmp.full = dfixed_const(100);
-                       rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info_v2.ulBootUpSidePortClock);
+                       rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpSidePortClock));
                        rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp);
-                       if (info->info_v2.ulBootUpUMAClock)
-                               rdev->pm.igp_system_mclk.full = dfixed_const(info->info_v2.ulBootUpUMAClock);
+                       if (le32_to_cpu(info->info_v2.ulBootUpUMAClock))
+                               rdev->pm.igp_system_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpUMAClock));
                        else if (rdev->clock.default_mclk)
                                rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk);
                        else
                                rdev->pm.igp_system_mclk.full = dfixed_const(66700);
                        rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp);
-                       rdev->pm.igp_ht_link_clk.full = dfixed_const(info->info_v2.ulHTLinkFreq);
+                       rdev->pm.igp_ht_link_clk.full = dfixed_const(le32_to_cpu(info->info_v2.ulHTLinkFreq));
                        rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp);
                        rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth));
                        break;
index 2211a32..d8ba676 100644 (file)
@@ -321,7 +321,11 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev)
                return -EINVAL;
 
        r700_cp_stop(rdev);
-       WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0));
+       WREG32(CP_RB_CNTL,
+#ifdef __BIG_ENDIAN
+              BUF_SWAP_32BIT |
+#endif
+              RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
 
        /* Reset cp */
        WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
index abc8cf5..79fa588 100644 (file)
 #define                ROQ_IB1_START(x)                                ((x) << 0)
 #define                ROQ_IB2_START(x)                                ((x) << 8)
 #define        CP_RB_CNTL                                      0xC104
-#define                RB_BUFSZ(x)                                     ((x)<<0)
-#define                RB_BLKSZ(x)                                     ((x)<<8)
-#define                RB_NO_UPDATE                                    (1<<27)
-#define                RB_RPTR_WR_ENA                                  (1<<31)
+#define                RB_BUFSZ(x)                                     ((x) << 0)
+#define                RB_BLKSZ(x)                                     ((x) << 8)
+#define                RB_NO_UPDATE                                    (1 << 27)
+#define                RB_RPTR_WR_ENA                                  (1 << 31)
 #define                BUF_SWAP_32BIT                                  (2 << 16)
 #define        CP_RB_RPTR                                      0x8700
 #define        CP_RB_RPTR_ADDR                                 0xC10C
index 5dea9fa..cd2a6e4 100644 (file)
@@ -344,7 +344,7 @@ static int emc1403_remove(struct i2c_client *client)
 }
 
 static const unsigned short emc1403_address_list[] = {
-       0x18, 0x2a, 0x4c, 0x4d, I2C_CLIENT_END
+       0x18, 0x29, 0x4c, 0x4d, I2C_CLIENT_END
 };
 
 static const struct i2c_device_id emc1403_idtable[] = {
index 776aeb3..508cb29 100644 (file)
@@ -98,6 +98,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
  * value, it uses signed 8-bit values with LSB = 1 degree Celsius.
  * For remote temperature, low and high limits, it uses signed 11-bit values
  * with LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
+ * For LM64 the actual remote diode temperature is 16 degree Celsius higher
+ * than the register reading. Remote temperature setpoints have to be
+ * adapted accordingly.
  */
 
 #define FAN_FROM_REG(reg)      ((reg) == 0xFFFC || (reg) == 0 ? 0 : \
@@ -165,6 +168,8 @@ struct lm63_data {
        struct mutex update_lock;
        char valid; /* zero until following fields are valid */
        unsigned long last_updated; /* in jiffies */
+       int kind;
+       int temp2_offset;
 
        /* registers values */
        u8 config, config_fan;
@@ -247,16 +252,34 @@ static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dum
        return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
 }
 
-static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
-                         char *buf)
+/*
+ * There are 8bit registers for both local(temp1) and remote(temp2) sensor.
+ * For remote sensor registers temp2_offset has to be considered,
+ * for local sensor it must not.
+ * So we need separate 8bit accessors for local and remote sensor.
+ */
+static ssize_t show_local_temp8(struct device *dev,
+                               struct device_attribute *devattr,
+                               char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct lm63_data *data = lm63_update_device(dev);
        return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]));
 }
 
-static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy,
-                        const char *buf, size_t count)
+static ssize_t show_remote_temp8(struct device *dev,
+                                struct device_attribute *devattr,
+                                char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct lm63_data *data = lm63_update_device(dev);
+       return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])
+                      + data->temp2_offset);
+}
+
+static ssize_t set_local_temp8(struct device *dev,
+                              struct device_attribute *dummy,
+                              const char *buf, size_t count)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct lm63_data *data = i2c_get_clientdata(client);
@@ -274,7 +297,8 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct lm63_data *data = lm63_update_device(dev);
-       return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]));
+       return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index])
+                      + data->temp2_offset);
 }
 
 static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
@@ -294,7 +318,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
        int nr = attr->index;
 
        mutex_lock(&data->update_lock);
-       data->temp11[nr] = TEMP11_TO_REG(val);
+       data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset);
        i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
                                  data->temp11[nr] >> 8);
        i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
@@ -310,6 +334,7 @@ static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute
 {
        struct lm63_data *data = lm63_update_device(dev);
        return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2])
+                      + data->temp2_offset
                       - TEMP8_FROM_REG(data->temp2_crit_hyst));
 }
 
@@ -324,7 +349,7 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *
        long hyst;
 
        mutex_lock(&data->update_lock);
-       hyst = TEMP8_FROM_REG(data->temp8[2]) - val;
+       hyst = TEMP8_FROM_REG(data->temp8[2]) + data->temp2_offset - val;
        i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
                                  HYST_TO_REG(hyst));
        mutex_unlock(&data->update_lock);
@@ -355,16 +380,21 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
 static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1);
 static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
 
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
-       set_temp8, 1);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8,
+       set_local_temp8, 1);
 
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
        set_temp11, 1);
 static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
        set_temp11, 2);
-static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
+/*
+ * On LM63, temp2_crit can be set only once, which should be job
+ * of the bootloader.
+ */
+static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8,
+       NULL, 2);
 static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
        set_temp2_crit_hyst);
 
@@ -479,7 +509,12 @@ static int lm63_probe(struct i2c_client *new_client,
        data->valid = 0;
        mutex_init(&data->update_lock);
 
-       /* Initialize the LM63 chip */
+       /* Set the device type */
+       data->kind = id->driver_data;
+       if (data->kind == lm64)
+               data->temp2_offset = 16000;
+
+       /* Initialize chip */
        lm63_init_client(new_client);
 
        /* Register sysfs hooks */
index 7985114..11905b6 100644 (file)
@@ -75,7 +75,6 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
  * dev->event_lock held and interrupts disabled.
  */
 static void input_pass_event(struct input_dev *dev,
-                            struct input_handler *src_handler,
                             unsigned int type, unsigned int code, int value)
 {
        struct input_handler *handler;
@@ -94,15 +93,6 @@ static void input_pass_event(struct input_dev *dev,
                                continue;
 
                        handler = handle->handler;
-
-                       /*
-                        * If this is the handler that injected this
-                        * particular event we want to skip it to avoid
-                        * filters firing again and again.
-                        */
-                       if (handler == src_handler)
-                               continue;
-
                        if (!handler->filter) {
                                if (filtered)
                                        break;
@@ -132,7 +122,7 @@ static void input_repeat_key(unsigned long data)
        if (test_bit(dev->repeat_key, dev->key) &&
            is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
 
-               input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2);
+               input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
 
                if (dev->sync) {
                        /*
@@ -141,7 +131,7 @@ static void input_repeat_key(unsigned long data)
                         * Otherwise assume that the driver will send
                         * SYN_REPORT once it's done.
                         */
-                       input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
                }
 
                if (dev->rep[REP_PERIOD])
@@ -174,7 +164,6 @@ static void input_stop_autorepeat(struct input_dev *dev)
 #define INPUT_PASS_TO_ALL      (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
 
 static int input_handle_abs_event(struct input_dev *dev,
-                                 struct input_handler *src_handler,
                                  unsigned int code, int *pval)
 {
        bool is_mt_event;
@@ -218,15 +207,13 @@ static int input_handle_abs_event(struct input_dev *dev,
        /* Flush pending "slot" event */
        if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
                input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
-               input_pass_event(dev, src_handler,
-                                EV_ABS, ABS_MT_SLOT, dev->slot);
+               input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
        }
 
        return INPUT_PASS_TO_HANDLERS;
 }
 
 static void input_handle_event(struct input_dev *dev,
-                              struct input_handler *src_handler,
                               unsigned int type, unsigned int code, int value)
 {
        int disposition = INPUT_IGNORE_EVENT;
@@ -279,8 +266,7 @@ static void input_handle_event(struct input_dev *dev,
 
        case EV_ABS:
                if (is_event_supported(code, dev->absbit, ABS_MAX))
-                       disposition = input_handle_abs_event(dev, src_handler,
-                                                            code, &value);
+                       disposition = input_handle_abs_event(dev, code, &value);
 
                break;
 
@@ -338,7 +324,7 @@ static void input_handle_event(struct input_dev *dev,
                dev->event(dev, type, code, value);
 
        if (disposition & INPUT_PASS_TO_HANDLERS)
-               input_pass_event(dev, src_handler, type, code, value);
+               input_pass_event(dev, type, code, value);
 }
 
 /**
@@ -367,7 +353,7 @@ void input_event(struct input_dev *dev,
 
                spin_lock_irqsave(&dev->event_lock, flags);
                add_input_randomness(type, code, value);
-               input_handle_event(dev, NULL, type, code, value);
+               input_handle_event(dev, type, code, value);
                spin_unlock_irqrestore(&dev->event_lock, flags);
        }
 }
@@ -397,8 +383,7 @@ void input_inject_event(struct input_handle *handle,
                rcu_read_lock();
                grab = rcu_dereference(dev->grab);
                if (!grab || grab == handle)
-                       input_handle_event(dev, handle->handler,
-                                          type, code, value);
+                       input_handle_event(dev, type, code, value);
                rcu_read_unlock();
 
                spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -611,10 +596,10 @@ static void input_dev_release_keys(struct input_dev *dev)
                for (code = 0; code <= KEY_MAX; code++) {
                        if (is_event_supported(code, dev->keybit, KEY_MAX) &&
                            __test_and_clear_bit(code, dev->key)) {
-                               input_pass_event(dev, NULL, EV_KEY, code, 0);
+                               input_pass_event(dev, EV_KEY, code, 0);
                        }
                }
-               input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+               input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
        }
 }
 
@@ -889,9 +874,9 @@ int input_set_keycode(struct input_dev *dev,
            !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
            __test_and_clear_bit(old_keycode, dev->key)) {
 
-               input_pass_event(dev, NULL, EV_KEY, old_keycode, 0);
+               input_pass_event(dev, EV_KEY, old_keycode, 0);
                if (dev->sync)
-                       input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
        }
 
  out:
index 1f8e010..7e64d01 100644 (file)
@@ -176,7 +176,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
 
        /* request the IRQs */
        err = request_irq(encoder->irq_a, &rotary_encoder_irq,
-                         IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+                         IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                          DRV_NAME, encoder);
        if (err) {
                dev_err(&pdev->dev, "unable to request IRQ %d\n",
@@ -185,7 +185,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
        }
 
        err = request_irq(encoder->irq_b, &rotary_encoder_irq,
-                         IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+                         IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                          DRV_NAME, encoder);
        if (err) {
                dev_err(&pdev->dev, "unable to request IRQ %d\n",
index db5b0bc..7c38d1f 100644 (file)
@@ -188,7 +188,8 @@ static void serio_free_event(struct serio_event *event)
        kfree(event);
 }
 
-static void serio_remove_duplicate_events(struct serio_event *event)
+static void serio_remove_duplicate_events(void *object,
+                                         enum serio_event_type type)
 {
        struct serio_event *e, *next;
        unsigned long flags;
@@ -196,13 +197,13 @@ static void serio_remove_duplicate_events(struct serio_event *event)
        spin_lock_irqsave(&serio_event_lock, flags);
 
        list_for_each_entry_safe(e, next, &serio_event_list, node) {
-               if (event->object == e->object) {
+               if (object == e->object) {
                        /*
                         * If this event is of different type we should not
                         * look further - we only suppress duplicate events
                         * that were sent back-to-back.
                         */
-                       if (event->type != e->type)
+                       if (type != e->type)
                                break;
 
                        list_del_init(&e->node);
@@ -245,7 +246,7 @@ static void serio_handle_event(struct work_struct *work)
                        break;
                }
 
-               serio_remove_duplicate_events(event);
+               serio_remove_duplicate_events(event->object, event->type);
                serio_free_event(event);
        }
 
@@ -436,10 +437,12 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
        } else if (!strncmp(buf, "rescan", count)) {
                serio_disconnect_port(serio);
                serio_find_driver(serio);
+               serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
        } else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
                serio_disconnect_port(serio);
                error = serio_bind_driver(serio, to_serio_driver(drv));
                put_driver(drv);
+               serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
        } else {
                error = -EINVAL;
        }
index fc38149..cf8fb9f 100644 (file)
@@ -519,7 +519,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        /* Retrieve the physical and logical size for OEM devices */
        error = wacom_retrieve_hid_descriptor(intf, features);
        if (error)
-               goto fail2;
+               goto fail3;
 
        wacom_setup_device_quirks(features);
 
index 14ea54b..4bf2316 100644 (file)
@@ -941,28 +941,29 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784
        struct ads7846_platform_data *pdata = spi->dev.platform_data;
        int err;
 
-       /* REVISIT when the irq can be triggered active-low, or if for some
+       /*
+        * REVISIT when the irq can be triggered active-low, or if for some
         * reason the touchscreen isn't hooked up, we don't need to access
         * the pendown state.
         */
-       if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) {
-               dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
-               return -EINVAL;
-       }
 
        if (pdata->get_pendown_state) {
                ts->get_pendown_state = pdata->get_pendown_state;
-               return 0;
-       }
+       } else if (gpio_is_valid(pdata->gpio_pendown)) {
 
-       err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
-       if (err) {
-               dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
-                       pdata->gpio_pendown);
-               return err;
-       }
+               err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
+               if (err) {
+                       dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
+                               pdata->gpio_pendown);
+                       return err;
+               }
 
-       ts->gpio_pendown = pdata->gpio_pendown;
+               ts->gpio_pendown = pdata->gpio_pendown;
+
+       } else {
+               dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
+               return -EINVAL;
+       }
 
        return 0;
 }
@@ -1353,7 +1354,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
  err_put_regulator:
        regulator_put(ts->reg);
  err_free_gpio:
-       if (ts->gpio_pendown != -1)
+       if (!ts->get_pendown_state)
                gpio_free(ts->gpio_pendown);
  err_cleanup_filter:
        if (ts->filter_cleanup)
@@ -1383,8 +1384,13 @@ static int __devexit ads7846_remove(struct spi_device *spi)
        regulator_disable(ts->reg);
        regulator_put(ts->reg);
 
-       if (ts->gpio_pendown != -1)
+       if (!ts->get_pendown_state) {
+               /*
+                * If we are not using specialized pendown method we must
+                * have been relying on gpio we set up ourselves.
+                */
                gpio_free(ts->gpio_pendown);
+       }
 
        if (ts->filter_cleanup)
                ts->filter_cleanup(ts->filter_data);
index 5cb8449..c14412e 100644 (file)
@@ -51,6 +51,10 @@ MODULE_LICENSE("GPL");
 #define W8001_PKTLEN_TPCCTL    11      /* control packet */
 #define W8001_PKTLEN_TOUCH2FG  13
 
+/* resolution in points/mm */
+#define W8001_PEN_RESOLUTION    100
+#define W8001_TOUCH_RESOLUTION  10
+
 struct w8001_coord {
        u8 rdy;
        u8 tsw;
@@ -198,7 +202,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
                query->y = 1024;
                if (query->panel_res)
                        query->x = query->y = (1 << query->panel_res);
-               query->panel_res = 10;
+               query->panel_res = W8001_TOUCH_RESOLUTION;
        }
 }
 
@@ -394,6 +398,8 @@ static int w8001_setup(struct w8001 *w8001)
 
                input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
                input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
+               input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION);
+               input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION);
                input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
                if (coord.tilt_x && coord.tilt_y) {
                        input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
@@ -418,14 +424,17 @@ static int w8001_setup(struct w8001 *w8001)
                w8001->max_touch_x = touch.x;
                w8001->max_touch_y = touch.y;
 
-               /* scale to pen maximum */
                if (w8001->max_pen_x && w8001->max_pen_y) {
+                       /* if pen is supported scale to pen maximum */
                        touch.x = w8001->max_pen_x;
                        touch.y = w8001->max_pen_y;
+                       touch.panel_res = W8001_PEN_RESOLUTION;
                }
 
                input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
                input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
+               input_abs_set_res(dev, ABS_X, touch.panel_res);
+               input_abs_set_res(dev, ABS_Y, touch.panel_res);
 
                switch (touch.sensor_id) {
                case 0:
index 729df40..18b801a 100644 (file)
@@ -227,7 +227,6 @@ extern hysdn_card *card_root;       /* pointer to first card */
 /*************************/
 /* im/exported functions */
 /*************************/
-extern char *hysdn_getrev(const char *);
 
 /* hysdn_procconf.c */
 extern int hysdn_procconf_init(void);  /* init proc config filesys */
@@ -259,7 +258,6 @@ extern int hysdn_tx_cfgline(hysdn_card *, unsigned char *,
 
 /* hysdn_net.c */
 extern unsigned int hynet_enable; 
-extern char *hysdn_net_revision;
 extern int hysdn_net_create(hysdn_card *);     /* create a new net device */
 extern int hysdn_net_release(hysdn_card *);    /* delete the device */
 extern char *hysdn_net_getname(hysdn_card *);  /* get name of net interface */
index b7cc5c2..0ab42ac 100644 (file)
@@ -36,7 +36,6 @@ MODULE_DESCRIPTION("ISDN4Linux: Driver for HYSDN cards");
 MODULE_AUTHOR("Werner Cornelius");
 MODULE_LICENSE("GPL");
 
-static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
 static int cardmax;            /* number of found cards */
 hysdn_card *card_root = NULL;  /* pointer to first card */
 static hysdn_card *card_last = NULL;   /* pointer to first card */
@@ -49,25 +48,6 @@ static hysdn_card *card_last = NULL; /* pointer to first card */
 /* Additionally newer versions may be activated without rebooting.          */
 /****************************************************************************/
 
-/******************************************************/
-/* extract revision number from string for log output */
-/******************************************************/
-char *
-hysdn_getrev(const char *revision)
-{
-       char *rev;
-       char *p;
-
-       if ((p = strchr(revision, ':'))) {
-               rev = p + 2;
-               p = strchr(rev, '$');
-               *--p = 0;
-       } else
-               rev = "???";
-       return rev;
-}
-
-
 /****************************************************************************/
 /* init_module is called once when the module is loaded to do all necessary */
 /* things like autodetect...                                                */
@@ -175,13 +155,9 @@ static int hysdn_have_procfs;
 static int __init
 hysdn_init(void)
 {
-       char tmp[50];
        int rc;
 
-       strcpy(tmp, hysdn_init_revision);
-       printk(KERN_NOTICE "HYSDN: module Rev: %s loaded\n", hysdn_getrev(tmp));
-       strcpy(tmp, hysdn_net_revision);
-       printk(KERN_NOTICE "HYSDN: network interface Rev: %s \n", hysdn_getrev(tmp));
+       printk(KERN_NOTICE "HYSDN: module loaded\n");
 
        rc = pci_register_driver(&hysdn_pci_driver);
        if (rc)
index feec8d8..11f2cce 100644 (file)
@@ -26,9 +26,6 @@
 unsigned int hynet_enable = 0xffffffff; 
 module_param(hynet_enable, uint, 0);
 
-/* store the actual version for log reporting */
-char *hysdn_net_revision = "$Revision: 1.8.6.4 $";
-
 #define MAX_SKB_BUFFERS 20     /* number of buffers for keeping TX-data */
 
 /****************************************************************************/
index 96b3e39..5fe83bd 100644 (file)
@@ -23,7 +23,6 @@
 #include "hysdn_defs.h"
 
 static DEFINE_MUTEX(hysdn_conf_mutex);
-static char *hysdn_procconf_revision = "$Revision: 1.8.6.4 $";
 
 #define INFO_OUT_LEN 80                /* length of info line including lf */
 
@@ -404,7 +403,7 @@ hysdn_procconf_init(void)
                card = card->next;      /* next entry */
        }
 
-       printk(KERN_NOTICE "HYSDN: procfs Rev. %s initialised\n", hysdn_getrev(hysdn_procconf_revision));
+       printk(KERN_NOTICE "HYSDN: procfs initialised\n");
        return (0);
 }                              /* hysdn_procconf_init */
 
index b76cfc8..0cc30ec 100644 (file)
@@ -287,6 +287,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
        mddev_t *mddev = q->queuedata;
        int rv;
        int cpu;
+       unsigned int sectors;
 
        if (mddev == NULL || mddev->pers == NULL
            || !mddev->ready) {
@@ -311,12 +312,16 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
        atomic_inc(&mddev->active_io);
        rcu_read_unlock();
 
+       /*
+        * save the sectors now since our bio can
+        * go away inside make_request
+        */
+       sectors = bio_sectors(bio);
        rv = mddev->pers->make_request(mddev, bio);
 
        cpu = part_stat_lock();
        part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
-       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
-                     bio_sectors(bio));
+       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors);
        part_stat_unlock();
 
        if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
@@ -1947,8 +1952,6 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
                        __bdevname(dev, b));
                return PTR_ERR(bdev);
        }
-       if (!shared)
-               set_bit(AllReserved, &rdev->flags);
        rdev->bdev = bdev;
        return err;
 }
@@ -2465,6 +2468,9 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                if (rdev->raid_disk != -1)
                        return -EBUSY;
 
+               if (test_bit(MD_RECOVERY_RUNNING, &rdev->mddev->recovery))
+                       return -EBUSY;
+
                if (rdev->mddev->pers->hot_add_disk == NULL)
                        return -EINVAL;
 
@@ -2610,12 +2616,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 
                        mddev_lock(mddev);
                        list_for_each_entry(rdev2, &mddev->disks, same_set)
-                               if (test_bit(AllReserved, &rdev2->flags) ||
-                                   (rdev->bdev == rdev2->bdev &&
-                                    rdev != rdev2 &&
-                                    overlaps(rdev->data_offset, rdev->sectors,
-                                             rdev2->data_offset,
-                                             rdev2->sectors))) {
+                               if (rdev->bdev == rdev2->bdev &&
+                                   rdev != rdev2 &&
+                                   overlaps(rdev->data_offset, rdev->sectors,
+                                            rdev2->data_offset,
+                                            rdev2->sectors)) {
                                        overlap = 1;
                                        break;
                                }
@@ -5578,6 +5583,8 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks)
        mddev->delta_disks = raid_disks - mddev->raid_disks;
 
        rv = mddev->pers->check_reshape(mddev);
+       if (rv < 0)
+               mddev->delta_disks = 0;
        return rv;
 }
 
@@ -6985,9 +6992,6 @@ void md_do_sync(mddev_t *mddev)
        } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
                mddev->resync_min = mddev->curr_resync_completed;
        mddev->curr_resync = 0;
-       if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
-               mddev->curr_resync_completed = 0;
-       sysfs_notify(&mddev->kobj, NULL, "sync_completed");
        wake_up(&resync_wait);
        set_bit(MD_RECOVERY_DONE, &mddev->recovery);
        md_wakeup_thread(mddev->thread);
@@ -7028,7 +7032,7 @@ static int remove_and_add_spares(mddev_t *mddev)
                        }
                }
 
-       if (mddev->degraded && ! mddev->ro && !mddev->recovery_disabled) {
+       if (mddev->degraded && !mddev->recovery_disabled) {
                list_for_each_entry(rdev, &mddev->disks, same_set) {
                        if (rdev->raid_disk >= 0 &&
                            !test_bit(In_sync, &rdev->flags) &&
@@ -7151,7 +7155,20 @@ void md_check_recovery(mddev_t *mddev)
                        /* Only thing we do on a ro array is remove
                         * failed devices.
                         */
-                       remove_and_add_spares(mddev);
+                       mdk_rdev_t *rdev;
+                       list_for_each_entry(rdev, &mddev->disks, same_set)
+                               if (rdev->raid_disk >= 0 &&
+                                   !test_bit(Blocked, &rdev->flags) &&
+                                   test_bit(Faulty, &rdev->flags) &&
+                                   atomic_read(&rdev->nr_pending)==0) {
+                                       if (mddev->pers->hot_remove_disk(
+                                                   mddev, rdev->raid_disk)==0) {
+                                               char nm[20];
+                                               sprintf(nm,"rd%d", rdev->raid_disk);
+                                               sysfs_remove_link(&mddev->kobj, nm);
+                                               rdev->raid_disk = -1;
+                                       }
+                               }
                        clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                        goto unlock;
                }
index eec517c..7e90b85 100644 (file)
@@ -93,8 +93,6 @@ struct mdk_rdev_s
 #define        Faulty          1               /* device is known to have a fault */
 #define        In_sync         2               /* device is in_sync with rest of array */
 #define        WriteMostly     4               /* Avoid reading if at all possible */
-#define        AllReserved     6               /* If whole device is reserved for
-                                        * one array */
 #define        AutoDetected    7               /* added by auto-detect */
 #define Blocked                8               /* An error occured on an externally
                                         * managed array, don't allow writes
index a39f4c3..637a968 100644 (file)
@@ -179,6 +179,14 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf)
                        rdev1->new_raid_disk = j;
                }
 
+               if (mddev->level == 1) {
+                       /* taiking over a raid1 array-
+                        * we have only one active disk
+                        */
+                       j = 0;
+                       rdev1->new_raid_disk = j;
+               }
+
                if (j < 0 || j >= mddev->raid_disks) {
                        printk(KERN_ERR "md/raid0:%s: bad disk number %d - "
                               "aborting!\n", mdname(mddev), j);
@@ -644,12 +652,38 @@ static void *raid0_takeover_raid10(mddev_t *mddev)
        return priv_conf;
 }
 
+static void *raid0_takeover_raid1(mddev_t *mddev)
+{
+       raid0_conf_t *priv_conf;
+
+       /* Check layout:
+        *  - (N - 1) mirror drives must be already faulty
+        */
+       if ((mddev->raid_disks - 1) != mddev->degraded) {
+               printk(KERN_ERR "md/raid0:%s: (N - 1) mirrors drives must be already faulty!\n",
+                      mdname(mddev));
+               return ERR_PTR(-EINVAL);
+       }
+
+       /* Set new parameters */
+       mddev->new_level = 0;
+       mddev->new_layout = 0;
+       mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */
+       mddev->delta_disks = 1 - mddev->raid_disks;
+       /* make sure it will be not marked as dirty */
+       mddev->recovery_cp = MaxSector;
+
+       create_strip_zones(mddev, &priv_conf);
+       return priv_conf;
+}
+
 static void *raid0_takeover(mddev_t *mddev)
 {
        /* raid0 can take over:
         *  raid4 - if all data disks are active.
         *  raid5 - providing it is Raid4 layout and one disk is faulty
         *  raid10 - assuming we have all necessary active disks
+        *  raid1 - with (N -1) mirror drives faulty
         */
        if (mddev->level == 4)
                return raid0_takeover_raid45(mddev);
@@ -665,6 +699,12 @@ static void *raid0_takeover(mddev_t *mddev)
        if (mddev->level == 10)
                return raid0_takeover_raid10(mddev);
 
+       if (mddev->level == 1)
+               return raid0_takeover_raid1(mddev);
+
+       printk(KERN_ERR "Takeover from raid%i to raid0 not supported\n",
+               mddev->level);
+
        return ERR_PTR(-EINVAL);
 }
 
index 69b6595..3b607b2 100644 (file)
@@ -2463,11 +2463,13 @@ static void *raid10_takeover_raid0(mddev_t *mddev)
        mddev->recovery_cp = MaxSector;
 
        conf = setup_conf(mddev);
-       if (!IS_ERR(conf))
+       if (!IS_ERR(conf)) {
                list_for_each_entry(rdev, &mddev->disks, same_set)
                        if (rdev->raid_disk >= 0)
                                rdev->new_raid_disk = rdev->raid_disk * 2;
-               
+               conf->barrier = 1;
+       }
+
        return conf;
 }
 
index 5044bab..7028128 100644 (file)
@@ -5517,7 +5517,6 @@ static int raid5_start_reshape(mddev_t *mddev)
        raid5_conf_t *conf = mddev->private;
        mdk_rdev_t *rdev;
        int spares = 0;
-       int added_devices = 0;
        unsigned long flags;
 
        if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
@@ -5527,8 +5526,8 @@ static int raid5_start_reshape(mddev_t *mddev)
                return -ENOSPC;
 
        list_for_each_entry(rdev, &mddev->disks, same_set)
-               if ((rdev->raid_disk < 0 || rdev->raid_disk >= conf->raid_disks)
-                    && !test_bit(Faulty, &rdev->flags))
+               if (!test_bit(In_sync, &rdev->flags)
+                   && !test_bit(Faulty, &rdev->flags))
                        spares++;
 
        if (spares - mddev->degraded < mddev->delta_disks - conf->max_degraded)
@@ -5571,34 +5570,35 @@ static int raid5_start_reshape(mddev_t *mddev)
         * to correctly record the "partially reconstructed" state of
         * such devices during the reshape and confusion could result.
         */
-       if (mddev->delta_disks >= 0)
-           list_for_each_entry(rdev, &mddev->disks, same_set)
-               if (rdev->raid_disk < 0 &&
-                   !test_bit(Faulty, &rdev->flags)) {
-                       if (raid5_add_disk(mddev, rdev) == 0) {
-                               char nm[20];
-                               if (rdev->raid_disk >= conf->previous_raid_disks) {
-                                       set_bit(In_sync, &rdev->flags);
-                                       added_devices++;
-                               } else
-                                       rdev->recovery_offset = 0;
-                               sprintf(nm, "rd%d", rdev->raid_disk);
-                               if (sysfs_create_link(&mddev->kobj,
-                                                     &rdev->kobj, nm))
-                                       /* Failure here is OK */;
-                       } else
-                               break;
-               } else if (rdev->raid_disk >= conf->previous_raid_disks
-                          && !test_bit(Faulty, &rdev->flags)) {
-                       /* This is a spare that was manually added */
-                       set_bit(In_sync, &rdev->flags);
-                       added_devices++;
-               }
+       if (mddev->delta_disks >= 0) {
+               int added_devices = 0;
+               list_for_each_entry(rdev, &mddev->disks, same_set)
+                       if (rdev->raid_disk < 0 &&
+                           !test_bit(Faulty, &rdev->flags)) {
+                               if (raid5_add_disk(mddev, rdev) == 0) {
+                                       char nm[20];
+                                       if (rdev->raid_disk
+                                           >= conf->previous_raid_disks) {
+                                               set_bit(In_sync, &rdev->flags);
+                                               added_devices++;
+                                       } else
+                                               rdev->recovery_offset = 0;
+                                       sprintf(nm, "rd%d", rdev->raid_disk);
+                                       if (sysfs_create_link(&mddev->kobj,
+                                                             &rdev->kobj, nm))
+                                               /* Failure here is OK */;
+                               }
+                       } else if (rdev->raid_disk >= conf->previous_raid_disks
+                                  && !test_bit(Faulty, &rdev->flags)) {
+                               /* This is a spare that was manually added */
+                               set_bit(In_sync, &rdev->flags);
+                               added_devices++;
+                       }
 
-       /* When a reshape changes the number of devices, ->degraded
-        * is measured against the larger of the pre and post number of
-        * devices.*/
-       if (mddev->delta_disks > 0) {
+               /* When a reshape changes the number of devices,
+                * ->degraded is measured against the larger of the
+                * pre and post number of devices.
+                */
                spin_lock_irqsave(&conf->device_lock, flags);
                mddev->degraded += (conf->raid_disks - conf->previous_raid_disks)
                        - added_devices;
index 0c7811f..a179cc6 100644 (file)
@@ -1786,6 +1786,10 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
        spin_lock_bh(&adapter->mcc_lock);
 
        wrb = wrb_from_mccq(adapter);
+       if (!wrb) {
+               status = -EBUSY;
+               goto err;
+       }
        req = nonemb_cmd->va;
        sge = nonembedded_sgl(wrb);
 
@@ -1801,6 +1805,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
 
        status = be_mcc_notify_wait(adapter);
 
+err:
        spin_unlock_bh(&adapter->mcc_lock);
        return status;
 }
index f40740e..d584d32 100644 (file)
@@ -4276,9 +4276,12 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
                def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
                                BNX2X_ACCEPT_MULTICAST;
 #ifdef BCM_CNIC
-               cl_id = bnx2x_fcoe(bp, cl_id);
-               bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
-                                         BNX2X_ACCEPT_MULTICAST);
+               if (!NO_FCOE(bp)) {
+                       cl_id = bnx2x_fcoe(bp, cl_id);
+                       bnx2x_rxq_set_mac_filters(bp, cl_id,
+                                                 BNX2X_ACCEPT_UNICAST |
+                                                 BNX2X_ACCEPT_MULTICAST);
+               }
 #endif
                break;
 
@@ -4286,18 +4289,29 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
                def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
                                BNX2X_ACCEPT_ALL_MULTICAST;
 #ifdef BCM_CNIC
-               cl_id = bnx2x_fcoe(bp, cl_id);
-               bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
-                                         BNX2X_ACCEPT_MULTICAST);
+               /*
+                *  Prevent duplication of multicast packets by configuring FCoE
+                *  L2 Client to receive only matched unicast frames.
+                */
+               if (!NO_FCOE(bp)) {
+                       cl_id = bnx2x_fcoe(bp, cl_id);
+                       bnx2x_rxq_set_mac_filters(bp, cl_id,
+                                                 BNX2X_ACCEPT_UNICAST);
+               }
 #endif
                break;
 
        case BNX2X_RX_MODE_PROMISC:
                def_q_filters |= BNX2X_PROMISCUOUS_MODE;
 #ifdef BCM_CNIC
-               cl_id = bnx2x_fcoe(bp, cl_id);
-               bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
-                                         BNX2X_ACCEPT_MULTICAST);
+               /*
+                *  Prevent packets duplication by configuring DROP_ALL for FCoE
+                *  L2 Client.
+                */
+               if (!NO_FCOE(bp)) {
+                       cl_id = bnx2x_fcoe(bp, cl_id);
+                       bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE);
+               }
 #endif
                /* pass management unicast packets as well */
                llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST;
index 27d1d39..d387069 100644 (file)
@@ -1,5 +1,5 @@
 config CAN_MSCAN
-       depends on CAN_DEV && (PPC || M68K || M68KNOMMU)
+       depends on CAN_DEV && (PPC || M68K)
        tristate "Support for Freescale MSCAN based chips"
        ---help---
          The Motorola Scalable Controller Area Network (MSCAN) definition
index c42e972..e54712b 100644 (file)
@@ -185,7 +185,7 @@ struct pch_can_priv {
 
 static struct can_bittiming_const pch_can_bittiming_const = {
        .name = KBUILD_MODNAME,
-       .tseg1_min = 1,
+       .tseg1_min = 2,
        .tseg1_max = 16,
        .tseg2_min = 1,
        .tseg2_max = 8,
@@ -959,13 +959,13 @@ static void __devexit pch_can_remove(struct pci_dev *pdev)
        struct pch_can_priv *priv = netdev_priv(ndev);
 
        unregister_candev(priv->ndev);
-       pci_iounmap(pdev, priv->regs);
        if (priv->use_msi)
                pci_disable_msi(priv->dev);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
        pch_can_reset(priv);
+       pci_iounmap(pdev, priv->regs);
        free_candev(priv->ndev);
 }
 
@@ -1238,6 +1238,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
                priv->use_msi = 0;
        } else {
                netdev_err(ndev, "PCH CAN opened with MSI\n");
+               pci_set_master(pdev);
                priv->use_msi = 1;
        }
 
index 300fe75..c11bb4d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
index aed223b..7501d97 100644 (file)
@@ -124,6 +124,7 @@ static s32 e1000_set_phy_type(struct e1000_hw *hw)
        case M88E1000_I_PHY_ID:
        case M88E1011_I_PHY_ID:
        case M88E1111_I_PHY_ID:
+       case M88E1118_E_PHY_ID:
                hw->phy_type = e1000_phy_m88;
                break;
        case IGP01E1000_I_PHY_ID:
@@ -3222,7 +3223,8 @@ static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
                break;
        case e1000_ce4100:
                if ((hw->phy_id == RTL8211B_PHY_ID) ||
-                   (hw->phy_id == RTL8201N_PHY_ID))
+                   (hw->phy_id == RTL8201N_PHY_ID) ||
+                   (hw->phy_id == M88E1118_E_PHY_ID))
                        match = true;
                break;
        case e1000_82541:
index 196eeda..c70b23d 100644 (file)
@@ -2917,6 +2917,7 @@ struct e1000_host_command_info {
 #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
 #define M88E1011_I_REV_4   0x04
 #define M88E1111_I_PHY_ID  0x01410CC0
+#define M88E1118_E_PHY_ID  0x01410E40
 #define L1LXT971A_PHY_ID   0x001378E0
 
 #define RTL8211B_PHY_ID    0x001CC910
index 1c18f26..3065870 100644 (file)
@@ -4309,7 +4309,6 @@ link_up:
                         * to get done, so reset controller to flush Tx.
                         * (Do the reset outside of interrupt context).
                         */
-                       adapter->tx_timeout_count++;
                        schedule_work(&adapter->reset_task);
                        /* return immediately since reset is imminent */
                        return;
index d5ede2d..ebbda7d 100644 (file)
@@ -1370,6 +1370,9 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
                hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr);
 
                hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+
+               /*  clear VMDq pool/queue selection for RAR 0 */
+               hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
        }
        hw->addr_ctrl.overflow_promisc = 0;
 
index 6342d48..8753980 100644 (file)
@@ -165,7 +165,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
        unsigned int thisoff = 0;
        unsigned int thislen = 0;
        u32 fcbuff, fcdmarw, fcfltrw;
-       dma_addr_t addr;
+       dma_addr_t addr = 0;
 
        if (!netdev || !sgl)
                return 0;
index 602078b..fbae703 100644 (file)
@@ -52,7 +52,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                              "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "3.0.12-k2"
+#define DRV_VERSION "3.2.9-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation.";
 
@@ -3176,9 +3176,16 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
        u32 mhadd, hlreg0;
 
        /* Decide whether to use packet split mode or not */
+       /* On by default */
+       adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
+
        /* Do not use packet split if we're in SR-IOV Mode */
-       if (!adapter->num_vfs)
-               adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
+       if (adapter->num_vfs)
+               adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+
+       /* Disable packet split due to 82599 erratum #45 */
+       if (hw->mac.type == ixgbe_mac_82599EB)
+               adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
 
        /* Set the RX buffer length according to the mode */
        if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
@@ -4863,16 +4870,13 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
 {
        int q_idx, num_q_vectors;
        struct ixgbe_q_vector *q_vector;
-       int napi_vectors;
        int (*poll)(struct napi_struct *, int);
 
        if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
                num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-               napi_vectors = adapter->num_rx_queues;
                poll = &ixgbe_clean_rxtx_many;
        } else {
                num_q_vectors = 1;
-               napi_vectors = 1;
                poll = &ixgbe_poll;
        }
 
index 47b1573..187b3a1 100644 (file)
@@ -110,12 +110,10 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
        return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
 }
 
-
 static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
 {
        u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
        vmolr |= (IXGBE_VMOLR_ROMPE |
-                 IXGBE_VMOLR_ROPE |
                  IXGBE_VMOLR_BAM);
        if (aupe)
                vmolr |= IXGBE_VMOLR_AUPE;
index 3a89239..f2518b0 100644 (file)
@@ -133,17 +133,17 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
        }
 
        ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
-       IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
+       IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | reset_bit));
        IXGBE_WRITE_FLUSH(hw);
 
        /* Poll for reset bit to self-clear indicating reset is complete */
        for (i = 0; i < 10; i++) {
                udelay(1);
                ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
-               if (!(ctrl & IXGBE_CTRL_RST))
+               if (!(ctrl & reset_bit))
                        break;
        }
-       if (ctrl & IXGBE_CTRL_RST) {
+       if (ctrl & reset_bit) {
                status = IXGBE_ERR_RESET_FAILED;
                hw_dbg(hw, "Reset polling failed to complete.\n");
        }
index 1bf1233..4c9a7d4 100644 (file)
@@ -519,7 +519,9 @@ static void pch_gbe_reset_task(struct work_struct *work)
        struct pch_gbe_adapter *adapter;
        adapter = container_of(work, struct pch_gbe_adapter, reset_task);
 
+       rtnl_lock();
        pch_gbe_reinit_locked(adapter);
+       rtnl_unlock();
 }
 
 /**
@@ -528,14 +530,8 @@ static void pch_gbe_reset_task(struct work_struct *work)
  */
 void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter)
 {
-       struct net_device *netdev = adapter->netdev;
-
-       rtnl_lock();
-       if (netif_running(netdev)) {
-               pch_gbe_down(adapter);
-               pch_gbe_up(adapter);
-       }
-       rtnl_unlock();
+       pch_gbe_down(adapter);
+       pch_gbe_up(adapter);
 }
 
 /**
index 5976d1d..640e368 100644 (file)
@@ -1777,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev)
                                              "cur_rx:%4.4d, dirty_rx:%4.4d\n",
                                              net_dev->name, sis_priv->cur_rx,
                                              sis_priv->dirty_rx);
+                               dev_kfree_skb(skb);
                                break;
                        }
 
index 04e8ce1..7113168 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * cdc_ncm.c
  *
- * Copyright (C) ST-Ericsson 2010
+ * Copyright (C) ST-Ericsson 2010-2011
  * Contact: Alexey Orishko <alexey.orishko@stericsson.com>
  * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com>
  *
@@ -54,7 +54,7 @@
 #include <linux/usb/usbnet.h>
 #include <linux/usb/cdc.h>
 
-#define        DRIVER_VERSION                          "17-Jan-2011"
+#define        DRIVER_VERSION                          "7-Feb-2011"
 
 /* CDC NCM subclass 3.2.1 */
 #define USB_CDC_NCM_NDP16_LENGTH_MIN           0x10
@@ -77,6 +77,9 @@
  */
 #define        CDC_NCM_DPT_DATAGRAMS_MAX               32
 
+/* Maximum amount of IN datagrams in NTB */
+#define        CDC_NCM_DPT_DATAGRAMS_IN_MAX            0 /* unlimited */
+
 /* Restart the timer, if amount of datagrams is less than given value */
 #define        CDC_NCM_RESTART_TIMER_DATAGRAM_CNT      3
 
        (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \
        (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16))
 
-struct connection_speed_change {
-       __le32  USBitRate; /* holds 3GPP downlink value, bits per second */
-       __le32  DSBitRate; /* holds 3GPP uplink value, bits per second */
-} __attribute__ ((packed));
-
 struct cdc_ncm_data {
        struct usb_cdc_ncm_nth16 nth16;
        struct usb_cdc_ncm_ndp16 ndp16;
@@ -198,10 +196,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
 {
        struct usb_cdc_notification req;
        u32 val;
-       __le16 max_datagram_size;
        u8 flags;
        u8 iface_no;
        int err;
+       u16 ntb_fmt_supported;
 
        iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
 
@@ -223,6 +221,9 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
        ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder);
        ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor);
        ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment);
+       /* devices prior to NCM Errata shall set this field to zero */
+       ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams);
+       ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported);
 
        if (ctx->func_desc != NULL)
                flags = ctx->func_desc->bmNetworkCapabilities;
@@ -231,22 +232,58 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
 
        pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u "
                 "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u "
-                "wNdpOutAlignment=%u flags=0x%x\n",
+                "wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n",
                 ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus,
-                ctx->tx_ndp_modulus, flags);
+                ctx->tx_ndp_modulus, ctx->tx_max_datagrams, flags);
 
-       /* max count of tx datagrams without terminating NULL entry */
-       ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX;
+       /* max count of tx datagrams */
+       if ((ctx->tx_max_datagrams == 0) ||
+                       (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX))
+               ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX;
 
        /* verify maximum size of received NTB in bytes */
-       if ((ctx->rx_max <
-           (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) ||
-           (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX)) {
+       if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) {
+               pr_debug("Using min receive length=%d\n",
+                                               USB_CDC_NCM_NTB_MIN_IN_SIZE);
+               ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE;
+       }
+
+       if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) {
                pr_debug("Using default maximum receive length=%d\n",
                                                CDC_NCM_NTB_MAX_SIZE_RX);
                ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX;
        }
 
+       /* inform device about NTB input size changes */
+       if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) {
+               req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT |
+                                                       USB_RECIP_INTERFACE;
+               req.bNotificationType = USB_CDC_SET_NTB_INPUT_SIZE;
+               req.wValue = 0;
+               req.wIndex = cpu_to_le16(iface_no);
+
+               if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) {
+                       struct usb_cdc_ncm_ndp_input_size ndp_in_sz;
+
+                       req.wLength = 8;
+                       ndp_in_sz.dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
+                       ndp_in_sz.wNtbInMaxDatagrams =
+                                       cpu_to_le16(CDC_NCM_DPT_DATAGRAMS_MAX);
+                       ndp_in_sz.wReserved = 0;
+                       err = cdc_ncm_do_request(ctx, &req, &ndp_in_sz, 0, NULL,
+                                                                       1000);
+               } else {
+                       __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
+
+                       req.wLength = 4;
+                       err = cdc_ncm_do_request(ctx, &req, &dwNtbInMaxSize, 0,
+                                                               NULL, 1000);
+               }
+
+               if (err)
+                       pr_debug("Setting NTB Input Size failed\n");
+       }
+
        /* verify maximum size of transmitted NTB in bytes */
        if ((ctx->tx_max <
            (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) ||
@@ -297,47 +334,84 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
        /* additional configuration */
 
        /* set CRC Mode */
-       req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE;
-       req.bNotificationType = USB_CDC_SET_CRC_MODE;
-       req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED);
-       req.wIndex = cpu_to_le16(iface_no);
-       req.wLength = 0;
-
-       err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
-       if (err)
-               pr_debug("Setting CRC mode off failed\n");
+       if (flags & USB_CDC_NCM_NCAP_CRC_MODE) {
+               req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT |
+                                                       USB_RECIP_INTERFACE;
+               req.bNotificationType = USB_CDC_SET_CRC_MODE;
+               req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED);
+               req.wIndex = cpu_to_le16(iface_no);
+               req.wLength = 0;
+
+               err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
+               if (err)
+                       pr_debug("Setting CRC mode off failed\n");
+       }
 
-       /* set NTB format */
-       req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE;
-       req.bNotificationType = USB_CDC_SET_NTB_FORMAT;
-       req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT);
-       req.wIndex = cpu_to_le16(iface_no);
-       req.wLength = 0;
+       /* set NTB format, if both formats are supported */
+       if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) {
+               req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT |
+                                                       USB_RECIP_INTERFACE;
+               req.bNotificationType = USB_CDC_SET_NTB_FORMAT;
+               req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT);
+               req.wIndex = cpu_to_le16(iface_no);
+               req.wLength = 0;
+
+               err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
+               if (err)
+                       pr_debug("Setting NTB format to 16-bit failed\n");
+       }
 
-       err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
-       if (err)
-               pr_debug("Setting NTB format to 16-bit failed\n");
+       ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
 
        /* set Max Datagram Size (MTU) */
-       req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE;
-       req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE;
-       req.wValue = 0;
-       req.wIndex = cpu_to_le16(iface_no);
-       req.wLength = cpu_to_le16(2);
+       if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
+               __le16 max_datagram_size;
+               u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
+
+               req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN |
+                                                       USB_RECIP_INTERFACE;
+               req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE;
+               req.wValue = 0;
+               req.wIndex = cpu_to_le16(iface_no);
+               req.wLength = cpu_to_le16(2);
+
+               err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL,
+                                                                       1000);
+               if (err) {
+                       pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
+                                               CDC_NCM_MIN_DATAGRAM_SIZE);
+               } else {
+                       ctx->max_datagram_size = le16_to_cpu(max_datagram_size);
+                       /* Check Eth descriptor value */
+                       if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) {
+                               if (ctx->max_datagram_size > eth_max_sz)
+                                       ctx->max_datagram_size = eth_max_sz;
+                       } else {
+                               if (ctx->max_datagram_size >
+                                               CDC_NCM_MAX_DATAGRAM_SIZE)
+                                       ctx->max_datagram_size =
+                                               CDC_NCM_MAX_DATAGRAM_SIZE;
+                       }
 
-       err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, 1000);
-       if (err) {
-               pr_debug(" GET_MAX_DATAGRAM_SIZE failed, using size=%u\n",
-                        CDC_NCM_MIN_DATAGRAM_SIZE);
-               /* use default */
-               ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
-       } else {
-               ctx->max_datagram_size = le16_to_cpu(max_datagram_size);
+                       if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
+                               ctx->max_datagram_size =
+                                       CDC_NCM_MIN_DATAGRAM_SIZE;
+
+                       /* if value changed, update device */
+                       req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT |
+                                                       USB_RECIP_INTERFACE;
+                       req.bNotificationType = USB_CDC_SET_MAX_DATAGRAM_SIZE;
+                       req.wValue = 0;
+                       req.wIndex = cpu_to_le16(iface_no);
+                       req.wLength = 2;
+                       max_datagram_size = cpu_to_le16(ctx->max_datagram_size);
+
+                       err = cdc_ncm_do_request(ctx, &req, &max_datagram_size,
+                                                               0, NULL, 1000);
+                       if (err)
+                               pr_debug("SET_MAX_DATAGRAM_SIZE failed\n");
+               }
 
-               if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
-                       ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
-               else if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
-                       ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE;
        }
 
        if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
@@ -466,19 +540,13 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
 
                        ctx->ether_desc =
                                        (const struct usb_cdc_ether_desc *)buf;
-
                        dev->hard_mtu =
                                le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
 
-                       if (dev->hard_mtu <
-                           (CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN))
-                               dev->hard_mtu =
-                                       CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN;
-
-                       else if (dev->hard_mtu >
-                                (CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN))
-                               dev->hard_mtu =
-                                       CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN;
+                       if (dev->hard_mtu < CDC_NCM_MIN_DATAGRAM_SIZE)
+                               dev->hard_mtu = CDC_NCM_MIN_DATAGRAM_SIZE;
+                       else if (dev->hard_mtu > CDC_NCM_MAX_DATAGRAM_SIZE)
+                               dev->hard_mtu = CDC_NCM_MAX_DATAGRAM_SIZE;
                        break;
 
                case USB_CDC_NCM_TYPE:
@@ -628,13 +696,13 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
        u32 offset;
        u32 last_offset;
        u16 n = 0;
-       u8 timeout = 0;
+       u8 ready2send = 0;
 
        /* if there is a remaining skb, it gets priority */
        if (skb != NULL)
                swap(skb, ctx->tx_rem_skb);
        else
-               timeout = 1;
+               ready2send = 1;
 
        /*
         * +----------------+
@@ -682,9 +750,10 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
 
        for (; n < ctx->tx_max_datagrams; n++) {
                /* check if end of transmit buffer is reached */
-               if (offset >= ctx->tx_max)
+               if (offset >= ctx->tx_max) {
+                       ready2send = 1;
                        break;
-
+               }
                /* compute maximum buffer size */
                rem = ctx->tx_max - offset;
 
@@ -711,9 +780,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
                                }
                                ctx->tx_rem_skb = skb;
                                skb = NULL;
-
-                               /* loop one more time */
-                               timeout = 1;
+                               ready2send = 1;
                        }
                        break;
                }
@@ -756,7 +823,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
                ctx->tx_curr_last_offset = last_offset;
                goto exit_no_skb;
 
-       } else if ((n < ctx->tx_max_datagrams) && (timeout == 0)) {
+       } else if ((n < ctx->tx_max_datagrams) && (ready2send == 0)) {
                /* wait for more frames */
                /* push variables */
                ctx->tx_curr_skb = skb_out;
@@ -813,7 +880,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
                                        cpu_to_le16(sizeof(ctx->tx_ncm.nth16));
        ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq);
        ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset);
-       ctx->tx_ncm.nth16.wFpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16),
+       ctx->tx_ncm.nth16.wNdpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16),
                                                        ctx->tx_ndp_modulus);
 
        memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16));
@@ -825,13 +892,13 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
        rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) *
                                        sizeof(struct usb_cdc_ncm_dpe16));
        ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem);
-       ctx->tx_ncm.ndp16.wNextFpIndex = 0; /* reserved */
+       ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */
 
-       memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex,
+       memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex,
                                                &(ctx->tx_ncm.ndp16),
                                                sizeof(ctx->tx_ncm.ndp16));
 
-       memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex +
+       memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex +
                                        sizeof(ctx->tx_ncm.ndp16),
                                        &(ctx->tx_ncm.dpe16),
                                        (ctx->tx_curr_frame_num + 1) *
@@ -961,7 +1028,7 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
                goto error;
        }
 
-       temp = le16_to_cpu(ctx->rx_ncm.nth16.wFpIndex);
+       temp = le16_to_cpu(ctx->rx_ncm.nth16.wNdpIndex);
        if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) {
                pr_debug("invalid DPT16 index\n");
                goto error;
@@ -1048,10 +1115,10 @@ error:
 
 static void
 cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx,
-                    struct connection_speed_change *data)
+                    struct usb_cdc_speed_change *data)
 {
-       uint32_t rx_speed = le32_to_cpu(data->USBitRate);
-       uint32_t tx_speed = le32_to_cpu(data->DSBitRate);
+       uint32_t rx_speed = le32_to_cpu(data->DLBitRRate);
+       uint32_t tx_speed = le32_to_cpu(data->ULBitRate);
 
        /*
         * Currently the USB-NET API does not support reporting the actual
@@ -1092,7 +1159,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
        /* test for split data in 8-byte chunks */
        if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
                cdc_ncm_speed_change(ctx,
-                     (struct connection_speed_change *)urb->transfer_buffer);
+                     (struct usb_cdc_speed_change *)urb->transfer_buffer);
                return;
        }
 
@@ -1120,12 +1187,12 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
                break;
 
        case USB_CDC_NOTIFY_SPEED_CHANGE:
-               if (urb->actual_length <
-                   (sizeof(*event) + sizeof(struct connection_speed_change)))
+               if (urb->actual_length < (sizeof(*event) +
+                                       sizeof(struct usb_cdc_speed_change)))
                        set_bit(EVENT_STS_SPLIT, &dev->flags);
                else
                        cdc_ncm_speed_change(ctx,
-                               (struct connection_speed_change *) &event[1]);
+                               (struct usb_cdc_speed_change *) &event[1]);
                break;
 
        default:
index 90a23e4..82dba5a 100644 (file)
@@ -446,6 +446,20 @@ static void skb_recv_done(struct virtqueue *rvq)
        }
 }
 
+static void virtnet_napi_enable(struct virtnet_info *vi)
+{
+       napi_enable(&vi->napi);
+
+       /* If all buffers were filled by other side before we napi_enabled, we
+        * won't get another interrupt, so process any outstanding packets
+        * now.  virtnet_poll wants re-enable the queue, so we disable here.
+        * We synchronize against interrupts via NAPI_STATE_SCHED */
+       if (napi_schedule_prep(&vi->napi)) {
+               virtqueue_disable_cb(vi->rvq);
+               __napi_schedule(&vi->napi);
+       }
+}
+
 static void refill_work(struct work_struct *work)
 {
        struct virtnet_info *vi;
@@ -454,7 +468,7 @@ static void refill_work(struct work_struct *work)
        vi = container_of(work, struct virtnet_info, refill.work);
        napi_disable(&vi->napi);
        still_empty = !try_fill_recv(vi, GFP_KERNEL);
-       napi_enable(&vi->napi);
+       virtnet_napi_enable(vi);
 
        /* In theory, this can happen: if we don't get any buffers in
         * we will *never* try to fill again. */
@@ -638,16 +652,7 @@ static int virtnet_open(struct net_device *dev)
 {
        struct virtnet_info *vi = netdev_priv(dev);
 
-       napi_enable(&vi->napi);
-
-       /* If all buffers were filled by other side before we napi_enabled, we
-        * won't get another interrupt, so process any outstanding packets
-        * now.  virtnet_poll wants re-enable the queue, so we disable here.
-        * We synchronize against interrupts via NAPI_STATE_SCHED */
-       if (napi_schedule_prep(&vi->napi)) {
-               virtqueue_disable_cb(vi->rvq);
-               __napi_schedule(&vi->napi);
-       }
+       virtnet_napi_enable(vi);
        return 0;
 }
 
index 3681caf..23838e3 100644 (file)
@@ -218,6 +218,7 @@ struct ath_frame_info {
 struct ath_buf_state {
        u8 bf_type;
        u8 bfs_paprd;
+       unsigned long bfs_paprd_timestamp;
        enum ath9k_internal_frame_type bfs_ftype;
 };
 
@@ -593,7 +594,6 @@ struct ath_softc {
        struct work_struct paprd_work;
        struct work_struct hw_check_work;
        struct completion paprd_complete;
-       bool paprd_pending;
 
        u32 intrstatus;
        u32 sc_flags; /* SC_OP_* */
index 9040c2f..da5c645 100644 (file)
@@ -342,7 +342,6 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
        tx_info->control.rates[1].idx = -1;
 
        init_completion(&sc->paprd_complete);
-       sc->paprd_pending = true;
        txctl.paprd = BIT(chain);
 
        if (ath_tx_start(hw, skb, &txctl) != 0) {
@@ -353,7 +352,6 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
 
        time_left = wait_for_completion_timeout(&sc->paprd_complete,
                        msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
-       sc->paprd_pending = false;
 
        if (!time_left)
                ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE,
index 33a37ed..07b7804 100644 (file)
@@ -1725,6 +1725,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
                        ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc,
                                                   bf->bf_state.bfs_paprd);
 
+               if (txctl->paprd)
+                       bf->bf_state.bfs_paprd_timestamp = jiffies;
+
                ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
        }
 
@@ -1886,7 +1889,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
        bf->bf_buf_addr = 0;
 
        if (bf->bf_state.bfs_paprd) {
-               if (!sc->paprd_pending)
+               if (time_after(jiffies,
+                               bf->bf_state.bfs_paprd_timestamp +
+                               msecs_to_jiffies(ATH_PAPRD_TIMEOUT)))
                        dev_kfree_skb_any(skb);
                else
                        complete(&sc->paprd_complete);
index 939a0e9..84866a4 100644 (file)
@@ -564,7 +564,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
        cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid);
 
        /* 2. Maybe the AP wants to send multicast/broadcast data? */
-       cam = !!(tim_ie->bitmap_ctrl & 0x01);
+       cam |= !!(tim_ie->bitmap_ctrl & 0x01);
 
        if (!cam) {
                /* back to low-power land. */
index af505bc..ef36aff 100644 (file)
@@ -681,6 +681,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
        .fw_name_pre = IWL6050_FW_PRE,                          \
        .ucode_api_max = IWL6050_UCODE_API_MAX,                 \
        .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
+       .valid_tx_ant = ANT_AB,         /* .cfg overwrite */    \
+       .valid_rx_ant = ANT_AB,         /* .cfg overwrite */    \
        .ops = &iwl6050_ops,                                    \
        .eeprom_ver = EEPROM_6050_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,       \
index 36335b1..c1cfd99 100644 (file)
@@ -1157,6 +1157,9 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
        /* only Re-enable if disabled by irq */
        if (test_bit(STATUS_INT_ENABLED, &priv->status))
                iwl_enable_interrupts(priv);
+       /* Re-enable RF_KILL if it occurred */
+       else if (handled & CSR_INT_BIT_RF_KILL)
+               iwl_enable_rfkill_int(priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
        if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
@@ -1371,6 +1374,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* only Re-enable if disabled by irq */
        if (test_bit(STATUS_INT_ENABLED, &priv->status))
                iwl_enable_interrupts(priv);
+       /* Re-enable RF_KILL if it occurred */
+       else if (handled & CSR_INT_BIT_RF_KILL)
+               iwl_enable_rfkill_int(priv);
 }
 
 /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
index 012e1a4..40372ba 100644 (file)
@@ -1039,6 +1039,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
 
        if (changed & BSS_CHANGED_BEACON) {
                beacon = ieee80211_beacon_get(hw, vif);
+               if (!beacon)
+                       goto out_sleep;
+
                ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
                                              beacon->len);
 
index 8ecaac9..ea25e5b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/capability.h>
+#include <linux/security.h>
 #include <linux/pci-aspm.h>
 #include <linux/slab.h>
 #include "pci.h"
@@ -368,7 +369,7 @@ pci_read_config(struct file *filp, struct kobject *kobj,
        u8 *data = (u8*) buf;
 
        /* Several chips lock up trying to read undefined config space */
-       if (cap_raised(filp->f_cred->cap_effective, CAP_SYS_ADMIN)) {
+       if (security_capable(filp->f_cred, CAP_SYS_ADMIN) == 0) {
                size = dev->cfg_size;
        } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
                size = 128;
index b2752b6..e725d51 100644 (file)
@@ -134,36 +134,29 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
        return ret;
 }
 
-static int at32_rtc_ioctl(struct device *dev, unsigned int cmd,
-                       unsigned long arg)
+static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
        int ret = 0;
 
        spin_lock_irq(&rtc->lock);
 
-       switch (cmd) {
-       case RTC_AIE_ON:
+       if(enabled) {
                if (rtc_readl(rtc, VAL) > rtc->alarm_time) {
                        ret = -EINVAL;
-                       break;
+                       goto out;
                }
                rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
                                | RTC_BIT(CTRL_TOPEN));
                rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
                rtc_writel(rtc, IER, RTC_BIT(IER_TOPI));
-               break;
-       case RTC_AIE_OFF:
+       } else {
                rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
                                & ~RTC_BIT(CTRL_TOPEN));
                rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI));
                rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
-               break;
-       default:
-               ret = -ENOIOCTLCMD;
-               break;
        }
-
+out:
        spin_unlock_irq(&rtc->lock);
 
        return ret;
@@ -195,11 +188,11 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id)
 }
 
 static struct rtc_class_ops at32_rtc_ops = {
-       .ioctl          = at32_rtc_ioctl,
        .read_time      = at32_rtc_readtime,
        .set_time       = at32_rtc_settime,
        .read_alarm     = at32_rtc_readalarm,
        .set_alarm      = at32_rtc_setalarm,
+       .alarm_irq_enable = at32_rtc_alarm_irq_enable,
 };
 
 static int __init at32_rtc_probe(struct platform_device *pdev)
index bc8bbca..26d1cf5 100644 (file)
@@ -195,13 +195,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
 
        /* important:  scrub old status before enabling IRQs */
        switch (cmd) {
-       case RTC_AIE_OFF:       /* alarm off */
-               at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
-               break;
-       case RTC_AIE_ON:        /* alarm on */
-               at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
-               at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
-               break;
        case RTC_UIE_OFF:       /* update off */
                at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV);
                break;
@@ -217,6 +210,18 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
        return ret;
 }
 
+static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       pr_debug("%s(): cmd=%08x\n", __func__, enabled);
+
+       if (enabled) {
+               at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
+               at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
+       } else
+               at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
+
+       return 0;
+}
 /*
  * Provide additional RTC information in /proc/driver/rtc
  */
@@ -270,6 +275,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
        .read_alarm     = at91_rtc_readalarm,
        .set_alarm      = at91_rtc_setalarm,
        .proc           = at91_rtc_proc,
+       .alarm_irq_enable = at91_rtc_alarm_irq_enable,
 };
 
 /*
index f677e07..c36749e 100644 (file)
@@ -229,12 +229,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
        dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr);
 
        switch (cmd) {
-       case RTC_AIE_OFF:               /* alarm off */
-               rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
-               break;
-       case RTC_AIE_ON:                /* alarm on */
-               rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
-               break;
        case RTC_UIE_OFF:               /* update off */
                rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN);
                break;
@@ -249,6 +243,19 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
        return ret;
 }
 
+static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       struct sam9_rtc *rtc = dev_get_drvdata(dev);
+       u32 mr = rtt_readl(rtc, MR);
+
+       dev_dbg(dev, "alarm_irq_enable: enabled=%08x, mr %08x\n", enabled, mr);
+       if (enabled)
+               rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
+       else
+               rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
+       return 0;
+}
+
 /*
  * Provide additional RTC information in /proc/driver/rtc
  */
@@ -302,6 +309,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
        .read_alarm     = at91_rtc_readalarm,
        .set_alarm      = at91_rtc_setalarm,
        .proc           = at91_rtc_proc,
+       .alarm_irq_enabled = at91_rtc_alarm_irq_enable,
 };
 
 /*
index b4b6087..17971d9 100644 (file)
@@ -259,15 +259,6 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar
                bfin_rtc_int_clear(~RTC_ISTAT_SEC);
                break;
 
-       case RTC_AIE_ON:
-               dev_dbg_stamp(dev);
-               bfin_rtc_int_set_alarm(rtc);
-               break;
-       case RTC_AIE_OFF:
-               dev_dbg_stamp(dev);
-               bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
-               break;
-
        default:
                dev_dbg_stamp(dev);
                ret = -ENOIOCTLCMD;
@@ -276,6 +267,17 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar
        return ret;
 }
 
+static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       struct bfin_rtc *rtc = dev_get_drvdata(dev);
+
+       dev_dbg_stamp(dev);
+       if (enabled)
+               bfin_rtc_int_set_alarm(rtc);
+       else
+               bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
+}
+
 static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct bfin_rtc *rtc = dev_get_drvdata(dev);
@@ -362,6 +364,7 @@ static struct rtc_class_ops bfin_rtc_ops = {
        .read_alarm    = bfin_rtc_read_alarm,
        .set_alarm     = bfin_rtc_set_alarm,
        .proc          = bfin_rtc_proc,
+       .alarm_irq_enable = bfin_rtc_alarm_irq_enable,
 };
 
 static int __devinit bfin_rtc_probe(struct platform_device *pdev)
index 212b16e..37c3cc1 100644 (file)
@@ -154,19 +154,7 @@ static long rtc_dev_ioctl(struct file *file,
        if (err)
                goto done;
 
-       /* try the driver's ioctl interface */
-       if (ops->ioctl) {
-               err = ops->ioctl(rtc->dev.parent, cmd, arg);
-               if (err != -ENOIOCTLCMD) {
-                       mutex_unlock(&rtc->ops_lock);
-                       return err;
-               }
-       }
-
-       /* if the driver does not provide the ioctl interface
-        * or if that particular ioctl was not implemented
-        * (-ENOIOCTLCMD), we will try to emulate here.
-        *
+       /*
         * Drivers *SHOULD NOT* provide ioctl implementations
         * for these requests.  Instead, provide methods to
         * support the following code, so that the RTC's main
@@ -329,7 +317,12 @@ static long rtc_dev_ioctl(struct file *file,
                return err;
 
        default:
-               err = -ENOTTY;
+               /* Finally try the driver's ioctl interface */
+               if (ops->ioctl) {
+                       err = ops->ioctl(rtc->dev.parent, cmd, arg);
+                       if (err == -ENOIOCTLCMD)
+                               err = -ENOTTY;
+               }
                break;
        }
 
index bf430f9..60ce696 100644 (file)
@@ -40,6 +40,26 @@ static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg)
        __raw_writel(data, &priv->rtcregs[reg]);
 }
 
+
+static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       struct ds1286_priv *priv = dev_get_drvdata(dev);
+       unsigned long flags;
+       unsigned char val;
+
+       /* Allow or mask alarm interrupts */
+       spin_lock_irqsave(&priv->lock, flags);
+       val = ds1286_rtc_read(priv, RTC_CMD);
+       if (enabled)
+               val &=  ~RTC_TDM;
+       else
+               val |=  RTC_TDM;
+       ds1286_rtc_write(priv, val, RTC_CMD);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 0;
+}
+
 #ifdef CONFIG_RTC_INTF_DEV
 
 static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
@@ -49,22 +69,6 @@ static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
        unsigned char val;
 
        switch (cmd) {
-       case RTC_AIE_OFF:
-               /* Mask alarm int. enab. bit    */
-               spin_lock_irqsave(&priv->lock, flags);
-               val = ds1286_rtc_read(priv, RTC_CMD);
-               val |=  RTC_TDM;
-               ds1286_rtc_write(priv, val, RTC_CMD);
-               spin_unlock_irqrestore(&priv->lock, flags);
-               break;
-       case RTC_AIE_ON:
-               /* Allow alarm interrupts.      */
-               spin_lock_irqsave(&priv->lock, flags);
-               val = ds1286_rtc_read(priv, RTC_CMD);
-               val &=  ~RTC_TDM;
-               ds1286_rtc_write(priv, val, RTC_CMD);
-               spin_unlock_irqrestore(&priv->lock, flags);
-               break;
        case RTC_WIE_OFF:
                /* Mask watchdog int. enab. bit */
                spin_lock_irqsave(&priv->lock, flags);
@@ -316,12 +320,13 @@ static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 }
 
 static const struct rtc_class_ops ds1286_ops = {
-       .ioctl          = ds1286_ioctl,
-       .proc           = ds1286_proc,
+       .ioctl          = ds1286_ioctl,
+       .proc           = ds1286_proc,
        .read_time      = ds1286_read_time,
        .set_time       = ds1286_set_time,
        .read_alarm     = ds1286_read_alarm,
        .set_alarm      = ds1286_set_alarm,
+       .alarm_irq_enable = ds1286_alarm_irq_enable,
 };
 
 static int __devinit ds1286_probe(struct platform_device *pdev)
index 077af1d..57fbcc1 100644 (file)
@@ -139,49 +139,32 @@ static u8 hour2bcd(bool hr12, int hour)
  * Interface to RTC framework
  */
 
-#ifdef CONFIG_RTC_INTF_DEV
-
-/*
- * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
- */
-static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
+static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct ds1305   *ds1305 = dev_get_drvdata(dev);
        u8              buf[2];
-       int             status = -ENOIOCTLCMD;
+       long            err = -EINVAL;
 
        buf[0] = DS1305_WRITE | DS1305_CONTROL;
        buf[1] = ds1305->ctrl[0];
 
-       switch (cmd) {
-       case RTC_AIE_OFF:
-               status = 0;
-               if (!(buf[1] & DS1305_AEI0))
-                       goto done;
-               buf[1] &= ~DS1305_AEI0;
-               break;
-
-       case RTC_AIE_ON:
-               status = 0;
+       if (enabled) {
                if (ds1305->ctrl[0] & DS1305_AEI0)
                        goto done;
                buf[1] |= DS1305_AEI0;
-               break;
-       }
-       if (status == 0) {
-               status = spi_write_then_read(ds1305->spi, buf, sizeof buf,
-                               NULL, 0);
-               if (status >= 0)
-                       ds1305->ctrl[0] = buf[1];
+       } else {
+               if (!(buf[1] & DS1305_AEI0))
+                       goto done;
+               buf[1] &= ~DS1305_AEI0;
        }
-
+       err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0);
+       if (err >= 0)
+               ds1305->ctrl[0] = buf[1];
 done:
-       return status;
+       return err;
+
 }
 
-#else
-#define ds1305_ioctl   NULL
-#endif
 
 /*
  * Get/set of date and time is pretty normal.
@@ -460,12 +443,12 @@ done:
 #endif
 
 static const struct rtc_class_ops ds1305_ops = {
-       .ioctl          = ds1305_ioctl,
        .read_time      = ds1305_get_time,
        .set_time       = ds1305_set_time,
        .read_alarm     = ds1305_get_alarm,
        .set_alarm      = ds1305_set_alarm,
        .proc           = ds1305_proc,
+       .alarm_irq_enable = ds1305_alarm_irq_enable,
 };
 
 static void ds1305_work(struct work_struct *work)
index 0d559b6..4724ba3 100644 (file)
@@ -495,50 +495,27 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        return 0;
 }
 
-static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct i2c_client       *client = to_i2c_client(dev);
        struct ds1307           *ds1307 = i2c_get_clientdata(client);
        int                     ret;
 
-       switch (cmd) {
-       case RTC_AIE_OFF:
-               if (!test_bit(HAS_ALARM, &ds1307->flags))
-                       return -ENOTTY;
-
-               ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
-               if (ret < 0)
-                       return ret;
-
-               ret &= ~DS1337_BIT_A1IE;
-
-               ret = i2c_smbus_write_byte_data(client,
-                                               DS1337_REG_CONTROL, ret);
-               if (ret < 0)
-                       return ret;
-
-               break;
-
-       case RTC_AIE_ON:
-               if (!test_bit(HAS_ALARM, &ds1307->flags))
-                       return -ENOTTY;
+       if (!test_bit(HAS_ALARM, &ds1307->flags))
+               return -ENOTTY;
 
-               ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
-               if (ret < 0)
-                       return ret;
+       ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+       if (ret < 0)
+               return ret;
 
+       if (enabled)
                ret |= DS1337_BIT_A1IE;
+       else
+               ret &= ~DS1337_BIT_A1IE;
 
-               ret = i2c_smbus_write_byte_data(client,
-                                               DS1337_REG_CONTROL, ret);
-               if (ret < 0)
-                       return ret;
-
-               break;
-
-       default:
-               return -ENOIOCTLCMD;
-       }
+       ret = i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, ret);
+       if (ret < 0)
+               return ret;
 
        return 0;
 }
@@ -548,7 +525,7 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
        .set_time       = ds1307_set_time,
        .read_alarm     = ds1337_read_alarm,
        .set_alarm      = ds1337_set_alarm,
-       .ioctl          = ds1307_ioctl,
+       .alarm_irq_enable = ds1307_alarm_irq_enable,
 };
 
 /*----------------------------------------------------------------------*/
index 47fb635..d834a63 100644 (file)
@@ -307,42 +307,25 @@ unlock:
        mutex_unlock(&ds1374->mutex);
 }
 
-static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct ds1374 *ds1374 = i2c_get_clientdata(client);
-       int ret = -ENOIOCTLCMD;
+       int ret;
 
        mutex_lock(&ds1374->mutex);
 
-       switch (cmd) {
-       case RTC_AIE_OFF:
-               ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
-               if (ret < 0)
-                       goto out;
-
-               ret &= ~DS1374_REG_CR_WACE;
-
-               ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
-               if (ret < 0)
-                       goto out;
-
-               break;
-
-       case RTC_AIE_ON:
-               ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
-               if (ret < 0)
-                       goto out;
+       ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
+       if (ret < 0)
+               goto out;
 
+       if (enabled) {
                ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
                ret &= ~DS1374_REG_CR_WDALM;
-
-               ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
-               if (ret < 0)
-                       goto out;
-
-               break;
+       } else {
+               ret &= ~DS1374_REG_CR_WACE;
        }
+       ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
 
 out:
        mutex_unlock(&ds1374->mutex);
@@ -354,7 +337,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
        .set_time = ds1374_set_time,
        .read_alarm = ds1374_read_alarm,
        .set_alarm = ds1374_set_alarm,
-       .ioctl = ds1374_ioctl,
+       .alarm_irq_enable = ds1374_alarm_irq_enable,
 };
 
 static int ds1374_probe(struct i2c_client *client,
index 5a8daa3..69fe664 100644 (file)
@@ -213,41 +213,27 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
        return m41t80_set_datetime(to_i2c_client(dev), tm);
 }
 
-#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
-static int
-m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct i2c_client *client = to_i2c_client(dev);
        int rc;
 
-       switch (cmd) {
-       case RTC_AIE_OFF:
-       case RTC_AIE_ON:
-               break;
-       default:
-               return -ENOIOCTLCMD;
-       }
-
        rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
        if (rc < 0)
                goto err;
-       switch (cmd) {
-       case RTC_AIE_OFF:
-               rc &= ~M41T80_ALMON_AFE;
-               break;
-       case RTC_AIE_ON:
+
+       if (enabled)
                rc |= M41T80_ALMON_AFE;
-               break;
-       }
+       else
+               rc &= ~M41T80_ALMON_AFE;
+
        if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
                goto err;
+
        return 0;
 err:
        return -EIO;
 }
-#else
-#define        m41t80_rtc_ioctl NULL
-#endif
 
 static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
@@ -374,7 +360,7 @@ static struct rtc_class_ops m41t80_rtc_ops = {
        .read_alarm = m41t80_rtc_read_alarm,
        .set_alarm = m41t80_rtc_set_alarm,
        .proc = m41t80_rtc_proc,
-       .ioctl = m41t80_rtc_ioctl,
+       .alarm_irq_enable = m41t80_rtc_alarm_irq_enable,
 };
 
 #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
index a99a0b5..3978f4c 100644 (file)
@@ -263,30 +263,21 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 /*
  * Handle commands from user-space
  */
-static int m48t59_rtc_ioctl(struct device *dev, unsigned int cmd,
-                       unsigned long arg)
+static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct m48t59_plat_data *pdata = pdev->dev.platform_data;
        struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
        unsigned long flags;
-       int ret = 0;
 
        spin_lock_irqsave(&m48t59->lock, flags);
-       switch (cmd) {
-       case RTC_AIE_OFF:       /* alarm interrupt off */
-               M48T59_WRITE(0x00, M48T59_INTR);
-               break;
-       case RTC_AIE_ON:        /* alarm interrupt on */
+       if (enabled)
                M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR);
-               break;
-       default:
-               ret = -ENOIOCTLCMD;
-               break;
-       }
+       else
+               M48T59_WRITE(0x00, M48T59_INTR);
        spin_unlock_irqrestore(&m48t59->lock, flags);
 
-       return ret;
+       return 0;
 }
 
 static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq)
@@ -330,12 +321,12 @@ static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id)
 }
 
 static const struct rtc_class_ops m48t59_rtc_ops = {
-       .ioctl          = m48t59_rtc_ioctl,
        .read_time      = m48t59_rtc_read_time,
        .set_time       = m48t59_rtc_set_time,
        .read_alarm     = m48t59_rtc_readalarm,
        .set_alarm      = m48t59_rtc_setalarm,
        .proc           = m48t59_rtc_proc,
+       .alarm_irq_enable = m48t59_rtc_alarm_irq_enable,
 };
 
 static const struct rtc_class_ops m48t02_rtc_ops = {
index bcd0cf6..1db62db 100644 (file)
@@ -255,42 +255,21 @@ static int mrst_irq_set_state(struct device *dev, int enabled)
        return 0;
 }
 
-#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
-
 /* Currently, the vRTC doesn't support UIE ON/OFF */
-static int
-mrst_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct mrst_rtc *mrst = dev_get_drvdata(dev);
        unsigned long   flags;
 
-       switch (cmd) {
-       case RTC_AIE_OFF:
-       case RTC_AIE_ON:
-               if (!mrst->irq)
-                       return -EINVAL;
-               break;
-       default:
-               /* PIE ON/OFF is handled by mrst_irq_set_state() */
-               return -ENOIOCTLCMD;
-       }
-
        spin_lock_irqsave(&rtc_lock, flags);
-       switch (cmd) {
-       case RTC_AIE_OFF:       /* alarm off */
-               mrst_irq_disable(mrst, RTC_AIE);
-               break;
-       case RTC_AIE_ON:        /* alarm on */
+       if (enabled)
                mrst_irq_enable(mrst, RTC_AIE);
-               break;
-       }
+       else
+               mrst_irq_disable(mrst, RTC_AIE);
        spin_unlock_irqrestore(&rtc_lock, flags);
        return 0;
 }
 
-#else
-#define        mrst_rtc_ioctl  NULL
-#endif
 
 #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
 
@@ -317,13 +296,13 @@ static int mrst_procfs(struct device *dev, struct seq_file *seq)
 #endif
 
 static const struct rtc_class_ops mrst_rtc_ops = {
-       .ioctl          = mrst_rtc_ioctl,
        .read_time      = mrst_read_time,
        .set_time       = mrst_set_time,
        .read_alarm     = mrst_read_alarm,
        .set_alarm      = mrst_set_alarm,
        .proc           = mrst_procfs,
        .irq_set_state  = mrst_irq_set_state,
+       .alarm_irq_enable = mrst_rtc_alarm_irq_enable,
 };
 
 static struct mrst_rtc mrst_rtc;
index b2fff0c..6782062 100644 (file)
@@ -82,7 +82,7 @@ static inline unsigned int msm6242_read(struct msm6242_priv *priv,
 static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val,
                                unsigned int reg)
 {
-       return __raw_writel(val, &priv->regs[reg]);
+       __raw_writel(val, &priv->regs[reg]);
 }
 
 static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val,
index bcca472..60627a7 100644 (file)
@@ -169,25 +169,19 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
        return 0;
 }
 
-static int mv_rtc_ioctl(struct device *dev, unsigned int cmd,
-                       unsigned long arg)
+static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
        void __iomem *ioaddr = pdata->ioaddr;
 
        if (pdata->irq < 0)
-               return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
-       switch (cmd) {
-       case RTC_AIE_OFF:
-               writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
-               break;
-       case RTC_AIE_ON:
+               return -EINVAL; /* fall back into rtc-dev's emulation */
+
+       if (enabled)
                writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
-               break;
-       default:
-               return -ENOIOCTLCMD;
-       }
+       else
+               writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
        return 0;
 }
 
@@ -216,7 +210,7 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = {
        .set_time       = mv_rtc_set_time,
        .read_alarm     = mv_rtc_read_alarm,
        .set_alarm      = mv_rtc_set_alarm,
-       .ioctl          = mv_rtc_ioctl,
+       .alarm_irq_enable = mv_rtc_alarm_irq_enable,
 };
 
 static int __devinit mv_rtc_probe(struct platform_device *pdev)
index e72b523..b4dbf3a 100644 (file)
@@ -143,8 +143,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
        u8 reg;
 
        switch (cmd) {
-       case RTC_AIE_OFF:
-       case RTC_AIE_ON:
        case RTC_UIE_OFF:
        case RTC_UIE_ON:
                break;
@@ -156,13 +154,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
        rtc_wait_not_busy();
        reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
        switch (cmd) {
-       /* AIE = Alarm Interrupt Enable */
-       case RTC_AIE_OFF:
-               reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
-               break;
-       case RTC_AIE_ON:
-               reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
-               break;
        /* UIE = Update Interrupt Enable (1/second) */
        case RTC_UIE_OFF:
                reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER;
@@ -182,6 +173,24 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 #define        omap_rtc_ioctl  NULL
 #endif
 
+static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       u8 reg;
+
+       local_irq_disable();
+       rtc_wait_not_busy();
+       reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
+       if (enabled)
+               reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
+       else
+               reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
+       rtc_wait_not_busy();
+       rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
+       local_irq_enable();
+
+       return 0;
+}
+
 /* this hardware doesn't support "don't care" alarm fields */
 static int tm2bcd(struct rtc_time *tm)
 {
@@ -309,6 +318,7 @@ static struct rtc_class_ops omap_rtc_ops = {
        .set_time       = omap_rtc_set_time,
        .read_alarm     = omap_rtc_read_alarm,
        .set_alarm      = omap_rtc_set_alarm,
+       .alarm_irq_enable = omap_rtc_alarm_irq_enable,
 };
 
 static int omap_rtc_alarm;
index c086fc3..242bbf8 100644 (file)
@@ -81,12 +81,16 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
 
 static int rtc_proc_open(struct inode *inode, struct file *file)
 {
+       int ret;
        struct rtc_device *rtc = PDE(inode)->data;
 
        if (!try_module_get(THIS_MODULE))
                return -ENODEV;
 
-       return single_open(file, rtc_proc_show, rtc);
+       ret = single_open(file, rtc_proc_show, rtc);
+       if (ret)
+               module_put(THIS_MODULE);
+       return ret;
 }
 
 static int rtc_proc_release(struct inode *inode, struct file *file)
index 36eb661..694da39 100644 (file)
@@ -76,7 +76,7 @@ static inline unsigned int rp5c01_read(struct rp5c01_priv *priv,
 static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val,
                                unsigned int reg)
 {
-       return __raw_writel(val, &priv->regs[reg]);
+       __raw_writel(val, &priv->regs[reg]);
 }
 
 static void rp5c01_lock(struct rp5c01_priv *priv)
index dd14e20..6aaa155 100644 (file)
@@ -299,14 +299,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
                if (rs5c->type == rtc_rs5c372a
                                && (buf & RS5C372A_CTRL1_SL1))
                        return -ENOIOCTLCMD;
-       case RTC_AIE_OFF:
-       case RTC_AIE_ON:
-               /* these irq management calls only make sense for chips
-                * which are wired up to an IRQ.
-                */
-               if (!rs5c->has_irq)
-                       return -ENOIOCTLCMD;
-               break;
        default:
                return -ENOIOCTLCMD;
        }
@@ -317,12 +309,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 
        addr = RS5C_ADDR(RS5C_REG_CTRL1);
        switch (cmd) {
-       case RTC_AIE_OFF:       /* alarm off */
-               buf &= ~RS5C_CTRL1_AALE;
-               break;
-       case RTC_AIE_ON:        /* alarm on */
-               buf |= RS5C_CTRL1_AALE;
-               break;
        case RTC_UIE_OFF:       /* update off */
                buf &= ~RS5C_CTRL1_CT_MASK;
                break;
@@ -347,6 +333,39 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 #endif
 
 
+static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       struct i2c_client       *client = to_i2c_client(dev);
+       struct rs5c372          *rs5c = i2c_get_clientdata(client);
+       unsigned char           buf;
+       int                     status, addr;
+
+       buf = rs5c->regs[RS5C_REG_CTRL1];
+
+       if (!rs5c->has_irq)
+               return -EINVAL;
+
+       status = rs5c_get_regs(rs5c);
+       if (status < 0)
+               return status;
+
+       addr = RS5C_ADDR(RS5C_REG_CTRL1);
+       if (enabled)
+               buf |= RS5C_CTRL1_AALE;
+       else
+               buf &= ~RS5C_CTRL1_AALE;
+
+       if (i2c_smbus_write_byte_data(client, addr, buf) < 0) {
+               printk(KERN_WARNING "%s: can't update alarm\n",
+                       rs5c->rtc->name);
+               status = -EIO;
+       } else
+               rs5c->regs[RS5C_REG_CTRL1] = buf;
+
+       return status;
+}
+
+
 /* NOTE:  Since RTC_WKALM_{RD,SET} were originally defined for EFI,
  * which only exposes a polled programming interface; and since
  * these calls map directly to those EFI requests; we don't demand
@@ -466,6 +485,7 @@ static const struct rtc_class_ops rs5c372_rtc_ops = {
        .set_time       = rs5c372_rtc_set_time,
        .read_alarm     = rs5c_read_alarm,
        .set_alarm      = rs5c_set_alarm,
+       .alarm_irq_enable = rs5c_rtc_alarm_irq_enable,
 };
 
 #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
index 88ea52b..5dfe5ff 100644 (file)
@@ -314,16 +314,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
                unsigned long arg)
 {
        switch (cmd) {
-       case RTC_AIE_OFF:
-               spin_lock_irq(&sa1100_rtc_lock);
-               RTSR &= ~RTSR_ALE;
-               spin_unlock_irq(&sa1100_rtc_lock);
-               return 0;
-       case RTC_AIE_ON:
-               spin_lock_irq(&sa1100_rtc_lock);
-               RTSR |= RTSR_ALE;
-               spin_unlock_irq(&sa1100_rtc_lock);
-               return 0;
        case RTC_UIE_OFF:
                spin_lock_irq(&sa1100_rtc_lock);
                RTSR &= ~RTSR_HZE;
@@ -338,6 +328,17 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
        return -ENOIOCTLCMD;
 }
 
+static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       spin_lock_irq(&sa1100_rtc_lock);
+       if (enabled)
+               RTSR |= RTSR_ALE;
+       else
+               RTSR &= ~RTSR_ALE;
+       spin_unlock_irq(&sa1100_rtc_lock);
+       return 0;
+}
+
 static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        rtc_time_to_tm(RCNR, tm);
@@ -410,6 +411,7 @@ static const struct rtc_class_ops sa1100_rtc_ops = {
        .proc = sa1100_rtc_proc,
        .irq_set_freq = sa1100_irq_set_freq,
        .irq_set_state = sa1100_irq_set_state,
+       .alarm_irq_enable = sa1100_rtc_alarm_irq_enable,
 };
 
 static int sa1100_rtc_probe(struct platform_device *pdev)
index 06e41ed..93314a9 100644 (file)
@@ -350,10 +350,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
        unsigned int ret = 0;
 
        switch (cmd) {
-       case RTC_AIE_OFF:
-       case RTC_AIE_ON:
-               sh_rtc_setaie(dev, cmd == RTC_AIE_ON);
-               break;
        case RTC_UIE_OFF:
                rtc->periodic_freq &= ~PF_OXS;
                sh_rtc_setcie(dev, 0);
@@ -369,6 +365,12 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
        return ret;
 }
 
+static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       sh_rtc_setaie(dev, enabled);
+       return 0;
+}
+
 static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -604,6 +606,7 @@ static struct rtc_class_ops sh_rtc_ops = {
        .irq_set_state  = sh_rtc_irq_set_state,
        .irq_set_freq   = sh_rtc_irq_set_freq,
        .proc           = sh_rtc_proc,
+       .alarm_irq_enable = sh_rtc_alarm_irq_enable,
 };
 
 static int __init sh_rtc_probe(struct platform_device *pdev)
index 51725f7..a82d6fe 100644 (file)
@@ -50,24 +50,9 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq)
        return 0;
 }
 
-static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
-       unsigned long arg)
+static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
 {
-       /* We do support interrupts, they're generated
-        * using the sysfs interface.
-        */
-       switch (cmd) {
-       case RTC_PIE_ON:
-       case RTC_PIE_OFF:
-       case RTC_UIE_ON:
-       case RTC_UIE_OFF:
-       case RTC_AIE_ON:
-       case RTC_AIE_OFF:
-               return 0;
-
-       default:
-               return -ENOIOCTLCMD;
-       }
+       return 0;
 }
 
 static const struct rtc_class_ops test_rtc_ops = {
@@ -76,7 +61,7 @@ static const struct rtc_class_ops test_rtc_ops = {
        .read_alarm = test_rtc_read_alarm,
        .set_alarm = test_rtc_set_alarm,
        .set_mmss = test_rtc_set_mmss,
-       .ioctl = test_rtc_ioctl,
+       .alarm_irq_enable = test_rtc_alarm_irq_enable,
 };
 
 static ssize_t test_irq_show(struct device *dev,
index c324424..769190a 100644 (file)
@@ -240,26 +240,6 @@ static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled)
 static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
        switch (cmd) {
-       case RTC_AIE_ON:
-               spin_lock_irq(&rtc_lock);
-
-               if (!alarm_enabled) {
-                       enable_irq(aie_irq);
-                       alarm_enabled = 1;
-               }
-
-               spin_unlock_irq(&rtc_lock);
-               break;
-       case RTC_AIE_OFF:
-               spin_lock_irq(&rtc_lock);
-
-               if (alarm_enabled) {
-                       disable_irq(aie_irq);
-                       alarm_enabled = 0;
-               }
-
-               spin_unlock_irq(&rtc_lock);
-               break;
        case RTC_EPOCH_READ:
                return put_user(epoch, (unsigned long __user *)arg);
        case RTC_EPOCH_SET:
@@ -275,6 +255,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
        return 0;
 }
 
+static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       spin_lock_irq(&rtc_lock);
+       if (enabled) {
+               if (!alarm_enabled) {
+                       enable_irq(aie_irq);
+                       alarm_enabled = 1;
+               }
+       } else {
+               if (alarm_enabled) {
+                       disable_irq(aie_irq);
+                       alarm_enabled = 0;
+               }
+       }
+       spin_unlock_irq(&rtc_lock);
+       return 0;
+}
+
 static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = (struct platform_device *)dev_id;
index 56f60c8..2c665fc 100644 (file)
@@ -509,9 +509,11 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
        bytes_done = 0;
 
        while (bytes_done < t->len) {
+               void *rx_buf = t->rx_buf ? t->rx_buf + bytes_done : NULL;
+               const void *tx_buf = t->tx_buf ? t->tx_buf + bytes_done : NULL;
                n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo,
-                                          t->tx_buf + bytes_done,
-                                          t->rx_buf + bytes_done,
+                                          tx_buf,
+                                          rx_buf,
                                           words, bits);
                if (n < 0)
                        break;
index c7345db..f853379 100644 (file)
@@ -733,7 +733,7 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
 
        /* Fetch the vendor specific tuples. */
        res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
-                               ssb_pcmcia_do_get_invariants, sprom);
+                               ssb_pcmcia_do_get_invariants, iv);
        if ((res == 0) || (res == -ENOSPC))
                return 0;
 
index f123588..cd8392b 100644 (file)
@@ -263,9 +263,7 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
        switch (type) {
        case NL80211_CHAN_HT20:
        case NL80211_CHAN_NO_HT:
-               WL_LOCK(wl);
                err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value);
-               WL_UNLOCK(wl);
                break;
        case NL80211_CHAN_HT40MINUS:
        case NL80211_CHAN_HT40PLUS:
@@ -285,6 +283,7 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
        int err = 0;
        int new_int;
 
+       WL_LOCK(wl);
        if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
                WL_NONE("%s: Setting listen interval to %d\n",
                        __func__, conf->listen_interval);
@@ -341,6 +340,7 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
        }
 
  config_out:
+       WL_UNLOCK(wl);
        return err;
 }
 
@@ -459,13 +459,21 @@ wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
 
 static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
 {
+       struct wl_info *wl = hw->priv;
        WL_NONE("Scan Start\n");
+       WL_LOCK(wl);
+       wlc_scan_start(wl->wlc);
+       WL_UNLOCK(wl);
        return;
 }
 
 static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
 {
+       struct wl_info *wl = hw->priv;
        WL_NONE("Scan Complete\n");
+       WL_LOCK(wl);
+       wlc_scan_stop(wl->wlc);
+       WL_UNLOCK(wl);
        return;
 }
 
index a130386..e37e805 100644 (file)
@@ -8461,3 +8461,16 @@ static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh,
 
        kfree(qi);
 }
+
+/*
+ * Flag 'scan in progress' to withold dynamic phy calibration
+ */
+void wlc_scan_start(struct wlc_info *wlc)
+{
+       wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
+}
+
+void wlc_scan_stop(struct wlc_info *wlc)
+{
+       wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
+}
index 146a690..aff4130 100644 (file)
@@ -570,6 +570,8 @@ extern void wlc_enable_mac(struct wlc_info *wlc);
 extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate);
 extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg);
 extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg);
+extern void wlc_scan_start(struct wlc_info *wlc);
+extern void wlc_scan_stop(struct wlc_info *wlc);
 
 static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name,
                                    uint *arg)
index aad4732..1502d80 100644 (file)
@@ -439,6 +439,7 @@ config COMEDI_NI_AT_AO
 config COMEDI_NI_ATMIO
        tristate "NI AT-MIO E series ISA-PNP card support"
        depends on ISAPNP && COMEDI_NI_TIO && COMEDI_NI_COMMON
+       select COMEDI_8255
        default N
        ---help---
          Enable support for National Instruments AT-MIO E series cards
@@ -1040,6 +1041,8 @@ config COMEDI_NI_PCIDIO
 config COMEDI_NI_PCIMIO
        tristate "NI PCI-MIO-E series and M series support"
        depends on COMEDI_NI_TIO && COMEDI_NI_COMMON
+       select COMEDI_8255
+       select COMEDI_FC
        default N
        ---help---
          Enable support for National Instruments PCI-MIO-E series and M series
@@ -1164,6 +1167,7 @@ config COMEDI_NI_LABPC_CS
 config COMEDI_NI_MIO_CS
        tristate "NI DAQCard E series PCMCIA support"
        depends on COMEDI_NI_TIO && COMEDI_NI_COMMON
+       select COMEDI_8255
        select COMEDI_FC
        default N
        ---help---
@@ -1268,7 +1272,6 @@ config COMEDI_MITE
 config COMEDI_NI_TIO
        tristate "NI general purpose counter support"
        depends on COMEDI_MITE
-       select COMEDI_8255
        default N
        ---help---
          Enable support for National Instruments general purpose counters.
index cd25b24..fd274e9 100644 (file)
@@ -61,8 +61,6 @@
 #define PCI_DAQ_SIZE           4096
 #define PCI_DAQ_SIZE_660X       8192
 
-MODULE_LICENSE("GPL");
-
 struct mite_struct *mite_devices;
 EXPORT_SYMBOL(mite_devices);
 
index 14e716e..54741c9 100644 (file)
@@ -527,3 +527,7 @@ static void __exit driver_ni6527_cleanup_module(void)
 
 module_init(driver_ni6527_init_module);
 module_exit(driver_ni6527_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 8b8e2aa..403fc09 100644 (file)
@@ -871,3 +871,7 @@ static void __exit driver_ni_65xx_cleanup_module(void)
 
 module_init(driver_ni_65xx_init_module);
 module_exit(driver_ni_65xx_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 6612b08..ca2aeaa 100644 (file)
@@ -1421,3 +1421,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev,
        };
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index e9f034e..d8d91f9 100644 (file)
@@ -384,3 +384,7 @@ static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot)
        mite_list_devices();
        return -EIO;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 84a15c3..005d2fe 100644 (file)
@@ -1354,3 +1354,7 @@ static void __exit driver_pcidio_cleanup_module(void)
 
 module_init(driver_pcidio_init_module);
 module_exit(driver_pcidio_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 23a3812..9148abd 100644 (file)
@@ -1853,3 +1853,7 @@ static int pcimio_dio_change(struct comedi_device *dev,
 
        return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");
index 54706a1..b41c964 100644 (file)
@@ -236,6 +236,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj,
        if (status == 1) {
                netif_carrier_on(net);
                netif_wake_queue(net);
+               netif_notify_peers(net);
        } else {
                netif_carrier_off(net);
                netif_stop_queue(net);
index e38e89d..e2f6d6a 100644 (file)
@@ -874,7 +874,10 @@ static int nc_set_selected_input_dev(u8 value)
                sc_access[3].reg_addr = 0x109;
                sc_access[3].mask = MASK6;
                sc_access[3].value = 0x00;
-               num_val = 4;
+               sc_access[4].reg_addr = 0x104;
+               sc_access[4].value = 0x3C;
+               sc_access[4].mask = 0xff;
+               num_val = 5;
                break;
        default:
                return -EINVAL;
index 5415712..4bd8cbd 100644 (file)
@@ -227,6 +227,7 @@ static int zram_read(struct zram *zram, struct bio *bio)
 
                if (zram_test_flag(zram, index, ZRAM_ZERO)) {
                        handle_zero_page(page);
+                       index++;
                        continue;
                }
 
@@ -235,12 +236,14 @@ static int zram_read(struct zram *zram, struct bio *bio)
                        pr_debug("Read before write: sector=%lu, size=%u",
                                (ulong)(bio->bi_sector), bio->bi_size);
                        /* Do nothing */
+                       index++;
                        continue;
                }
 
                /* Page is stored uncompressed since it's incompressible */
                if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) {
                        handle_uncompressed_page(zram, page, index);
+                       index++;
                        continue;
                }
 
@@ -320,6 +323,7 @@ static int zram_write(struct zram *zram, struct bio *bio)
                        mutex_unlock(&zram->lock);
                        zram_stat_inc(&zram->stats.pages_zero);
                        zram_set_flag(zram, index, ZRAM_ZERO);
+                       index++;
                        continue;
                }
 
index e6bed5f..d79e7e9 100644 (file)
@@ -10,4 +10,3 @@ obj-$(CONFIG_HVC_XEN)         += hvc_xen.o
 obj-$(CONFIG_HVC_IUCV)         += hvc_iucv.o
 obj-$(CONFIG_HVC_UDBG)         += hvc_udbg.o
 obj-$(CONFIG_HVCS)             += hvcs.o
-obj-$(CONFIG_VIRTIO_CONSOLE)   += virtio_console.o
index 44b8412..aa2e5d3 100644 (file)
@@ -2414,6 +2414,7 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm,
 
        gsm->initiator = c->initiator;
        gsm->mru = c->mru;
+       gsm->mtu = c->mtu;
        gsm->encoding = c->encapsulation;
        gsm->adaption = c->adaption;
        gsm->n2 = c->n2;
index be0ebce..de0160e 100644 (file)
@@ -262,7 +262,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
 
 static void receive_chars(struct m68k_serial *info, unsigned short rx)
 {
-       struct tty_struct *tty = info->port.tty;
+       struct tty_struct *tty = info->tty;
        m68328_uart *uart = &uart_addr[info->line];
        unsigned char ch, flag;
 
@@ -329,7 +329,7 @@ static void transmit_chars(struct m68k_serial *info)
                goto clear_and_return;
        }
 
-       if((info->xmit_cnt <= 0) || info->port.tty->stopped) {
+       if((info->xmit_cnt <= 0) || info->tty->stopped) {
                /* That's peculiar... TX ints off */
                uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
                goto clear_and_return;
@@ -383,7 +383,7 @@ static void do_softint(struct work_struct *work)
        struct m68k_serial      *info = container_of(work, struct m68k_serial, tqueue);
        struct tty_struct       *tty;
        
-       tty = info->port.tty;
+       tty = info->tty;
        if (!tty)
                return;
 #if 0
@@ -407,7 +407,7 @@ static void do_serial_hangup(struct work_struct *work)
        struct m68k_serial      *info = container_of(work, struct m68k_serial, tqueue_hangup);
        struct tty_struct       *tty;
        
-       tty = info->port.tty;
+       tty = info->tty;
        if (!tty)
                return;
 
@@ -451,8 +451,8 @@ static int startup(struct m68k_serial * info)
        uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
 #endif
 
-       if (info->port.tty)
-               clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
+       if (info->tty)
+               clear_bit(TTY_IO_ERROR, &info->tty->flags);
        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 
        /*
@@ -486,8 +486,8 @@ static void shutdown(struct m68k_serial * info)
                info->xmit_buf = 0;
        }
 
-       if (info->port.tty)
-               set_bit(TTY_IO_ERROR, &info->port.tty->flags);
+       if (info->tty)
+               set_bit(TTY_IO_ERROR, &info->tty->flags);
        
        info->flags &= ~S_INITIALIZED;
        local_irq_restore(flags);
@@ -553,9 +553,9 @@ static void change_speed(struct m68k_serial *info)
        unsigned cflag;
        int     i;
 
-       if (!info->port.tty || !info->port.tty->termios)
+       if (!info->tty || !info->tty->termios)
                return;
-       cflag = info->port.tty->termios->c_cflag;
+       cflag = info->tty->termios->c_cflag;
        if (!(port = info->port))
                return;
 
@@ -970,7 +970,6 @@ static void send_break(struct m68k_serial * info, unsigned int duration)
 static int rs_ioctl(struct tty_struct *tty, struct file * file,
                    unsigned int cmd, unsigned long arg)
 {
-       int error;
        struct m68k_serial * info = (struct m68k_serial *)tty->driver_data;
        int retval;
 
@@ -1104,7 +1103,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
        tty_ldisc_flush(tty);
        tty->closing = 0;
        info->event = 0;
-       info->port.tty = NULL;
+       info->tty = NULL;
 #warning "This is not and has never been valid so fix it"      
 #if 0
        if (tty->ldisc.num != ldiscs[N_TTY].num) {
@@ -1142,7 +1141,7 @@ void rs_hangup(struct tty_struct *tty)
        info->event = 0;
        info->count = 0;
        info->flags &= ~S_NORMAL_ACTIVE;
-       info->port.tty = NULL;
+       info->tty = NULL;
        wake_up_interruptible(&info->open_wait);
 }
 
@@ -1261,7 +1260,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
 
        info->count++;
        tty->driver_data = info;
-       info->port.tty = tty;
+       info->tty = tty;
 
        /*
         * Start up serial port
@@ -1338,7 +1337,7 @@ rs68328_init(void)
            info = &m68k_soft[i];
            info->magic = SERIAL_MAGIC;
            info->port = (int) &uart_addr[i];
-           info->port.tty = NULL;
+           info->tty = NULL;
            info->irq = uart_irqs[i];
            info->custom_divisor = 16;
            info->close_delay = 50;
index 88b1335..bc21eea 100644 (file)
@@ -2428,6 +2428,7 @@ static const struct tty_operations rs_360_ops = {
        /* .read_proc = rs_360_read_proc, */
        .tiocmget = rs_360_tiocmget,
        .tiocmset = rs_360_tiocmset,
+       .get_icount = rs_360_get_icount,
 };
 
 static int __init rs_360_init(void)
index e381b89..9b1ff2b 100644 (file)
@@ -370,10 +370,8 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id)
 {
        struct bfin_serial_port *uart = dev_id;
 
-       spin_lock(&uart->port.lock);
        while (UART_GET_LSR(uart) & DR)
                bfin_serial_rx_chars(uart);
-       spin_unlock(&uart->port.lock);
 
        return IRQ_HANDLED;
 }
@@ -490,9 +488,8 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
 {
        int x_pos, pos;
 
-       dma_disable_irq(uart->tx_dma_channel);
-       dma_disable_irq(uart->rx_dma_channel);
-       spin_lock_bh(&uart->port.lock);
+       dma_disable_irq_nosync(uart->rx_dma_channel);
+       spin_lock_bh(&uart->rx_lock);
 
        /* 2D DMA RX buffer ring is used. Because curr_y_count and
         * curr_x_count can't be read as an atomic operation,
@@ -523,8 +520,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
                uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
        }
 
-       spin_unlock_bh(&uart->port.lock);
-       dma_enable_irq(uart->tx_dma_channel);
+       spin_unlock_bh(&uart->rx_lock);
        dma_enable_irq(uart->rx_dma_channel);
 
        mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
@@ -571,7 +567,7 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id)
        unsigned short irqstat;
        int x_pos, pos;
 
-       spin_lock(&uart->port.lock);
+       spin_lock(&uart->rx_lock);
        irqstat = get_dma_curr_irqstat(uart->rx_dma_channel);
        clear_dma_irqstat(uart->rx_dma_channel);
 
@@ -589,7 +585,7 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id)
                uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
        }
 
-       spin_unlock(&uart->port.lock);
+       spin_unlock(&uart->rx_lock);
 
        return IRQ_HANDLED;
 }
@@ -1332,6 +1328,7 @@ static int bfin_serial_probe(struct platform_device *pdev)
                }
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
+               spin_lock_init(&uart->rx_lock);
                uart->tx_done       = 1;
                uart->tx_count      = 0;
 
index 8e0dd25..81f1395 100644 (file)
@@ -571,6 +571,7 @@ struct sysrq_state {
        unsigned int alt_use;
        bool active;
        bool need_reinject;
+       bool reinjecting;
 };
 
 static void sysrq_reinject_alt_sysrq(struct work_struct *work)
@@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
        unsigned int alt_code = sysrq->alt_use;
 
        if (sysrq->need_reinject) {
+               /* we do not want the assignment to be reordered */
+               sysrq->reinjecting = true;
+               mb();
+
                /* Simulate press and release of Alt + SysRq */
                input_inject_event(handle, EV_KEY, alt_code, 1);
                input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
@@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
                input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
                input_inject_event(handle, EV_KEY, alt_code, 0);
                input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+
+               mb();
+               sysrq->reinjecting = false;
        }
 }
 
@@ -599,6 +607,13 @@ static bool sysrq_filter(struct input_handle *handle,
        bool was_active = sysrq->active;
        bool suppress;
 
+       /*
+        * Do not filter anything if we are in the process of re-injecting
+        * Alt+SysRq combination.
+        */
+       if (sysrq->reinjecting)
+               return false;
+
        switch (type) {
 
        case EV_SYN:
@@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_handle *handle,
                                sysrq->alt_use = sysrq->alt;
                                /*
                                 * If nothing else will be pressed we'll need
-                                * to re-inject Alt-SysRq keysroke.
+                                * to re-inject Alt-SysRq keysroke.
                                 */
                                sysrq->need_reinject = true;
                        }
index d6ede98..4ab49d4 100644 (file)
@@ -1607,6 +1607,7 @@ static const struct usb_device_id acm_ids[] = {
        { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */
        { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */
        { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */
+       { NOKIA_PCSUITE_ACM_INFO(0x0302), }, /* Nokia N8 */
        { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */
 
        /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
index 6a95017..e935f71 100644 (file)
@@ -1955,7 +1955,6 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
 
        dev_dbg(&rhdev->dev, "usb %s%s\n",
                        (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume");
-       clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
        if (!hcd->driver->bus_resume)
                return -ENOENT;
        if (hcd->state == HC_STATE_RUNNING)
@@ -1963,6 +1962,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
 
        hcd->state = HC_STATE_RESUMING;
        status = hcd->driver->bus_resume(hcd);
+       clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
        if (status == 0) {
                /* TRSMRCY = 10 msec */
                msleep(10);
index 4310cc4..d041c68 100644 (file)
@@ -2753,6 +2753,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                udev->ttport = hdev->ttport;
        } else if (udev->speed != USB_SPEED_HIGH
                        && hdev->speed == USB_SPEED_HIGH) {
+               if (!hub->tt.hub) {
+                       dev_err(&udev->dev, "parent hub has no TT\n");
+                       retval = -EINVAL;
+                       goto fail;
+               }
                udev->tt = &hub->tt;
                udev->ttport = port1;
        }
index 06bb9d4..d500996 100644 (file)
@@ -546,6 +546,8 @@ config USB_GADGET_CI13XXX_MSM
          ci13xxx_udc core.
          This driver depends on OTG driver for PHY initialization,
          clock management, powering up VBUS, and power management.
+         This driver is not supported on boards like trout which
+         has an external PHY.
 
          Say "y" to link the driver statically, or "m" to build a
          dynamically linked module called "ci13xxx_msm" and force all
index b5dbb23..6d8e533 100644 (file)
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/usb/composite.h>
 
 #include "gadget_chips.h"
 
@@ -2763,7 +2764,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
                        return ERR_PTR(-ENOMEM);
                common->free_storage_on_release = 1;
        } else {
-               memset(common, 0, sizeof common);
+               memset(common, 0, sizeof *common);
                common->free_storage_on_release = 0;
        }
 
index 20d43da..0151185 100644 (file)
@@ -258,7 +258,7 @@ static int pipe_buffer_setting(struct r8a66597 *r8a66597,
                break;
        case R8A66597_BULK:
                /* isochronous pipes may be used as bulk pipes */
-               if (info->pipe > R8A66597_BASE_PIPENUM_BULK)
+               if (info->pipe >= R8A66597_BASE_PIPENUM_BULK)
                        bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK;
                else
                        bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC;
index 24046c0..0e6afa2 100644 (file)
@@ -151,6 +151,8 @@ config USB_EHCI_MSM
          Qualcomm chipsets. Root Hub has inbuilt TT.
          This driver depends on OTG driver for PHY initialization,
          clock management, powering up VBUS, and power management.
+         This driver is not supported on boards like trout which
+         has an external PHY.
 
 config USB_EHCI_HCD_PPC_OF
        bool "EHCI support for PPC USB controller on OF platform bus"
index 2baf8a8..a869e3c 100644 (file)
@@ -227,8 +227,8 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
         * mark HW unaccessible.  The PM and USB cores make sure that
         * the root hub is either suspended or stopped.
         */
-       spin_lock_irqsave(&ehci->lock, flags);
        ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
+       spin_lock_irqsave(&ehci->lock, flags);
        ehci_writel(ehci, 0, &ehci->regs->intr_enable);
        (void)ehci_readl(ehci, &ehci->regs->intr_enable);
 
index 796ea0c..8a515f0 100644 (file)
@@ -111,6 +111,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
 {
        int             port;
        u32             temp;
+       unsigned long   flags;
 
        /* If remote wakeup is enabled for the root hub but disabled
         * for the controller, we must adjust all the port wakeup flags
@@ -120,6 +121,8 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
        if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup)
                return;
 
+       spin_lock_irqsave(&ehci->lock, flags);
+
        /* clear phy low-power mode before changing wakeup flags */
        if (ehci->has_hostpc) {
                port = HCS_N_PORTS(ehci->hcs_params);
@@ -131,7 +134,9 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
                        temp = ehci_readl(ehci, hostpc_reg);
                        ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
                }
+               spin_unlock_irqrestore(&ehci->lock, flags);
                msleep(5);
+               spin_lock_irqsave(&ehci->lock, flags);
        }
 
        port = HCS_N_PORTS(ehci->hcs_params);
@@ -170,6 +175,8 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
        /* Does the root hub have a port wakeup pending? */
        if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD))
                usb_hcd_resume_root_hub(ehci_to_hcd(ehci));
+
+       spin_unlock_irqrestore(&ehci->lock, flags);
 }
 
 static int ehci_bus_suspend (struct usb_hcd *hcd)
index 680f2ef..f784ceb 100644 (file)
@@ -796,7 +796,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
        hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
                        dev_name(&pdev->dev));
        if (!hcd) {
-               dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
+               dev_err(&pdev->dev, "failed to create hcd with err %d\n", ret);
                ret = -ENOMEM;
                goto err_create_hcd;
        }
@@ -864,7 +864,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 
        ret = omap_start_ehc(omap, hcd);
        if (ret) {
-               dev_dbg(&pdev->dev, "failed to start ehci\n");
+               dev_err(&pdev->dev, "failed to start ehci with err %d\n", ret);
                goto err_start;
        }
 
@@ -879,7 +879,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 
        ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
        if (ret) {
-               dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
+               dev_err(&pdev->dev, "failed to add hcd with err %d\n", ret);
                goto err_add_hcd;
        }
 
index bed07d4..07bb982 100644 (file)
@@ -367,8 +367,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
         * mark HW unaccessible.  The PM and USB cores make sure that
         * the root hub is either suspended or stopped.
         */
-       spin_lock_irqsave (&ehci->lock, flags);
        ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup);
+       spin_lock_irqsave (&ehci->lock, flags);
        ehci_writel(ehci, 0, &ehci->regs->intr_enable);
        (void)ehci_readl(ehci, &ehci->regs->intr_enable);
 
index 990f06b..2e9602a 100644 (file)
@@ -861,6 +861,7 @@ static int sl811h_urb_enqueue(
                        DBG("dev %d ep%d maxpacket %d\n",
                                udev->devnum, epnum, ep->maxpacket);
                        retval = -EINVAL;
+                       kfree(ep);
                        goto fail;
                }
 
index eeba228..9d49d1c 100644 (file)
@@ -404,6 +404,7 @@ static int bfin_musb_init(struct musb *musb)
                musb->xceiv->set_power = bfin_musb_set_power;
 
        musb->isr = blackfin_interrupt;
+       musb->double_buffer_not_ok = true;
 
        return 0;
 }
index 07cf394..54a8bd1 100644 (file)
@@ -128,12 +128,7 @@ MODULE_ALIAS("platform:" MUSB_DRIVER_NAME);
 
 static inline struct musb *dev_to_musb(struct device *dev)
 {
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-       /* usbcore insists dev->driver_data is a "struct hcd *" */
-       return hcd_to_musb(dev_get_drvdata(dev));
-#else
        return dev_get_drvdata(dev);
-#endif
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1876,10 +1871,9 @@ allocate_instance(struct device *dev,
        musb = kzalloc(sizeof *musb, GFP_KERNEL);
        if (!musb)
                return NULL;
-       dev_set_drvdata(dev, musb);
 
 #endif
-
+       dev_set_drvdata(dev, musb);
        musb->mregs = mbase;
        musb->ctrl_base = mbase;
        musb->nIrq = -ENODEV;
@@ -2191,7 +2185,7 @@ static int __init musb_probe(struct platform_device *pdev)
        void __iomem    *base;
 
        iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!iomem || irq == 0)
+       if (!iomem || irq <= 0)
                return -ENODEV;
 
        base = ioremap(iomem->start, resource_size(iomem));
index d0c236f..d74a811 100644 (file)
@@ -488,6 +488,18 @@ struct musb {
        unsigned                set_address:1;
        unsigned                test_mode:1;
        unsigned                softconnect:1;
+       /*
+        * FIXME: Remove this flag.
+        *
+        * This is only added to allow Blackfin to work
+        * with current driver. For some unknown reason
+        * Blackfin doesn't work with double buffering
+        * and that's enabled by default.
+        *
+        * We added this flag to forcefully disable double
+        * buffering until we get it working.
+        */
+       unsigned                double_buffer_not_ok:1 __deprecated;
 
        u8                      address;
        u8                      test_mode_nr;
index 916065b..3a97c4e 100644 (file)
@@ -169,6 +169,9 @@ struct dma_controller {
                                                        dma_addr_t dma_addr,
                                                        u32 length);
        int                     (*channel_abort)(struct dma_channel *);
+       int                     (*is_compatible)(struct dma_channel *channel,
+                                                       u16 maxpacket,
+                                                       void *buf, u32 length);
 };
 
 /* called after channel_program(), may indicate a fault */
index ed58c6c..2fe3046 100644 (file)
 
 /* ----------------------------------------------------------------------- */
 
+#define is_buffer_mapped(req) (is_dma_capable() && \
+                                       (req->map_state != UN_MAPPED))
+
 /* Maps the buffer to dma  */
 
 static inline void map_dma_buffer(struct musb_request *request,
-                               struct musb *musb)
+                       struct musb *musb, struct musb_ep *musb_ep)
 {
+       int compatible = true;
+       struct dma_controller *dma = musb->dma_controller;
+
+       request->map_state = UN_MAPPED;
+
+       if (!is_dma_capable() || !musb_ep->dma)
+               return;
+
+       /* Check if DMA engine can handle this request.
+        * DMA code must reject the USB request explicitly.
+        * Default behaviour is to map the request.
+        */
+       if (dma->is_compatible)
+               compatible = dma->is_compatible(musb_ep->dma,
+                               musb_ep->packet_sz, request->request.buf,
+                               request->request.length);
+       if (!compatible)
+               return;
+
        if (request->request.dma == DMA_ADDR_INVALID) {
                request->request.dma = dma_map_single(
                                musb->controller,
@@ -105,7 +127,7 @@ static inline void map_dma_buffer(struct musb_request *request,
                                request->tx
                                        ? DMA_TO_DEVICE
                                        : DMA_FROM_DEVICE);
-               request->mapped = 1;
+               request->map_state = MUSB_MAPPED;
        } else {
                dma_sync_single_for_device(musb->controller,
                        request->request.dma,
@@ -113,7 +135,7 @@ static inline void map_dma_buffer(struct musb_request *request,
                        request->tx
                                ? DMA_TO_DEVICE
                                : DMA_FROM_DEVICE);
-               request->mapped = 0;
+               request->map_state = PRE_MAPPED;
        }
 }
 
@@ -121,11 +143,14 @@ static inline void map_dma_buffer(struct musb_request *request,
 static inline void unmap_dma_buffer(struct musb_request *request,
                                struct musb *musb)
 {
+       if (!is_buffer_mapped(request))
+               return;
+
        if (request->request.dma == DMA_ADDR_INVALID) {
                DBG(20, "not unmapping a never mapped buffer\n");
                return;
        }
-       if (request->mapped) {
+       if (request->map_state == MUSB_MAPPED) {
                dma_unmap_single(musb->controller,
                        request->request.dma,
                        request->request.length,
@@ -133,16 +158,15 @@ static inline void unmap_dma_buffer(struct musb_request *request,
                                ? DMA_TO_DEVICE
                                : DMA_FROM_DEVICE);
                request->request.dma = DMA_ADDR_INVALID;
-               request->mapped = 0;
-       } else {
+       } else { /* PRE_MAPPED */
                dma_sync_single_for_cpu(musb->controller,
                        request->request.dma,
                        request->request.length,
                        request->tx
                                ? DMA_TO_DEVICE
                                : DMA_FROM_DEVICE);
-
        }
+       request->map_state = UN_MAPPED;
 }
 
 /*
@@ -172,8 +196,7 @@ __acquires(ep->musb->lock)
 
        ep->busy = 1;
        spin_unlock(&musb->lock);
-       if (is_dma_capable() && ep->dma)
-               unmap_dma_buffer(req, musb);
+       unmap_dma_buffer(req, musb);
        if (request->status == 0)
                DBG(5, "%s done request %p,  %d/%d\n",
                                ep->end_point.name, request,
@@ -335,7 +358,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
                        csr);
 
 #ifndef        CONFIG_MUSB_PIO_ONLY
-       if (is_dma_capable() && musb_ep->dma) {
+       if (is_buffer_mapped(req)) {
                struct dma_controller   *c = musb->dma_controller;
                size_t request_size;
 
@@ -436,8 +459,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
                 * Unmap the dma buffer back to cpu if dma channel
                 * programming fails
                 */
-               if (is_dma_capable() && musb_ep->dma)
-                       unmap_dma_buffer(req, musb);
+               unmap_dma_buffer(req, musb);
 
                musb_write_fifo(musb_ep->hw_ep, fifo_count,
                                (u8 *) (request->buf + request->actual));
@@ -627,7 +649,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                return;
        }
 
-       if (is_cppi_enabled() && musb_ep->dma) {
+       if (is_cppi_enabled() && is_buffer_mapped(req)) {
                struct dma_controller   *c = musb->dma_controller;
                struct dma_channel      *channel = musb_ep->dma;
 
@@ -658,7 +680,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                len = musb_readw(epio, MUSB_RXCOUNT);
                if (request->actual < request->length) {
 #ifdef CONFIG_USB_INVENTRA_DMA
-                       if (is_dma_capable() && musb_ep->dma) {
+                       if (is_buffer_mapped(req)) {
                                struct dma_controller   *c;
                                struct dma_channel      *channel;
                                int                     use_dma = 0;
@@ -742,7 +764,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                        fifo_count = min_t(unsigned, len, fifo_count);
 
 #ifdef CONFIG_USB_TUSB_OMAP_DMA
-                       if (tusb_dma_omap() && musb_ep->dma) {
+                       if (tusb_dma_omap() && is_buffer_mapped(req)) {
                                struct dma_controller *c = musb->dma_controller;
                                struct dma_channel *channel = musb_ep->dma;
                                u32 dma_addr = request->dma + request->actual;
@@ -762,7 +784,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                         * programming fails. This buffer is mapped if the
                         * channel allocation is successful
                         */
-                        if (is_dma_capable() && musb_ep->dma) {
+                        if (is_buffer_mapped(req)) {
                                unmap_dma_buffer(req, musb);
 
                                /*
@@ -989,7 +1011,11 @@ static int musb_gadget_enable(struct usb_ep *ep,
                /* Set TXMAXP with the FIFO size of the endpoint
                 * to disable double buffering mode.
                 */
-               musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
+               if (musb->double_buffer_not_ok)
+                       musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
+               else
+                       musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz
+                                       | (musb_ep->hb_mult << 11));
 
                csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
                if (musb_readw(regs, MUSB_TXCSR)
@@ -1025,7 +1051,11 @@ static int musb_gadget_enable(struct usb_ep *ep,
                /* Set RXMAXP with the FIFO size of the endpoint
                 * to disable double buffering mode.
                 */
-               musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
+               if (musb->double_buffer_not_ok)
+                       musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_tx);
+               else
+                       musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz
+                                       | (musb_ep->hb_mult << 11));
 
                /* force shared fifo to OUT-only mode */
                if (hw_ep->is_shared_fifo) {
@@ -1214,10 +1244,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
        request->epnum = musb_ep->current_epnum;
        request->tx = musb_ep->is_in;
 
-       if (is_dma_capable() && musb_ep->dma)
-               map_dma_buffer(request, musb);
-       else
-               request->mapped = 0;
+       map_dma_buffer(request, musb, musb_ep);
 
        spin_lock_irqsave(&musb->lock, lockflags);
 
index dec8dc0..a55354f 100644 (file)
 #ifndef __MUSB_GADGET_H
 #define __MUSB_GADGET_H
 
+enum buffer_map_state {
+       UN_MAPPED = 0,
+       PRE_MAPPED,
+       MUSB_MAPPED
+};
+
 struct musb_request {
        struct usb_request      request;
        struct musb_ep          *ep;
        struct musb             *musb;
        u8 tx;                  /* endpoint direction */
        u8 epnum;
-       u8 mapped;
+       enum buffer_map_state map_state;
 };
 
 static inline struct musb_request *to_musb_request(struct usb_request *req)
index 4d5bcb4..0f523d7 100644 (file)
@@ -609,7 +609,7 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
        /* Set RXMAXP with the FIFO size of the endpoint
         * to disable double buffer mode.
         */
-       if (musb->hwvers < MUSB_HWVERS_2000)
+       if (musb->double_buffer_not_ok)
                musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx);
        else
                musb_writew(ep->regs, MUSB_RXMAXP,
@@ -784,14 +784,13 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
                /* protocol/endpoint/interval/NAKlimit */
                if (epnum) {
                        musb_writeb(epio, MUSB_TXTYPE, qh->type_reg);
-                       if (can_bulk_split(musb, qh->type))
+                       if (musb->double_buffer_not_ok)
                                musb_writew(epio, MUSB_TXMAXP,
-                                       packet_sz
-                                       | ((hw_ep->max_packet_sz_tx /
-                                               packet_sz) - 1) << 11);
+                                               hw_ep->max_packet_sz_tx);
                        else
                                musb_writew(epio, MUSB_TXMAXP,
-                                       packet_sz);
+                                               qh->maxpacket |
+                                               ((qh->hb_mult - 1) << 11));
                        musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg);
                } else {
                        musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg);
index f763d62..21056c9 100644 (file)
@@ -94,24 +94,33 @@ static inline void musb_write_hsdma_addr(void __iomem *mbase,
 {
        musb_writew(mbase,
                MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW),
-               ((u16)((u32) dma_addr & 0xFFFF)));
+               dma_addr);
        musb_writew(mbase,
                MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH),
-               ((u16)(((u32) dma_addr >> 16) & 0xFFFF)));
+               (dma_addr >> 16));
 }
 
 static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel)
 {
-       return musb_readl(mbase,
+       u32 count = musb_readw(mbase,
                MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH));
+
+       count = count << 16;
+
+       count |= musb_readw(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW));
+
+       return count;
 }
 
 static inline void musb_write_hsdma_count(void __iomem *mbase,
                                u8 bchannel, u32 len)
 {
-       musb_writel(mbase,
+       musb_writew(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW),len);
+       musb_writew(mbase,
                MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH),
-               len);
+               (len >> 16));
 }
 
 #endif /* CONFIG_BLACKFIN */
index 9fb875d..9ffc823 100644 (file)
@@ -103,6 +103,8 @@ config USB_MSM_OTG_72K
          required after resetting the hardware and power management.
          This driver is required even for peripheral only or host only
          mode configurations.
+         This driver is not supported on boards like trout which
+         has an external PHY.
 
 config AB8500_USB
         tristate "AB8500 USB Transceiver Driver"
index 4787c0c..f349a36 100644 (file)
@@ -100,6 +100,7 @@ struct ftdi_sio_quirk {
 static int   ftdi_jtag_probe(struct usb_serial *serial);
 static int   ftdi_mtxorb_hack_setup(struct usb_serial *serial);
 static int   ftdi_NDI_device_setup(struct usb_serial *serial);
+static int   ftdi_stmclite_probe(struct usb_serial *serial);
 static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
 static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
 
@@ -123,6 +124,10 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
        .port_probe = ftdi_HE_TIRA1_setup,
 };
 
+static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
+       .probe  = ftdi_stmclite_probe,
+};
+
 /*
  * The 8U232AM has the same API as the sio except for:
  * - it can support MUCH higher baudrates; up to:
@@ -616,6 +621,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) },
        { USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
+       { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) },
        { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
@@ -810,6 +816,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
        { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
@@ -1708,6 +1716,25 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
        return 0;
 }
 
+/*
+ * First and second port on STMCLiteadaptors is reserved for JTAG interface
+ * and the forth port for pio
+ */
+static int ftdi_stmclite_probe(struct usb_serial *serial)
+{
+       struct usb_device *udev = serial->dev;
+       struct usb_interface *interface = serial->interface;
+
+       dbg("%s", __func__);
+
+       if (interface == udev->actconfig->interface[2])
+               return 0;
+
+       dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n");
+
+       return -ENODEV;
+}
+
 /*
  * The Matrix Orbital VK204-25-USB has an invalid IN endpoint.
  * We have to correct it if we want to read from it.
index ed160de..117e8e6 100644 (file)
 #define RATOC_VENDOR_ID                0x0584
 #define RATOC_PRODUCT_ID_USB60F        0xb020
 
+/*
+ * Acton Research Corp.
+ */
+#define ACTON_VID              0x0647  /* Vendor ID */
+#define ACTON_SPECTRAPRO_PID   0x0100
+
 /*
  * Contec products (http://www.contec.com)
  * Submitted by Daniel Sangorrin
 #define STB_PID                        0x0001 /* Sensor Terminal Board */
 #define WHT_PID                        0x0004 /* Wireless Handheld Terminal */
 
+/*
+ * STMicroelectonics
+ */
+#define ST_VID                 0x0483
+#define ST_STMCLT1030_PID      0x3747 /* ST Micro Connect Lite STMCLT1030 */
+
 /*
  * Papouch products (http://www.papouch.com/)
  * Submitted by Folkert van Heusden
index cd769ef..3b246d9 100644 (file)
@@ -2889,8 +2889,8 @@ static void load_application_firmware(struct edgeport_serial *edge_serial)
 
        dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build);
 
-       edge_serial->product_info.FirmwareMajorVersion = fw->data[0];
-       edge_serial->product_info.FirmwareMinorVersion = fw->data[1];
+       edge_serial->product_info.FirmwareMajorVersion = rec->data[0];
+       edge_serial->product_info.FirmwareMinorVersion = rec->data[1];
        edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build);
 
        for (rec = ihex_next_binrec(rec); rec;
index b2902f3..a910004 100644 (file)
@@ -369,9 +369,9 @@ failed_1port:
 
 static void __exit ti_exit(void)
 {
+       usb_deregister(&ti_usb_driver);
        usb_serial_deregister(&ti_1port_device);
        usb_serial_deregister(&ti_2port_device);
-       usb_deregister(&ti_usb_driver);
 }
 
 
index 24bd5d7..c1602b8 100644 (file)
@@ -1397,6 +1397,13 @@ UNUSUAL_DEV(  0x0f19, 0x0105, 0x0100, 0x0100,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
+/* Submitted by Nick Holloway */
+UNUSUAL_DEV( 0x0f88, 0x042e, 0x0100, 0x0100,
+               "VTech",
+               "Kidizoom",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
 /* Reported by Michael Stattmann <michael@stattmann.com> */
 UNUSUAL_DEV(  0x0fce, 0xd008, 0x0000, 0x0000,
                "Sony Ericsson",
@@ -1890,6 +1897,13 @@ UNUSUAL_DEV(  0x1e68, 0x001b, 0x0000, 0x0000,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ),
 
+/* Reported by Jasper Mackenzie <scarletpimpernal@hotmail.com> */
+UNUSUAL_DEV( 0x1e74, 0x4621, 0x0000, 0x0000,
+               "Coby Electronics",
+               "MP3 Player",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ),
+
 UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
                "ST",
                "2A",
index 3a7e9ff..38e96ab 100644 (file)
@@ -593,19 +593,17 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
 
        /* get interface & functional clock objects */
        hdq_data->hdq_ick = clk_get(&pdev->dev, "ick");
-       hdq_data->hdq_fck = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(hdq_data->hdq_ick)) {
+               dev_dbg(&pdev->dev, "Can't get HDQ ick clock object\n");
+               ret = PTR_ERR(hdq_data->hdq_ick);
+               goto err_ick;
+       }
 
-       if (IS_ERR(hdq_data->hdq_ick) || IS_ERR(hdq_data->hdq_fck)) {
-               dev_dbg(&pdev->dev, "Can't get HDQ clock objects\n");
-               if (IS_ERR(hdq_data->hdq_ick)) {
-                       ret = PTR_ERR(hdq_data->hdq_ick);
-                       goto err_clk;
-               }
-               if (IS_ERR(hdq_data->hdq_fck)) {
-                       ret = PTR_ERR(hdq_data->hdq_fck);
-                       clk_put(hdq_data->hdq_ick);
-                       goto err_clk;
-               }
+       hdq_data->hdq_fck = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(hdq_data->hdq_fck)) {
+               dev_dbg(&pdev->dev, "Can't get HDQ fck clock object\n");
+               ret = PTR_ERR(hdq_data->hdq_fck);
+               goto err_fck;
        }
 
        hdq_data->hdq_usecount = 0;
@@ -665,10 +663,12 @@ err_fnclk:
        clk_disable(hdq_data->hdq_ick);
 
 err_intfclk:
-       clk_put(hdq_data->hdq_ick);
        clk_put(hdq_data->hdq_fck);
 
-err_clk:
+err_fck:
+       clk_put(hdq_data->hdq_ick);
+
+err_ick:
        iounmap(hdq_data->hdq_base);
 
 err_ioremap:
index 2e2400e..31649b7 100644 (file)
@@ -862,12 +862,12 @@ config SBC_EPX_C3_WATCHDOG
 
 # M68K Architecture
 
-config M548x_WATCHDOG
-       tristate "MCF548x watchdog support"
+config M54xx_WATCHDOG
+       tristate "MCF54xx watchdog support"
        depends on M548x
        help
          To compile this driver as a module, choose M here: the
-         module will be called m548x_wdt.
+         module will be called m54xx_wdt.
 
 # MIPS Architecture
 
index dd77665..20e44c4 100644 (file)
@@ -106,7 +106,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
 # M32R Architecture
 
 # M68K Architecture
-obj-$(CONFIG_M548x_WATCHDOG) += m548x_wdt.o
+obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o
 
 # MIPS Architecture
 obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o
similarity index 80%
rename from drivers/watchdog/m548x_wdt.c
rename to drivers/watchdog/m54xx_wdt.c
index cabbcfe..4d43286 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * drivers/watchdog/m548x_wdt.c
+ * drivers/watchdog/m54xx_wdt.c
  *
- * Watchdog driver for ColdFire MCF548x processors
+ * Watchdog driver for ColdFire MCF547x & MCF548x processors
  * Copyright 2010 (c) Philippe De Muyter <phdm@macqel.be>
  *
  * Adapted from the IXP4xx watchdog driver, which carries these notices:
@@ -29,8 +29,8 @@
 #include <linux/uaccess.h>
 
 #include <asm/coldfire.h>
-#include <asm/m548xsim.h>
-#include <asm/m548xgpt.h>
+#include <asm/m54xxsim.h>
+#include <asm/m54xxgpt.h>
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 static unsigned int heartbeat = 30;    /* (secs) Default is 0.5 minute */
@@ -76,7 +76,7 @@ static void wdt_keepalive(void)
        __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0);
 }
 
-static int m548x_wdt_open(struct inode *inode, struct file *file)
+static int m54xx_wdt_open(struct inode *inode, struct file *file)
 {
        if (test_and_set_bit(WDT_IN_USE, &wdt_status))
                return -EBUSY;
@@ -86,7 +86,7 @@ static int m548x_wdt_open(struct inode *inode, struct file *file)
        return nonseekable_open(inode, file);
 }
 
-static ssize_t m548x_wdt_write(struct file *file, const char *data,
+static ssize_t m54xx_wdt_write(struct file *file, const char *data,
                                                size_t len, loff_t *ppos)
 {
        if (len) {
@@ -112,10 +112,10 @@ static ssize_t m548x_wdt_write(struct file *file, const char *data,
 static const struct watchdog_info ident = {
        .options        = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
                                WDIOF_KEEPALIVEPING,
-       .identity       = "Coldfire M548x Watchdog",
+       .identity       = "Coldfire M54xx Watchdog",
 };
 
-static long m548x_wdt_ioctl(struct file *file, unsigned int cmd,
+static long m54xx_wdt_ioctl(struct file *file, unsigned int cmd,
                                                         unsigned long arg)
 {
        int ret = -ENOTTY;
@@ -161,7 +161,7 @@ static long m548x_wdt_ioctl(struct file *file, unsigned int cmd,
        return ret;
 }
 
-static int m548x_wdt_release(struct inode *inode, struct file *file)
+static int m54xx_wdt_release(struct inode *inode, struct file *file)
 {
        if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
                wdt_disable();
@@ -177,45 +177,45 @@ static int m548x_wdt_release(struct inode *inode, struct file *file)
 }
 
 
-static const struct file_operations m548x_wdt_fops = {
+static const struct file_operations m54xx_wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
-       .write          = m548x_wdt_write,
-       .unlocked_ioctl = m548x_wdt_ioctl,
-       .open           = m548x_wdt_open,
-       .release        = m548x_wdt_release,
+       .write          = m54xx_wdt_write,
+       .unlocked_ioctl = m54xx_wdt_ioctl,
+       .open           = m54xx_wdt_open,
+       .release        = m54xx_wdt_release,
 };
 
-static struct miscdevice m548x_wdt_miscdev = {
+static struct miscdevice m54xx_wdt_miscdev = {
        .minor          = WATCHDOG_MINOR,
        .name           = "watchdog",
-       .fops           = &m548x_wdt_fops,
+       .fops           = &m54xx_wdt_fops,
 };
 
-static int __init m548x_wdt_init(void)
+static int __init m54xx_wdt_init(void)
 {
        if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4,
-                                               "Coldfire M548x Watchdog")) {
+                                               "Coldfire M54xx Watchdog")) {
                printk(KERN_WARNING
-                               "Coldfire M548x Watchdog : I/O region busy\n");
+                               "Coldfire M54xx Watchdog : I/O region busy\n");
                return -EBUSY;
        }
        printk(KERN_INFO "ColdFire watchdog driver is loaded.\n");
 
-       return misc_register(&m548x_wdt_miscdev);
+       return misc_register(&m54xx_wdt_miscdev);
 }
 
-static void __exit m548x_wdt_exit(void)
+static void __exit m54xx_wdt_exit(void)
 {
-       misc_deregister(&m548x_wdt_miscdev);
+       misc_deregister(&m54xx_wdt_miscdev);
        release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4);
 }
 
-module_init(m548x_wdt_init);
-module_exit(m548x_wdt_exit);
+module_init(m54xx_wdt_init);
+module_exit(m54xx_wdt_exit);
 
 MODULE_AUTHOR("Philippe De Muyter <phdm@macqel.be>");
-MODULE_DESCRIPTION("Coldfire M548x Watchdog");
+MODULE_DESCRIPTION("Coldfire M54xx Watchdog");
 
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 30s)");
index fdce879..e1aa8d6 100644 (file)
@@ -359,10 +359,14 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
 
        tree = &BTRFS_I(page->mapping->host)->io_tree;
 
-       if (page->private == EXTENT_PAGE_PRIVATE)
+       if (page->private == EXTENT_PAGE_PRIVATE) {
+               WARN_ON(1);
                goto out;
-       if (!page->private)
+       }
+       if (!page->private) {
+               WARN_ON(1);
                goto out;
+       }
        len = page->private >> 2;
        WARN_ON(len == 0);
 
index 4e7e012..f3c96fc 100644 (file)
@@ -6583,7 +6583,7 @@ static noinline int relocate_data_extent(struct inode *reloc_inode,
        u64 end = start + extent_key->offset - 1;
 
        em = alloc_extent_map(GFP_NOFS);
-       BUG_ON(!em || IS_ERR(em));
+       BUG_ON(!em);
 
        em->start = start;
        em->len = extent_key->offset;
index 5e76a47..92ac519 100644 (file)
@@ -1946,6 +1946,7 @@ void set_page_extent_mapped(struct page *page)
 
 static void set_page_extent_head(struct page *page, unsigned long len)
 {
+       WARN_ON(!PagePrivate(page));
        set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2);
 }
 
@@ -2821,9 +2822,17 @@ int try_release_extent_state(struct extent_map_tree *map,
                 * at this point we can safely clear everything except the
                 * locked bit and the nodatasum bit
                 */
-               clear_extent_bit(tree, start, end,
+               ret = clear_extent_bit(tree, start, end,
                                 ~(EXTENT_LOCKED | EXTENT_NODATASUM),
                                 0, 0, NULL, mask);
+
+               /* if clear_extent_bit failed for enomem reasons,
+                * we can't allow the release to continue.
+                */
+               if (ret < 0)
+                       ret = 0;
+               else
+                       ret = 1;
        }
        return ret;
 }
@@ -3194,7 +3203,13 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
                }
                if (!PageUptodate(p))
                        uptodate = 0;
-               unlock_page(p);
+
+               /*
+                * see below about how we avoid a nasty race with release page
+                * and why we unlock later
+                */
+               if (i != 0)
+                       unlock_page(p);
        }
        if (uptodate)
                set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
@@ -3218,9 +3233,26 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
        atomic_inc(&eb->refs);
        spin_unlock(&tree->buffer_lock);
        radix_tree_preload_end();
+
+       /*
+        * there is a race where release page may have
+        * tried to find this extent buffer in the radix
+        * but failed.  It will tell the VM it is safe to
+        * reclaim the, and it will clear the page private bit.
+        * We must make sure to set the page private bit properly
+        * after the extent buffer is in the radix tree so
+        * it doesn't get lost
+        */
+       set_page_extent_mapped(eb->first_page);
+       set_page_extent_head(eb->first_page, eb->len);
+       if (!page0)
+               unlock_page(eb->first_page);
        return eb;
 
 free_eb:
+       if (eb->first_page && !page0)
+               unlock_page(eb->first_page);
+
        if (!atomic_dec_and_test(&eb->refs))
                return exists;
        btrfs_release_extent_buffer(eb);
@@ -3271,10 +3303,11 @@ int clear_extent_buffer_dirty(struct extent_io_tree *tree,
                        continue;
 
                lock_page(page);
+               WARN_ON(!PagePrivate(page));
+
+               set_page_extent_mapped(page);
                if (i == 0)
                        set_page_extent_head(page, eb->len);
-               else
-                       set_page_private(page, EXTENT_PAGE_PRIVATE);
 
                clear_page_dirty_for_io(page);
                spin_lock_irq(&page->mapping->tree_lock);
@@ -3464,6 +3497,13 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
 
        for (i = start_i; i < num_pages; i++) {
                page = extent_buffer_page(eb, i);
+
+               WARN_ON(!PagePrivate(page));
+
+               set_page_extent_mapped(page);
+               if (i == 0)
+                       set_page_extent_head(page, eb->len);
+
                if (inc_all_pages)
                        page_cache_get(page);
                if (!PageUptodate(page)) {
index b0e1fce..2b6c12e 100644 (file)
@@ -51,8 +51,8 @@ struct extent_map *alloc_extent_map(gfp_t mask)
 {
        struct extent_map *em;
        em = kmem_cache_alloc(extent_map_cache, mask);
-       if (!em || IS_ERR(em))
-               return em;
+       if (!em)
+               return NULL;
        em->in_tree = 0;
        em->flags = 0;
        em->compress_type = BTRFS_COMPRESS_NONE;
index c1d3a81..7084140 100644 (file)
@@ -186,6 +186,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                        split = alloc_extent_map(GFP_NOFS);
                if (!split2)
                        split2 = alloc_extent_map(GFP_NOFS);
+               BUG_ON(!split || !split2);
 
                write_lock(&em_tree->lock);
                em = lookup_extent_mapping(em_tree, start, len);
index bcc461a..fb9bd78 100644 (file)
@@ -644,6 +644,7 @@ retry:
                                        async_extent->ram_size - 1, 0);
 
                em = alloc_extent_map(GFP_NOFS);
+               BUG_ON(!em);
                em->start = async_extent->start;
                em->len = async_extent->ram_size;
                em->orig_start = em->start;
@@ -820,6 +821,7 @@ static noinline int cow_file_range(struct inode *inode,
                BUG_ON(ret);
 
                em = alloc_extent_map(GFP_NOFS);
+               BUG_ON(!em);
                em->start = start;
                em->orig_start = em->start;
                ram_size = ins.offset;
@@ -1169,6 +1171,7 @@ out_check:
                        struct extent_map_tree *em_tree;
                        em_tree = &BTRFS_I(inode)->extent_tree;
                        em = alloc_extent_map(GFP_NOFS);
+                       BUG_ON(!em);
                        em->start = cur_offset;
                        em->orig_start = em->start;
                        em->len = num_bytes;
index 02d224e..be2d4f6 100644 (file)
@@ -2208,7 +2208,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
        int num_types = 4;
        int alloc_size;
        int ret = 0;
-       int slot_count = 0;
+       u64 slot_count = 0;
        int i, c;
 
        if (copy_from_user(&space_args,
@@ -2247,7 +2247,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
                goto out;
        }
 
-       slot_count = min_t(int, space_args.space_slots, slot_count);
+       slot_count = min_t(u64, space_args.space_slots, slot_count);
 
        alloc_size = sizeof(*dest) * slot_count;
 
@@ -2267,6 +2267,9 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
        for (i = 0; i < num_types; i++) {
                struct btrfs_space_info *tmp;
 
+               if (!slot_count)
+                       break;
+
                info = NULL;
                rcu_read_lock();
                list_for_each_entry_rcu(tmp, &root->fs_info->space_info,
@@ -2288,7 +2291,10 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
                                memcpy(dest, &space, sizeof(space));
                                dest++;
                                space_args.total_spaces++;
+                               slot_count--;
                        }
+                       if (!slot_count)
+                               break;
                }
                up_read(&info->groups_sem);
        }
index 1f5556a..0825e4e 100644 (file)
@@ -1157,6 +1157,7 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
        new_node->bytenr = dest->node->start;
        new_node->level = node->level;
        new_node->lowest = node->lowest;
+       new_node->checked = 1;
        new_node->root = dest;
 
        if (!node->lowest) {
index 2636a05..af7dbca 100644 (file)
@@ -1605,12 +1605,14 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
 
        ret = find_next_devid(root, &device->devid);
        if (ret) {
+               kfree(device->name);
                kfree(device);
                goto error;
        }
 
        trans = btrfs_start_transaction(root, 0);
        if (IS_ERR(trans)) {
+               kfree(device->name);
                kfree(device);
                ret = PTR_ERR(trans);
                goto error;
index edd5b29..17afb0f 100644 (file)
@@ -188,6 +188,8 @@ struct TCP_Server_Info {
        /* multiplexed reads or writes */
        unsigned int maxBuf;    /* maxBuf specifies the maximum */
        /* message size the server can send or receive for non-raw SMBs */
+       /* maxBuf is returned by SMB NegotiateProtocol so maxBuf is only 0 */
+       /* when socket is setup (and during reconnect) before NegProt sent */
        unsigned int max_rw;    /* maxRw specifies the maximum */
        /* message size the server can send or receive for */
        /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
@@ -652,7 +654,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
 #define   MID_REQUEST_SUBMITTED 2
 #define   MID_RESPONSE_RECEIVED 4
 #define   MID_RETRY_NEEDED      8 /* session closed while this request out */
-#define   MID_NO_RESP_NEEDED 0x10
+#define   MID_RESPONSE_MALFORMED 0x10
 
 /* Types of response buffer returned from SendReceive2 */
 #define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
index 257b6d8..8d6c17a 100644 (file)
@@ -338,10 +338,11 @@ cifs_echo_request(struct work_struct *work)
                                        struct TCP_Server_Info, echo.work);
 
        /*
-        * We cannot send an echo until the NEGOTIATE_PROTOCOL request is done.
-        * Also, no need to ping if we got a response recently
+        * We cannot send an echo until the NEGOTIATE_PROTOCOL request is
+        * done, which is indicated by maxBuf != 0. Also, no need to ping if
+        * we got a response recently
         */
-       if (server->tcpStatus != CifsGood ||
+       if (server->maxBuf == 0 ||
            time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
                goto requeue_echo;
 
@@ -585,11 +586,20 @@ incomplete_rcv:
                total_read += 4; /* account for rfc1002 hdr */
 
                dump_smb(smb_buffer, total_read);
-               if (checkSMB(smb_buffer, smb_buffer->Mid, total_read)) {
+
+               /*
+                * We know that we received enough to get to the MID as we
+                * checked the pdu_length earlier. Now check to see
+                * if the rest of the header is OK. We borrow the length
+                * var for the rest of the loop to avoid a new stack var.
+                *
+                * 48 bytes is enough to display the header and a little bit
+                * into the payload for debugging purposes.
+                */
+               length = checkSMB(smb_buffer, smb_buffer->Mid, total_read);
+               if (length != 0)
                        cifs_dump_mem("Bad SMB: ", smb_buffer,
-                                       total_read < 48 ? total_read : 48);
-                       continue;
-               }
+                                       min_t(unsigned int, total_read, 48));
 
                mid_entry = NULL;
                server->lstrp = jiffies;
@@ -601,7 +611,8 @@ incomplete_rcv:
                        if ((mid_entry->mid == smb_buffer->Mid) &&
                            (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
                            (mid_entry->command == smb_buffer->Command)) {
-                               if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
+                               if (length == 0 &&
+                                  check2ndT2(smb_buffer, server->maxBuf) > 0) {
                                        /* We have a multipart transact2 resp */
                                        isMultiRsp = true;
                                        if (mid_entry->resp_buf) {
@@ -636,7 +647,12 @@ incomplete_rcv:
                                mid_entry->resp_buf = smb_buffer;
                                mid_entry->largeBuf = isLargeBuf;
 multi_t2_fnd:
-                               mid_entry->midState = MID_RESPONSE_RECEIVED;
+                               if (length == 0)
+                                       mid_entry->midState =
+                                                       MID_RESPONSE_RECEIVED;
+                               else
+                                       mid_entry->midState =
+                                                       MID_RESPONSE_MALFORMED;
 #ifdef CONFIG_CIFS_STATS2
                                mid_entry->when_received = jiffies;
 #endif
@@ -657,6 +673,9 @@ multi_t2_fnd:
                                else
                                        smallbuf = NULL;
                        }
+               } else if (length != 0) {
+                       /* response sanity checks failed */
+                       continue;
                } else if (!is_valid_oplock_break(smb_buffer, server) &&
                           !isMultiRsp) {
                        cERROR(1, "No task to wake, unknown frame received! "
index fbc5aac..46d8756 100644 (file)
@@ -457,6 +457,9 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
        case MID_RETRY_NEEDED:
                rc = -EAGAIN;
                break;
+       case MID_RESPONSE_MALFORMED:
+               rc = -EIO;
+               break;
        default:
                cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
                        mid->mid, mid->midState);
index 9c64ae9..2d8c87b 100644 (file)
@@ -1468,15 +1468,13 @@ static void work_stop(void)
 
 static int work_start(void)
 {
-       recv_workqueue = alloc_workqueue("dlm_recv", WQ_MEM_RECLAIM |
-                                        WQ_HIGHPRI | WQ_FREEZEABLE, 0);
+       recv_workqueue = create_singlethread_workqueue("dlm_recv");
        if (!recv_workqueue) {
                log_print("can't start dlm_recv");
                return -ENOMEM;
        }
 
-       send_workqueue = alloc_workqueue("dlm_send", WQ_MEM_RECLAIM |
-                                        WQ_HIGHPRI | WQ_FREEZEABLE, 0);
+       send_workqueue = create_singlethread_workqueue("dlm_send");
        if (!send_workqueue) {
                log_print("can't start dlm_send");
                destroy_workqueue(recv_workqueue);
index 0c8d97b..3aa0b72 100644 (file)
@@ -848,6 +848,7 @@ struct ext4_inode_info {
        atomic_t i_ioend_count; /* Number of outstanding io_end structs */
        /* current io_end structure for async DIO write*/
        ext4_io_end_t *cur_aio_dio;
+       atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */
 
        spinlock_t i_block_reservation_lock;
 
@@ -2119,6 +2120,15 @@ static inline void set_bitmap_uptodate(struct buffer_head *bh)
 
 #define in_range(b, first, len)        ((b) >= (first) && (b) <= (first) + (len) - 1)
 
+/* For ioend & aio unwritten conversion wait queues */
+#define EXT4_WQ_HASH_SZ                37
+#define ext4_ioend_wq(v)   (&ext4__ioend_wq[((unsigned long)(v)) %\
+                                           EXT4_WQ_HASH_SZ])
+#define ext4_aio_mutex(v)  (&ext4__aio_mutex[((unsigned long)(v)) %\
+                                            EXT4_WQ_HASH_SZ])
+extern wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
+extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
+
 #endif /* __KERNEL__ */
 
 #endif /* _EXT4_H */
index 63a7581..ccce8a7 100644 (file)
@@ -3174,9 +3174,10 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
                 * that this IO needs to convertion to written when IO is
                 * completed
                 */
-               if (io)
+               if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) {
                        io->flag = EXT4_IO_END_UNWRITTEN;
-               else
+                       atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+               } else
                        ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN);
                if (ext4_should_dioread_nolock(inode))
                        map->m_flags |= EXT4_MAP_UNINIT;
@@ -3463,9 +3464,10 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
                 * that we need to perform convertion when IO is done.
                 */
                if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
-                       if (io)
+                       if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) {
                                io->flag = EXT4_IO_END_UNWRITTEN;
-                       else
+                               atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+                       } else
                                ext4_set_inode_state(inode,
                                                     EXT4_STATE_DIO_UNWRITTEN);
                }
index 2e8322c..7b80d54 100644 (file)
@@ -55,11 +55,47 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
        return 0;
 }
 
+static void ext4_aiodio_wait(struct inode *inode)
+{
+       wait_queue_head_t *wq = ext4_ioend_wq(inode);
+
+       wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_aiodio_unwritten) == 0));
+}
+
+/*
+ * This tests whether the IO in question is block-aligned or not.
+ * Ext4 utilizes unwritten extents when hole-filling during direct IO, and they
+ * are converted to written only after the IO is complete.  Until they are
+ * mapped, these blocks appear as holes, so dio_zero_block() will assume that
+ * it needs to zero out portions of the start and/or end block.  If 2 AIO
+ * threads are at work on the same unwritten block, they must be synchronized
+ * or one thread will zero the other's data, causing corruption.
+ */
+static int
+ext4_unaligned_aio(struct inode *inode, const struct iovec *iov,
+                  unsigned long nr_segs, loff_t pos)
+{
+       struct super_block *sb = inode->i_sb;
+       int blockmask = sb->s_blocksize - 1;
+       size_t count = iov_length(iov, nr_segs);
+       loff_t final_size = pos + count;
+
+       if (pos >= inode->i_size)
+               return 0;
+
+       if ((pos & blockmask) || (final_size & blockmask))
+               return 1;
+
+       return 0;
+}
+
 static ssize_t
 ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
                unsigned long nr_segs, loff_t pos)
 {
        struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
+       int unaligned_aio = 0;
+       int ret;
 
        /*
         * If we have encountered a bitmap-format file, the size limit
@@ -78,9 +114,31 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
                        nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
                                              sbi->s_bitmap_maxbytes - pos);
                }
+       } else if (unlikely((iocb->ki_filp->f_flags & O_DIRECT) &&
+                  !is_sync_kiocb(iocb))) {
+               unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos);
        }
 
-       return generic_file_aio_write(iocb, iov, nr_segs, pos);
+       /* Unaligned direct AIO must be serialized; see comment above */
+       if (unaligned_aio) {
+               static unsigned long unaligned_warn_time;
+
+               /* Warn about this once per day */
+               if (printk_timed_ratelimit(&unaligned_warn_time, 60*60*24*HZ))
+                       ext4_msg(inode->i_sb, KERN_WARNING,
+                                "Unaligned AIO/DIO on inode %ld by %s; "
+                                "performance will be poor.",
+                                inode->i_ino, current->comm);
+               mutex_lock(ext4_aio_mutex(inode));
+               ext4_aiodio_wait(inode);
+       }
+
+       ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+       if (unaligned_aio)
+               mutex_unlock(ext4_aio_mutex(inode));
+
+       return ret;
 }
 
 static const struct vm_operations_struct ext4_file_vm_ops = {
index 851f49b..d1fe09a 100644 (file)
@@ -342,10 +342,15 @@ static struct kmem_cache *ext4_free_ext_cachep;
 /* We create slab caches for groupinfo data structures based on the
  * superblock block size.  There will be one per mounted filesystem for
  * each unique s_blocksize_bits */
-#define NR_GRPINFO_CACHES      \
-       (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE + 1)
+#define NR_GRPINFO_CACHES 8
 static struct kmem_cache *ext4_groupinfo_caches[NR_GRPINFO_CACHES];
 
+static const char *ext4_groupinfo_slab_names[NR_GRPINFO_CACHES] = {
+       "ext4_groupinfo_1k", "ext4_groupinfo_2k", "ext4_groupinfo_4k",
+       "ext4_groupinfo_8k", "ext4_groupinfo_16k", "ext4_groupinfo_32k",
+       "ext4_groupinfo_64k", "ext4_groupinfo_128k"
+};
+
 static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
                                        ext4_group_t group);
 static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
@@ -2414,6 +2419,55 @@ err_freesgi:
        return -ENOMEM;
 }
 
+static void ext4_groupinfo_destroy_slabs(void)
+{
+       int i;
+
+       for (i = 0; i < NR_GRPINFO_CACHES; i++) {
+               if (ext4_groupinfo_caches[i])
+                       kmem_cache_destroy(ext4_groupinfo_caches[i]);
+               ext4_groupinfo_caches[i] = NULL;
+       }
+}
+
+static int ext4_groupinfo_create_slab(size_t size)
+{
+       static DEFINE_MUTEX(ext4_grpinfo_slab_create_mutex);
+       int slab_size;
+       int blocksize_bits = order_base_2(size);
+       int cache_index = blocksize_bits - EXT4_MIN_BLOCK_LOG_SIZE;
+       struct kmem_cache *cachep;
+
+       if (cache_index >= NR_GRPINFO_CACHES)
+               return -EINVAL;
+
+       if (unlikely(cache_index < 0))
+               cache_index = 0;
+
+       mutex_lock(&ext4_grpinfo_slab_create_mutex);
+       if (ext4_groupinfo_caches[cache_index]) {
+               mutex_unlock(&ext4_grpinfo_slab_create_mutex);
+               return 0;       /* Already created */
+       }
+
+       slab_size = offsetof(struct ext4_group_info,
+                               bb_counters[blocksize_bits + 2]);
+
+       cachep = kmem_cache_create(ext4_groupinfo_slab_names[cache_index],
+                                       slab_size, 0, SLAB_RECLAIM_ACCOUNT,
+                                       NULL);
+
+       mutex_unlock(&ext4_grpinfo_slab_create_mutex);
+       if (!cachep) {
+               printk(KERN_EMERG "EXT4: no memory for groupinfo slab cache\n");
+               return -ENOMEM;
+       }
+
+       ext4_groupinfo_caches[cache_index] = cachep;
+
+       return 0;
+}
+
 int ext4_mb_init(struct super_block *sb, int needs_recovery)
 {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -2421,9 +2475,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
        unsigned offset;
        unsigned max;
        int ret;
-       int cache_index;
-       struct kmem_cache *cachep;
-       char *namep = NULL;
 
        i = (sb->s_blocksize_bits + 2) * sizeof(*sbi->s_mb_offsets);
 
@@ -2440,30 +2491,9 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
                goto out;
        }
 
-       cache_index = sb->s_blocksize_bits - EXT4_MIN_BLOCK_LOG_SIZE;
-       cachep = ext4_groupinfo_caches[cache_index];
-       if (!cachep) {
-               char name[32];
-               int len = offsetof(struct ext4_group_info,
-                                       bb_counters[sb->s_blocksize_bits + 2]);
-
-               sprintf(name, "ext4_groupinfo_%d", sb->s_blocksize_bits);
-               namep = kstrdup(name, GFP_KERNEL);
-               if (!namep) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               /* Need to free the kmem_cache_name() when we
-                * destroy the slab */
-               cachep = kmem_cache_create(namep, len, 0,
-                                            SLAB_RECLAIM_ACCOUNT, NULL);
-               if (!cachep) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               ext4_groupinfo_caches[cache_index] = cachep;
-       }
+       ret = ext4_groupinfo_create_slab(sb->s_blocksize);
+       if (ret < 0)
+               goto out;
 
        /* order 0 is regular bitmap */
        sbi->s_mb_maxs[0] = sb->s_blocksize << 3;
@@ -2520,7 +2550,6 @@ out:
        if (ret) {
                kfree(sbi->s_mb_offsets);
                kfree(sbi->s_mb_maxs);
-               kfree(namep);
        }
        return ret;
 }
@@ -2734,7 +2763,6 @@ int __init ext4_init_mballoc(void)
 
 void ext4_exit_mballoc(void)
 {
-       int i;
        /*
         * Wait for completion of call_rcu()'s on ext4_pspace_cachep
         * before destroying the slab cache.
@@ -2743,15 +2771,7 @@ void ext4_exit_mballoc(void)
        kmem_cache_destroy(ext4_pspace_cachep);
        kmem_cache_destroy(ext4_ac_cachep);
        kmem_cache_destroy(ext4_free_ext_cachep);
-
-       for (i = 0; i < NR_GRPINFO_CACHES; i++) {
-               struct kmem_cache *cachep = ext4_groupinfo_caches[i];
-               if (cachep) {
-                       char *name = (char *)kmem_cache_name(cachep);
-                       kmem_cache_destroy(cachep);
-                       kfree(name);
-               }
-       }
+       ext4_groupinfo_destroy_slabs();
        ext4_remove_debugfs_entry();
 }
 
index 7270dcf..955cc30 100644 (file)
 
 static struct kmem_cache *io_page_cachep, *io_end_cachep;
 
-#define WQ_HASH_SZ             37
-#define to_ioend_wq(v) (&ioend_wq[((unsigned long)v) % WQ_HASH_SZ])
-static wait_queue_head_t ioend_wq[WQ_HASH_SZ];
-
 int __init ext4_init_pageio(void)
 {
-       int i;
-
        io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT);
        if (io_page_cachep == NULL)
                return -ENOMEM;
@@ -48,9 +42,6 @@ int __init ext4_init_pageio(void)
                kmem_cache_destroy(io_page_cachep);
                return -ENOMEM;
        }
-       for (i = 0; i < WQ_HASH_SZ; i++)
-               init_waitqueue_head(&ioend_wq[i]);
-
        return 0;
 }
 
@@ -62,7 +53,7 @@ void ext4_exit_pageio(void)
 
 void ext4_ioend_wait(struct inode *inode)
 {
-       wait_queue_head_t *wq = to_ioend_wq(inode);
+       wait_queue_head_t *wq = ext4_ioend_wq(inode);
 
        wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0));
 }
@@ -87,7 +78,7 @@ void ext4_free_io_end(ext4_io_end_t *io)
        for (i = 0; i < io->num_io_pages; i++)
                put_io_page(io->pages[i]);
        io->num_io_pages = 0;
-       wq = to_ioend_wq(io->inode);
+       wq = ext4_ioend_wq(io->inode);
        if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count) &&
            waitqueue_active(wq))
                wake_up_all(wq);
@@ -102,6 +93,7 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
        struct inode *inode = io->inode;
        loff_t offset = io->offset;
        ssize_t size = io->size;
+       wait_queue_head_t *wq;
        int ret = 0;
 
        ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
@@ -126,7 +118,16 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
        if (io->iocb)
                aio_complete(io->iocb, io->result, 0);
        /* clear the DIO AIO unwritten flag */
-       io->flag &= ~EXT4_IO_END_UNWRITTEN;
+       if (io->flag & EXT4_IO_END_UNWRITTEN) {
+               io->flag &= ~EXT4_IO_END_UNWRITTEN;
+               /* Wake up anyone waiting on unwritten extent conversion */
+               wq = ext4_ioend_wq(io->inode);
+               if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten) &&
+                   waitqueue_active(wq)) {
+                       wake_up_all(wq);
+               }
+       }
+
        return ret;
 }
 
@@ -190,6 +191,7 @@ static void ext4_end_bio(struct bio *bio, int error)
        struct inode *inode;
        unsigned long flags;
        int i;
+       sector_t bi_sector = bio->bi_sector;
 
        BUG_ON(!io_end);
        bio->bi_private = NULL;
@@ -207,9 +209,7 @@ static void ext4_end_bio(struct bio *bio, int error)
                if (error)
                        SetPageError(page);
                BUG_ON(!head);
-               if (head->b_size == PAGE_CACHE_SIZE)
-                       clear_buffer_dirty(head);
-               else {
+               if (head->b_size != PAGE_CACHE_SIZE) {
                        loff_t offset;
                        loff_t io_end_offset = io_end->offset + io_end->size;
 
@@ -221,7 +221,6 @@ static void ext4_end_bio(struct bio *bio, int error)
                                        if (error)
                                                buffer_io_error(bh);
 
-                                       clear_buffer_dirty(bh);
                                }
                                if (buffer_delay(bh))
                                        partial_write = 1;
@@ -257,7 +256,7 @@ static void ext4_end_bio(struct bio *bio, int error)
                             (unsigned long long) io_end->offset,
                             (long) io_end->size,
                             (unsigned long long)
-                            bio->bi_sector >> (inode->i_blkbits - 9));
+                            bi_sector >> (inode->i_blkbits - 9));
        }
 
        /* Add the io_end to per-inode completed io list*/
@@ -380,6 +379,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
 
        blocksize = 1 << inode->i_blkbits;
 
+       BUG_ON(!PageLocked(page));
        BUG_ON(PageWriteback(page));
        set_page_writeback(page);
        ClearPageError(page);
@@ -397,12 +397,14 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
        for (bh = head = page_buffers(page), block_start = 0;
             bh != head || !block_start;
             block_start = block_end, bh = bh->b_this_page) {
+
                block_end = block_start + blocksize;
                if (block_start >= len) {
                        clear_buffer_dirty(bh);
                        set_buffer_uptodate(bh);
                        continue;
                }
+               clear_buffer_dirty(bh);
                ret = io_submit_add_bh(io, io_page, inode, wbc, bh);
                if (ret) {
                        /*
index 48ce561..f6a318f 100644 (file)
@@ -77,6 +77,7 @@ static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
                       const char *dev_name, void *data);
 static void ext4_destroy_lazyinit_thread(void);
 static void ext4_unregister_li_request(struct super_block *sb);
+static void ext4_clear_request_list(void);
 
 #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
 static struct file_system_type ext3_fs_type = {
@@ -832,6 +833,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        ei->i_sync_tid = 0;
        ei->i_datasync_tid = 0;
        atomic_set(&ei->i_ioend_count, 0);
+       atomic_set(&ei->i_aiodio_unwritten, 0);
 
        return &ei->vfs_inode;
 }
@@ -2716,6 +2718,8 @@ static void ext4_unregister_li_request(struct super_block *sb)
        mutex_unlock(&ext4_li_info->li_list_mtx);
 }
 
+static struct task_struct *ext4_lazyinit_task;
+
 /*
  * This is the function where ext4lazyinit thread lives. It walks
  * through the request list searching for next scheduled filesystem.
@@ -2784,6 +2788,10 @@ cont_thread:
                if (time_before(jiffies, next_wakeup))
                        schedule();
                finish_wait(&eli->li_wait_daemon, &wait);
+               if (kthread_should_stop()) {
+                       ext4_clear_request_list();
+                       goto exit_thread;
+               }
        }
 
 exit_thread:
@@ -2808,6 +2816,7 @@ exit_thread:
        wake_up(&eli->li_wait_task);
 
        kfree(ext4_li_info);
+       ext4_lazyinit_task = NULL;
        ext4_li_info = NULL;
        mutex_unlock(&ext4_li_mtx);
 
@@ -2830,11 +2839,10 @@ static void ext4_clear_request_list(void)
 
 static int ext4_run_lazyinit_thread(void)
 {
-       struct task_struct *t;
-
-       t = kthread_run(ext4_lazyinit_thread, ext4_li_info, "ext4lazyinit");
-       if (IS_ERR(t)) {
-               int err = PTR_ERR(t);
+       ext4_lazyinit_task = kthread_run(ext4_lazyinit_thread,
+                                        ext4_li_info, "ext4lazyinit");
+       if (IS_ERR(ext4_lazyinit_task)) {
+               int err = PTR_ERR(ext4_lazyinit_task);
                ext4_clear_request_list();
                del_timer_sync(&ext4_li_info->li_timer);
                kfree(ext4_li_info);
@@ -2985,16 +2993,10 @@ static void ext4_destroy_lazyinit_thread(void)
         * If thread exited earlier
         * there's nothing to be done.
         */
-       if (!ext4_li_info)
+       if (!ext4_li_info || !ext4_lazyinit_task)
                return;
 
-       ext4_clear_request_list();
-
-       while (ext4_li_info->li_task) {
-               wake_up(&ext4_li_info->li_wait_daemon);
-               wait_event(ext4_li_info->li_wait_task,
-                          ext4_li_info->li_task == NULL);
-       }
+       kthread_stop(ext4_lazyinit_task);
 }
 
 static int ext4_fill_super(struct super_block *sb, void *data, int silent)
@@ -4768,7 +4770,7 @@ static struct file_system_type ext4_fs_type = {
        .fs_flags       = FS_REQUIRES_DEV,
 };
 
-int __init ext4_init_feat_adverts(void)
+static int __init ext4_init_feat_adverts(void)
 {
        struct ext4_features *ef;
        int ret = -ENOMEM;
@@ -4792,23 +4794,44 @@ out:
        return ret;
 }
 
+static void ext4_exit_feat_adverts(void)
+{
+       kobject_put(&ext4_feat->f_kobj);
+       wait_for_completion(&ext4_feat->f_kobj_unregister);
+       kfree(ext4_feat);
+}
+
+/* Shared across all ext4 file systems */
+wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
+struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
+
 static int __init ext4_init_fs(void)
 {
-       int err;
+       int i, err;
 
        ext4_check_flag_values();
+
+       for (i = 0; i < EXT4_WQ_HASH_SZ; i++) {
+               mutex_init(&ext4__aio_mutex[i]);
+               init_waitqueue_head(&ext4__ioend_wq[i]);
+       }
+
        err = ext4_init_pageio();
        if (err)
                return err;
        err = ext4_init_system_zone();
        if (err)
-               goto out5;
+               goto out7;
        ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
        if (!ext4_kset)
-               goto out4;
+               goto out6;
        ext4_proc_root = proc_mkdir("fs/ext4", NULL);
+       if (!ext4_proc_root)
+               goto out5;
 
        err = ext4_init_feat_adverts();
+       if (err)
+               goto out4;
 
        err = ext4_init_mballoc();
        if (err)
@@ -4838,12 +4861,14 @@ out1:
 out2:
        ext4_exit_mballoc();
 out3:
-       kfree(ext4_feat);
+       ext4_exit_feat_adverts();
+out4:
        remove_proc_entry("fs/ext4", NULL);
+out5:
        kset_unregister(ext4_kset);
-out4:
+out6:
        ext4_exit_system_zone();
-out5:
+out7:
        ext4_exit_pageio();
        return err;
 }
@@ -4857,6 +4882,7 @@ static void __exit ext4_exit_fs(void)
        destroy_inodecache();
        ext4_exit_xattr();
        ext4_exit_mballoc();
+       ext4_exit_feat_adverts();
        remove_proc_entry("fs/ext4", NULL);
        kset_unregister(ext4_kset);
        ext4_exit_system_zone();
index 9e46869..97e7346 100644 (file)
@@ -473,7 +473,8 @@ int __jbd2_log_space_left(journal_t *journal)
 }
 
 /*
- * Called under j_state_lock.  Returns true if a transaction commit was started.
+ * Called with j_state_lock locked for writing.
+ * Returns true if a transaction commit was started.
  */
 int __jbd2_log_start_commit(journal_t *journal, tid_t target)
 {
@@ -520,11 +521,13 @@ int jbd2_journal_force_commit_nested(journal_t *journal)
 {
        transaction_t *transaction = NULL;
        tid_t tid;
+       int need_to_start = 0;
 
        read_lock(&journal->j_state_lock);
        if (journal->j_running_transaction && !current->journal_info) {
                transaction = journal->j_running_transaction;
-               __jbd2_log_start_commit(journal, transaction->t_tid);
+               if (!tid_geq(journal->j_commit_request, transaction->t_tid))
+                       need_to_start = 1;
        } else if (journal->j_committing_transaction)
                transaction = journal->j_committing_transaction;
 
@@ -535,6 +538,8 @@ int jbd2_journal_force_commit_nested(journal_t *journal)
 
        tid = transaction->t_tid;
        read_unlock(&journal->j_state_lock);
+       if (need_to_start)
+               jbd2_log_start_commit(journal, tid);
        jbd2_log_wait_commit(journal, tid);
        return 1;
 }
index faad2bd..1d11910 100644 (file)
@@ -117,10 +117,10 @@ static inline void update_t_max_wait(transaction_t *transaction)
 static int start_this_handle(journal_t *journal, handle_t *handle,
                             int gfp_mask)
 {
-       transaction_t *transaction;
-       int needed;
-       int nblocks = handle->h_buffer_credits;
-       transaction_t *new_transaction = NULL;
+       transaction_t   *transaction, *new_transaction = NULL;
+       tid_t           tid;
+       int             needed, need_to_start;
+       int             nblocks = handle->h_buffer_credits;
 
        if (nblocks > journal->j_max_transaction_buffers) {
                printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",
@@ -222,8 +222,11 @@ repeat:
                atomic_sub(nblocks, &transaction->t_outstanding_credits);
                prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
                                TASK_UNINTERRUPTIBLE);
-               __jbd2_log_start_commit(journal, transaction->t_tid);
+               tid = transaction->t_tid;
+               need_to_start = !tid_geq(journal->j_commit_request, tid);
                read_unlock(&journal->j_state_lock);
+               if (need_to_start)
+                       jbd2_log_start_commit(journal, tid);
                schedule();
                finish_wait(&journal->j_wait_transaction_locked, &wait);
                goto repeat;
@@ -442,7 +445,8 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask)
 {
        transaction_t *transaction = handle->h_transaction;
        journal_t *journal = transaction->t_journal;
-       int ret;
+       tid_t           tid;
+       int             need_to_start, ret;
 
        /* If we've had an abort of any type, don't even think about
         * actually doing the restart! */
@@ -465,8 +469,11 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask)
        spin_unlock(&transaction->t_handle_lock);
 
        jbd_debug(2, "restarting handle %p\n", handle);
-       __jbd2_log_start_commit(journal, transaction->t_tid);
+       tid = transaction->t_tid;
+       need_to_start = !tid_geq(journal->j_commit_request, tid);
        read_unlock(&journal->j_state_lock);
+       if (need_to_start)
+               jbd2_log_start_commit(journal, tid);
 
        lock_map_release(&handle->h_lockdep_map);
        handle->h_buffer_credits = nblocks;
index 7d77f24..9e701e2 100644 (file)
@@ -455,14 +455,6 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry
        struct fs_struct *fs = current->fs;
        struct dentry *parent = nd->path.dentry;
 
-       /*
-        * It can be possible to revalidate the dentry that we started
-        * the path walk with. force_reval_path may also revalidate the
-        * dentry already committed to the nameidata.
-        */
-       if (unlikely(parent == dentry))
-               return nameidata_drop_rcu(nd);
-
        BUG_ON(!(nd->flags & LOOKUP_RCU));
        if (nd->root.mnt) {
                spin_lock(&fs->lock);
@@ -561,39 +553,25 @@ static inline int nameidata_drop_rcu_last_maybe(struct nameidata *nd)
  */
 void release_open_intent(struct nameidata *nd)
 {
-       if (nd->intent.open.file->f_path.dentry == NULL)
-               put_filp(nd->intent.open.file);
-       else
-               fput(nd->intent.open.file);
-}
-
-/*
- * Call d_revalidate and handle filesystems that request rcu-walk
- * to be dropped. This may be called and return in rcu-walk mode,
- * regardless of success or error. If -ECHILD is returned, the caller
- * must return -ECHILD back up the path walk stack so path walk may
- * be restarted in ref-walk mode.
- */
-static int d_revalidate(struct dentry *dentry, struct nameidata *nd)
-{
-       int status;
+       struct file *file = nd->intent.open.file;
 
-       status = dentry->d_op->d_revalidate(dentry, nd);
-       if (status == -ECHILD) {
-               if (nameidata_dentry_drop_rcu(nd, dentry))
-                       return status;
-               status = dentry->d_op->d_revalidate(dentry, nd);
+       if (file && !IS_ERR(file)) {
+               if (file->f_path.dentry == NULL)
+                       put_filp(file);
+               else
+                       fput(file);
        }
+}
 
-       return status;
+static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+       return dentry->d_op->d_revalidate(dentry, nd);
 }
 
-static inline struct dentry *
+static struct dentry *
 do_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
-       int status;
-
-       status = d_revalidate(dentry, nd);
+       int status = d_revalidate(dentry, nd);
        if (unlikely(status <= 0)) {
                /*
                 * The dentry failed validation.
@@ -602,24 +580,39 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd)
                 * to return a fail status.
                 */
                if (status < 0) {
-                       /* If we're in rcu-walk, we don't have a ref */
-                       if (!(nd->flags & LOOKUP_RCU))
-                               dput(dentry);
+                       dput(dentry);
                        dentry = ERR_PTR(status);
-
-               } else {
-                       /* Don't d_invalidate in rcu-walk mode */
-                       if (nameidata_dentry_drop_rcu_maybe(nd, dentry))
-                               return ERR_PTR(-ECHILD);
-                       if (!d_invalidate(dentry)) {
-                               dput(dentry);
-                               dentry = NULL;
-                       }
+               } else if (!d_invalidate(dentry)) {
+                       dput(dentry);
+                       dentry = NULL;
                }
        }
        return dentry;
 }
 
+static inline struct dentry *
+do_revalidate_rcu(struct dentry *dentry, struct nameidata *nd)
+{
+       int status = d_revalidate(dentry, nd);
+       if (likely(status > 0))
+               return dentry;
+       if (status == -ECHILD) {
+               if (nameidata_dentry_drop_rcu(nd, dentry))
+                       return ERR_PTR(-ECHILD);
+               return do_revalidate(dentry, nd);
+       }
+       if (status < 0)
+               return ERR_PTR(status);
+       /* Don't d_invalidate in rcu-walk mode */
+       if (nameidata_dentry_drop_rcu(nd, dentry))
+               return ERR_PTR(-ECHILD);
+       if (!d_invalidate(dentry)) {
+               dput(dentry);
+               dentry = NULL;
+       }
+       return dentry;
+}
+
 static inline int need_reval_dot(struct dentry *dentry)
 {
        if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE)))
@@ -664,9 +657,6 @@ force_reval_path(struct path *path, struct nameidata *nd)
                return 0;
 
        if (!status) {
-               /* Don't d_invalidate in rcu-walk mode */
-               if (nameidata_drop_rcu(nd))
-                       return -ECHILD;
                d_invalidate(dentry);
                status = -ESTALE;
        }
@@ -773,6 +763,8 @@ __do_follow_link(const struct path *link, struct nameidata *nd, void **p)
        int error;
        struct dentry *dentry = link->dentry;
 
+       BUG_ON(nd->flags & LOOKUP_RCU);
+
        touch_atime(link->mnt, dentry);
        nd_set_link(nd, NULL);
 
@@ -807,6 +799,11 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
 {
        void *cookie;
        int err = -ELOOP;
+
+       /* We drop rcu-walk here */
+       if (nameidata_dentry_drop_rcu_maybe(nd, path->dentry))
+               return -ECHILD;
+
        if (current->link_count >= MAX_NESTED_LINKS)
                goto loop;
        if (current->total_link_count >= 40)
@@ -1251,9 +1248,15 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
                        return -ECHILD;
 
                nd->seq = seq;
-               if (dentry->d_flags & DCACHE_OP_REVALIDATE)
-                       goto need_revalidate;
-done2:
+               if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) {
+                       dentry = do_revalidate_rcu(dentry, nd);
+                       if (!dentry)
+                               goto need_lookup;
+                       if (IS_ERR(dentry))
+                               goto fail;
+                       if (!(nd->flags & LOOKUP_RCU))
+                               goto done;
+               }
                path->mnt = mnt;
                path->dentry = dentry;
                if (likely(__follow_mount_rcu(nd, path, inode, false)))
@@ -1266,8 +1269,13 @@ done2:
        if (!dentry)
                goto need_lookup;
 found:
-       if (dentry->d_flags & DCACHE_OP_REVALIDATE)
-               goto need_revalidate;
+       if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) {
+               dentry = do_revalidate(dentry, nd);
+               if (!dentry)
+                       goto need_lookup;
+               if (IS_ERR(dentry))
+                       goto fail;
+       }
 done:
        path->mnt = mnt;
        path->dentry = dentry;
@@ -1309,16 +1317,6 @@ need_lookup:
        mutex_unlock(&dir->i_mutex);
        goto found;
 
-need_revalidate:
-       dentry = do_revalidate(dentry, nd);
-       if (!dentry)
-               goto need_lookup;
-       if (IS_ERR(dentry))
-               goto fail;
-       if (nd->flags & LOOKUP_RCU)
-               goto done2;
-       goto done;
-
 fail:
        return PTR_ERR(dentry);
 }
@@ -1415,9 +1413,6 @@ exec_again:
                        goto out_dput;
 
                if (inode->i_op->follow_link) {
-                       /* We commonly drop rcu-walk here */
-                       if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry))
-                               return -ECHILD;
                        BUG_ON(inode != next.dentry->d_inode);
                        err = do_follow_link(&next, nd);
                        if (err)
@@ -1463,8 +1458,6 @@ last_component:
                        break;
                if (inode && unlikely(inode->i_op->follow_link) &&
                    (lookup_flags & LOOKUP_FOLLOW)) {
-                       if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry))
-                               return -ECHILD;
                        BUG_ON(inode != next.dentry->d_inode);
                        err = do_follow_link(&next, nd);
                        if (err)
@@ -1500,12 +1493,15 @@ return_reval:
                 * We may need to check the cached dentry for staleness.
                 */
                if (need_reval_dot(nd->path.dentry)) {
+                       if (nameidata_drop_rcu_last_maybe(nd))
+                               return -ECHILD;
                        /* Note: we do not d_invalidate() */
                        err = d_revalidate(nd->path.dentry, nd);
                        if (!err)
                                err = -ESTALE;
                        if (err < 0)
                                break;
+                       return 0;
                }
 return_base:
                if (nameidata_drop_rcu_last_maybe(nd))
@@ -2265,8 +2261,6 @@ static struct file *finish_open(struct nameidata *nd,
        return filp;
 
 exit:
-       if (!IS_ERR(nd->intent.open.file))
-               release_open_intent(nd);
        path_put(&nd->path);
        return ERR_PTR(error);
 }
@@ -2389,8 +2383,6 @@ exit_mutex_unlock:
 exit_dput:
        path_put_conditional(path, nd);
 exit:
-       if (!IS_ERR(nd->intent.open.file))
-               release_open_intent(nd);
        path_put(&nd->path);
        return ERR_PTR(error);
 }
@@ -2477,6 +2469,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
        }
        audit_inode(pathname, nd.path.dentry);
        filp = finish_open(&nd, open_flag, acc_mode);
+       release_open_intent(&nd);
        return filp;
 
 creat:
@@ -2553,6 +2546,7 @@ out:
                path_put(&nd.root);
        if (filp == ERR_PTR(-ESTALE) && !(flags & LOOKUP_REVAL))
                goto reval;
+       release_open_intent(&nd);
        return filp;
 
 exit_dput:
@@ -2560,8 +2554,6 @@ exit_dput:
 out_path:
        path_put(&nd.path);
 out_filp:
-       if (!IS_ERR(nd.intent.open.file))
-               release_open_intent(&nd);
        filp = ERR_PTR(error);
        goto out;
 }
index 3be975e..cde36cb 100644 (file)
@@ -484,7 +484,7 @@ static int decode_cb_sequence4res(struct xdr_stream *xdr,
 out:
        return status;
 out_default:
-       return nfs_cb_stat_to_errno(status);
+       return nfs_cb_stat_to_errno(nfserr);
 }
 
 /*
@@ -564,11 +564,9 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
        if (unlikely(status))
                goto out;
        if (unlikely(nfserr != NFS4_OK))
-               goto out_default;
+               status = nfs_cb_stat_to_errno(nfserr);
 out:
        return status;
-out_default:
-       return nfs_cb_stat_to_errno(status);
 }
 
 /*
index d98d021..54b60bf 100644 (file)
@@ -230,9 +230,6 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
        dp->dl_client = clp;
        get_nfs4_file(fp);
        dp->dl_file = fp;
-       dp->dl_vfs_file = find_readable_file(fp);
-       get_file(dp->dl_vfs_file);
-       dp->dl_flock = NULL;
        dp->dl_type = type;
        dp->dl_stateid.si_boot = boot_time;
        dp->dl_stateid.si_stateownerid = current_delegid++;
@@ -241,8 +238,6 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
        fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
        dp->dl_time = 0;
        atomic_set(&dp->dl_count, 1);
-       list_add(&dp->dl_perfile, &fp->fi_delegations);
-       list_add(&dp->dl_perclnt, &clp->cl_delegations);
        INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc);
        return dp;
 }
@@ -253,36 +248,30 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
        if (atomic_dec_and_test(&dp->dl_count)) {
                dprintk("NFSD: freeing dp %p\n",dp);
                put_nfs4_file(dp->dl_file);
-               fput(dp->dl_vfs_file);
                kmem_cache_free(deleg_slab, dp);
                num_delegations--;
        }
 }
 
-/* Remove the associated file_lock first, then remove the delegation.
- * lease_modify() is called to remove the FS_LEASE file_lock from
- * the i_flock list, eventually calling nfsd's lock_manager
- * fl_release_callback.
- */
-static void
-nfs4_close_delegation(struct nfs4_delegation *dp)
+static void nfs4_put_deleg_lease(struct nfs4_file *fp)
 {
-       dprintk("NFSD: close_delegation dp %p\n",dp);
-       /* XXX: do we even need this check?: */
-       if (dp->dl_flock)
-               vfs_setlease(dp->dl_vfs_file, F_UNLCK, &dp->dl_flock);
+       if (atomic_dec_and_test(&fp->fi_delegees)) {
+               vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease);
+               fp->fi_lease = NULL;
+               fp->fi_deleg_file = NULL;
+       }
 }
 
 /* Called under the state lock. */
 static void
 unhash_delegation(struct nfs4_delegation *dp)
 {
-       list_del_init(&dp->dl_perfile);
        list_del_init(&dp->dl_perclnt);
        spin_lock(&recall_lock);
+       list_del_init(&dp->dl_perfile);
        list_del_init(&dp->dl_recall_lru);
        spin_unlock(&recall_lock);
-       nfs4_close_delegation(dp);
+       nfs4_put_deleg_lease(dp->dl_file);
        nfs4_put_delegation(dp);
 }
 
@@ -958,8 +947,6 @@ expire_client(struct nfs4_client *clp)
        spin_lock(&recall_lock);
        while (!list_empty(&clp->cl_delegations)) {
                dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
-               dprintk("NFSD: expire client. dp %p, fp %p\n", dp,
-                               dp->dl_flock);
                list_del_init(&dp->dl_perclnt);
                list_move(&dp->dl_recall_lru, &reaplist);
        }
@@ -2078,6 +2065,7 @@ alloc_init_file(struct inode *ino)
                fp->fi_inode = igrab(ino);
                fp->fi_id = current_fileid++;
                fp->fi_had_conflict = false;
+               fp->fi_lease = NULL;
                memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
                memset(fp->fi_access, 0, sizeof(fp->fi_access));
                spin_lock(&recall_lock);
@@ -2329,23 +2317,8 @@ nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
                nfs4_file_put_access(fp, O_RDONLY);
 }
 
-/*
- * Spawn a thread to perform a recall on the delegation represented
- * by the lease (file_lock)
- *
- * Called from break_lease() with lock_flocks() held.
- * Note: we assume break_lease will only call this *once* for any given
- * lease.
- */
-static
-void nfsd_break_deleg_cb(struct file_lock *fl)
+static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
 {
-       struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
-
-       dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl);
-       if (!dp)
-               return;
-
        /* We're assuming the state code never drops its reference
         * without first removing the lease.  Since we're in this lease
         * callback (and since the lease code is serialized by the kernel
@@ -2353,22 +2326,35 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
         * it's safe to take a reference: */
        atomic_inc(&dp->dl_count);
 
-       spin_lock(&recall_lock);
        list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
-       spin_unlock(&recall_lock);
 
        /* only place dl_time is set. protected by lock_flocks*/
        dp->dl_time = get_seconds();
 
+       nfsd4_cb_recall(dp);
+}
+
+/* Called from break_lease() with lock_flocks() held. */
+static void nfsd_break_deleg_cb(struct file_lock *fl)
+{
+       struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
+       struct nfs4_delegation *dp;
+
+       BUG_ON(!fp);
+       /* We assume break_lease is only called once per lease: */
+       BUG_ON(fp->fi_had_conflict);
        /*
         * We don't want the locks code to timeout the lease for us;
-        * we'll remove it ourself if the delegation isn't returned
-        * in time.
+        * we'll remove it ourself if a delegation isn't returned
+        * in time:
         */
        fl->fl_break_time = 0;
 
-       dp->dl_file->fi_had_conflict = true;
-       nfsd4_cb_recall(dp);
+       spin_lock(&recall_lock);
+       fp->fi_had_conflict = true;
+       list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
+               nfsd_break_one_deleg(dp);
+       spin_unlock(&recall_lock);
 }
 
 static
@@ -2459,13 +2445,15 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
 static struct nfs4_delegation *
 find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
 {
-       struct nfs4_delegation *dp;
+       struct nfs4_delegation *dp = NULL;
 
+       spin_lock(&recall_lock);
        list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) {
                if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid)
-                       return dp;
+                       break;
        }
-       return NULL;
+       spin_unlock(&recall_lock);
+       return dp;
 }
 
 int share_access_to_flags(u32 share_access)
@@ -2641,6 +2629,66 @@ static bool nfsd4_cb_channel_good(struct nfs4_client *clp)
        return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN;
 }
 
+static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int flag)
+{
+       struct file_lock *fl;
+
+       fl = locks_alloc_lock();
+       if (!fl)
+               return NULL;
+       locks_init_lock(fl);
+       fl->fl_lmops = &nfsd_lease_mng_ops;
+       fl->fl_flags = FL_LEASE;
+       fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
+       fl->fl_end = OFFSET_MAX;
+       fl->fl_owner = (fl_owner_t)(dp->dl_file);
+       fl->fl_pid = current->tgid;
+       return fl;
+}
+
+static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
+{
+       struct nfs4_file *fp = dp->dl_file;
+       struct file_lock *fl;
+       int status;
+
+       fl = nfs4_alloc_init_lease(dp, flag);
+       if (!fl)
+               return -ENOMEM;
+       fl->fl_file = find_readable_file(fp);
+       list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations);
+       status = vfs_setlease(fl->fl_file, fl->fl_type, &fl);
+       if (status) {
+               list_del_init(&dp->dl_perclnt);
+               locks_free_lock(fl);
+               return -ENOMEM;
+       }
+       fp->fi_lease = fl;
+       fp->fi_deleg_file = fl->fl_file;
+       get_file(fp->fi_deleg_file);
+       atomic_set(&fp->fi_delegees, 1);
+       list_add(&dp->dl_perfile, &fp->fi_delegations);
+       return 0;
+}
+
+static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag)
+{
+       struct nfs4_file *fp = dp->dl_file;
+
+       if (!fp->fi_lease)
+               return nfs4_setlease(dp, flag);
+       spin_lock(&recall_lock);
+       if (fp->fi_had_conflict) {
+               spin_unlock(&recall_lock);
+               return -EAGAIN;
+       }
+       atomic_inc(&fp->fi_delegees);
+       list_add(&dp->dl_perfile, &fp->fi_delegations);
+       spin_unlock(&recall_lock);
+       list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations);
+       return 0;
+}
+
 /*
  * Attempt to hand out a delegation.
  */
@@ -2650,7 +2698,6 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
        struct nfs4_delegation *dp;
        struct nfs4_stateowner *sop = stp->st_stateowner;
        int cb_up;
-       struct file_lock *fl;
        int status, flag = 0;
 
        cb_up = nfsd4_cb_channel_good(sop->so_client);
@@ -2681,36 +2728,11 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
        }
 
        dp = alloc_init_deleg(sop->so_client, stp, fh, flag);
-       if (dp == NULL) {
-               flag = NFS4_OPEN_DELEGATE_NONE;
-               goto out;
-       }
-       status = -ENOMEM;
-       fl = locks_alloc_lock();
-       if (!fl)
-               goto out;
-       locks_init_lock(fl);
-       fl->fl_lmops = &nfsd_lease_mng_ops;
-       fl->fl_flags = FL_LEASE;
-       fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
-       fl->fl_end = OFFSET_MAX;
-       fl->fl_owner =  (fl_owner_t)dp;
-       fl->fl_file = find_readable_file(stp->st_file);
-       BUG_ON(!fl->fl_file);
-       fl->fl_pid = current->tgid;
-       dp->dl_flock = fl;
-
-       /* vfs_setlease checks to see if delegation should be handed out.
-        * the lock_manager callback fl_change is used
-        */
-       if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
-               dprintk("NFSD: setlease failed [%d], no delegation\n", status);
-               dp->dl_flock = NULL;
-               locks_free_lock(fl);
-               unhash_delegation(dp);
-               flag = NFS4_OPEN_DELEGATE_NONE;
-               goto out;
-       }
+       if (dp == NULL)
+               goto out_no_deleg;
+       status = nfs4_set_delegation(dp, flag);
+       if (status)
+               goto out_free;
 
        memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid));
 
@@ -2722,6 +2744,12 @@ out:
                        && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
                dprintk("NFSD: WARNING: refusing delegation reclaim\n");
        open->op_delegate_type = flag;
+       return;
+out_free:
+       nfs4_put_delegation(dp);
+out_no_deleg:
+       flag = NFS4_OPEN_DELEGATE_NONE;
+       goto out;
 }
 
 /*
@@ -2916,8 +2944,6 @@ nfs4_laundromat(void)
                                test_val = u;
                        break;
                }
-               dprintk("NFSD: purging unused delegation dp %p, fp %p\n",
-                                   dp, dp->dl_flock);
                list_move(&dp->dl_recall_lru, &reaplist);
        }
        spin_unlock(&recall_lock);
@@ -3128,7 +3154,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
                        goto out;
                renew_client(dp->dl_client);
                if (filpp) {
-                       *filpp = find_readable_file(dp->dl_file);
+                       *filpp = dp->dl_file->fi_deleg_file;
                        BUG_ON(!*filpp);
                }
        } else { /* open or lock stateid */
index 3074656..2d31224 100644 (file)
@@ -83,8 +83,6 @@ struct nfs4_delegation {
        atomic_t                dl_count;       /* ref count */
        struct nfs4_client      *dl_client;
        struct nfs4_file        *dl_file;
-       struct file             *dl_vfs_file;
-       struct file_lock        *dl_flock;
        u32                     dl_type;
        time_t                  dl_time;
 /* For recall: */
@@ -379,6 +377,9 @@ struct nfs4_file {
         */
        atomic_t                fi_readers;
        atomic_t                fi_writers;
+       struct file             *fi_deleg_file;
+       struct file_lock        *fi_lease;
+       atomic_t                fi_delegees;
        struct inode            *fi_inode;
        u32                     fi_id;      /* used with stateowner->so_id 
                                             * for stateid_hashtbl hash */
index 641117f..da1d970 100644 (file)
@@ -808,7 +808,7 @@ nfsd_get_raparms(dev_t dev, ino_t ino)
                if (ra->p_count == 0)
                        frap = rap;
        }
-       depth = nfsdstats.ra_size*11/10;
+       depth = nfsdstats.ra_size;
        if (!frap) {    
                spin_unlock(&rab->pb_lock);
                return NULL;
@@ -1742,6 +1742,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
                goto out_dput_new;
 
        host_err = nfsd_break_lease(odentry->d_inode);
+       if (host_err)
+               goto out_drop_write;
+       if (ndentry->d_inode) {
+               host_err = nfsd_break_lease(ndentry->d_inode);
+               if (host_err)
+                       goto out_drop_write;
+       }
        if (host_err)
                goto out_drop_write;
        host_err = vfs_rename(fdir, odentry, tdir, ndentry);
@@ -1812,22 +1819,22 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 
        host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
        if (host_err)
-               goto out_nfserr;
+               goto out_put;
 
        host_err = nfsd_break_lease(rdentry->d_inode);
        if (host_err)
-               goto out_put;
+               goto out_drop_write;
        if (type != S_IFDIR)
                host_err = vfs_unlink(dirp, rdentry);
        else
                host_err = vfs_rmdir(dirp, rdentry);
-out_put:
-       dput(rdentry);
-
        if (!host_err)
                host_err = commit_metadata(fhp);
-
+out_drop_write:
        mnt_drop_write(fhp->fh_export->ex_path.mnt);
+out_put:
+       dput(rdentry);
+
 out_nfserr:
        err = nfserrno(host_err);
 out:
index e52389e..5a2c6eb 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -790,6 +790,8 @@ struct file *nameidata_to_filp(struct nameidata *nd)
 
        /* Pick up the filp from the open intent */
        filp = nd->intent.open.file;
+       nd->intent.open.file = NULL;
+
        /* Has the filesystem initialised the file for us? */
        if (filp->f_path.dentry == NULL) {
                path_get(&nd->path);
index df2b703..7c99c1c 100644 (file)
@@ -353,9 +353,6 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
        task_cap(m, task);
        task_cpus_allowed(m, task);
        cpuset_task_status_allowed(m, task);
-#if defined(CONFIG_S390)
-       task_show_regs(m, task);
-#endif
        task_context_switch_counts(m, task);
        return 0;
 }
index 74e149e..7e9dd4c 100644 (file)
@@ -177,6 +177,11 @@ void deactivate_locked_super(struct super_block *s)
        struct file_system_type *fs = s->s_type;
        if (atomic_dec_and_test(&s->s_active)) {
                fs->kill_sb(s);
+               /*
+                * We need to call rcu_barrier so all the delayed rcu free
+                * inodes are flushed before we release the fs module.
+                */
+               rcu_barrier();
                put_filesystem(fs);
                put_super(s);
        } else {
index 8e6c8c4..df29c8f 100644 (file)
@@ -57,7 +57,8 @@ extern pmd_t *page_check_address_pmd(struct page *page,
          (transparent_hugepage_flags &                                 \
           (1<<TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG) &&                   \
           ((__vma)->vm_flags & VM_HUGEPAGE))) &&                       \
-        !((__vma)->vm_flags & VM_NOHUGEPAGE))
+        !((__vma)->vm_flags & VM_NOHUGEPAGE) &&                        \
+        !is_vma_temporary_stack(__vma))
 #define transparent_hugepage_defrag(__vma)                             \
        ((transparent_hugepage_flags &                                  \
          (1<<TRANSPARENT_HUGEPAGE_DEFRAG_FLAG)) ||                     \
index 6974746..fe7c4b9 100644 (file)
@@ -4,8 +4,8 @@
 #include <linux/types.h>
 #include <linux/input.h>
 
-#define MATRIX_MAX_ROWS                16
-#define MATRIX_MAX_COLS                16
+#define MATRIX_MAX_ROWS                32
+#define MATRIX_MAX_COLS                32
 
 #define KEY(row, col, val)     ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
                                 (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\
index e91a4e5..a370ce5 100644 (file)
@@ -22,7 +22,7 @@ struct klist {
        struct list_head        k_list;
        void                    (*get)(struct klist_node *);
        void                    (*put)(struct klist_node *);
-} __attribute__ ((aligned (4)));
+} __attribute__ ((aligned (sizeof(void *))));
 
 #define KLIST_INIT(_name, _get, _put)                                  \
        { .k_lock       = __SPIN_LOCK_UNLOCKED(_name.k_lock),           \
index 32fb812..1ca6411 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/printk.h>
 #include <asm/atomic.h>
  
 /* Each escaped entry is prefixed by ESCAPE_CODE
@@ -186,10 +188,17 @@ int oprofile_add_data(struct op_entry *entry, unsigned long val);
 int oprofile_add_data64(struct op_entry *entry, u64 val);
 int oprofile_write_commit(struct op_entry *entry);
 
-#ifdef CONFIG_PERF_EVENTS
+#ifdef CONFIG_HW_PERF_EVENTS
 int __init oprofile_perf_init(struct oprofile_operations *ops);
 void oprofile_perf_exit(void);
 char *op_name_from_perf_id(void);
-#endif /* CONFIG_PERF_EVENTS */
+#else
+static inline int __init oprofile_perf_init(struct oprofile_operations *ops)
+{
+       pr_info("oprofile: hardware counters not available\n");
+       return -ENODEV;
+}
+static inline void oprofile_perf_exit(void) { }
+#endif /* CONFIG_HW_PERF_EVENTS */
 
 #endif /* OPROFILE_H */
index c642bb8..b2b7f97 100644 (file)
@@ -1662,7 +1662,7 @@ int security_capset(struct cred *new, const struct cred *old,
                    const kernel_cap_t *effective,
                    const kernel_cap_t *inheritable,
                    const kernel_cap_t *permitted);
-int security_capable(int cap);
+int security_capable(const struct cred *cred, int cap);
 int security_real_capable(struct task_struct *tsk, int cap);
 int security_real_capable_noaudit(struct task_struct *tsk, int cap);
 int security_sysctl(struct ctl_table *table, int op);
@@ -1856,9 +1856,9 @@ static inline int security_capset(struct cred *new,
        return cap_capset(new, old, effective, inheritable, permitted);
 }
 
-static inline int security_capable(int cap)
+static inline int security_capable(const struct cred *cred, int cap)
 {
-       return cap_capable(current, current_cred(), cap, SECURITY_CAP_AUDIT);
+       return cap_capable(current, cred, cap, SECURITY_CAP_AUDIT);
 }
 
 static inline int security_real_capable(struct task_struct *tsk, int cap)
index 5e86dc7..81a9279 100644 (file)
@@ -89,7 +89,7 @@ struct usb_cdc_acm_descriptor {
 
 #define USB_CDC_COMM_FEATURE   0x01
 #define USB_CDC_CAP_LINE       0x02
-#define USB_CDC_CAP_BRK        0x04
+#define USB_CDC_CAP_BRK                0x04
 #define USB_CDC_CAP_NOTIFY     0x08
 
 /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
@@ -271,6 +271,11 @@ struct usb_cdc_notification {
        __le16  wLength;
 } __attribute__ ((packed));
 
+struct usb_cdc_speed_change {
+       __le32  DLBitRRate;     /* contains the downlink bit rate (IN pipe) */
+       __le32  ULBitRate;      /* contains the uplink bit rate (OUT pipe) */
+} __attribute__ ((packed));
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -292,7 +297,7 @@ struct usb_cdc_ncm_ntb_parameters {
        __le16  wNdpOutDivisor;
        __le16  wNdpOutPayloadRemainder;
        __le16  wNdpOutAlignment;
-       __le16  wPadding2;
+       __le16  wNtbOutMaxDatagrams;
 } __attribute__ ((packed));
 
 /*
@@ -307,7 +312,7 @@ struct usb_cdc_ncm_nth16 {
        __le16  wHeaderLength;
        __le16  wSequence;
        __le16  wBlockLength;
-       __le16  wFpIndex;
+       __le16  wNdpIndex;
 } __attribute__ ((packed));
 
 struct usb_cdc_ncm_nth32 {
@@ -315,7 +320,7 @@ struct usb_cdc_ncm_nth32 {
        __le16  wHeaderLength;
        __le16  wSequence;
        __le32  dwBlockLength;
-       __le32  dwFpIndex;
+       __le32  dwNdpIndex;
 } __attribute__ ((packed));
 
 /*
@@ -337,7 +342,7 @@ struct usb_cdc_ncm_dpe16 {
 struct usb_cdc_ncm_ndp16 {
        __le32  dwSignature;
        __le16  wLength;
-       __le16  wNextFpIndex;
+       __le16  wNextNdpIndex;
        struct  usb_cdc_ncm_dpe16 dpe16[0];
 } __attribute__ ((packed));
 
@@ -375,6 +380,7 @@ struct usb_cdc_ncm_ndp32 {
 #define USB_CDC_NCM_NCAP_ENCAP_COMMAND                 (1 << 2)
 #define USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE             (1 << 3)
 #define USB_CDC_NCM_NCAP_CRC_MODE                      (1 << 4)
+#define        USB_CDC_NCM_NCAP_NTB_INPUT_SIZE                 (1 << 5)
 
 /* CDC NCM subclass Table 6-3: NTB Parameter Structure */
 #define USB_CDC_NCM_NTB16_SUPPORTED                    (1 << 0)
@@ -392,6 +398,13 @@ struct usb_cdc_ncm_ndp32 {
 #define USB_CDC_NCM_NTB_MIN_IN_SIZE                    2048
 #define USB_CDC_NCM_NTB_MIN_OUT_SIZE                   2048
 
+/* NTB Input Size Structure */
+struct usb_cdc_ncm_ndp_input_size {
+       __le32  dwNtbInMaxSize;
+       __le16  wNtbInMaxDatagrams;
+       __le16  wReserved;
+} __attribute__ ((packed));
+
 /* CDC NCM subclass 6.2.11 SetCrcMode */
 #define USB_CDC_NCM_CRC_NOT_APPENDED                   0x00
 #define USB_CDC_NCM_CRC_APPENDED                       0x01
index b92e173..7d1babb 100644 (file)
 #ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__
 #define __LINUX_USB_GADGET_MSM72K_UDC_H__
 
-#ifdef CONFIG_ARCH_MSM7X00A
-#define USB_SBUSCFG          (MSM_USB_BASE + 0x0090)
-#else
 #define USB_AHBBURST         (MSM_USB_BASE + 0x0090)
 #define USB_AHBMODE          (MSM_USB_BASE + 0x0098)
-#endif
 #define USB_CAPLENGTH        (MSM_USB_BASE + 0x0100) /* 8 bit */
 
 #define USB_USBCMD           (MSM_USB_BASE + 0x0140)
index a85064d..e4d3335 100644 (file)
@@ -7,7 +7,8 @@
  * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
  * anyone can use the definitions to implement compatible drivers/servers.
  *
- * Copyright (C) Red Hat, Inc., 2009, 2010
+ * Copyright (C) Red Hat, Inc., 2009, 2010, 2011
+ * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011
  */
 
 /* Feature bits */
index 6eb48e5..24fe022 100644 (file)
@@ -66,7 +66,7 @@ static unsigned long __cpuinit calibrate_delay_direct(void)
                pre_start = 0;
                read_current_timer(&start);
                start_jiffies = jiffies;
-               while (jiffies <= (start_jiffies + 1)) {
+               while (time_before_eq(jiffies, start_jiffies + 1)) {
                        pre_start = start;
                        read_current_timer(&start);
                }
@@ -74,8 +74,8 @@ static unsigned long __cpuinit calibrate_delay_direct(void)
 
                pre_end = 0;
                end = post_start;
-               while (jiffies <=
-                      (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) {
+               while (time_before_eq(jiffies, start_jiffies + 1 +
+                                              DELAY_CALIBRATION_TICKS)) {
                        pre_end = end;
                        read_current_timer(&end);
                }
index 2f05303..9e9385f 100644 (file)
@@ -306,7 +306,7 @@ int capable(int cap)
                BUG();
        }
 
-       if (security_capable(cap) == 0) {
+       if (security_capable(current_cred(), cap) == 0) {
                current->flags |= PF_SUPERPRIV;
                return 1;
        }
index a353a4d..3d3f282 100644 (file)
@@ -851,6 +851,10 @@ retry:
        raw_spin_unlock_irq(&ctx->lock);
 }
 
+#define MAX_INTERRUPTS (~0ULL)
+
+static void perf_log_throttle(struct perf_event *event, int enable);
+
 static int
 event_sched_in(struct perf_event *event,
                 struct perf_cpu_context *cpuctx,
@@ -863,6 +867,17 @@ event_sched_in(struct perf_event *event,
 
        event->state = PERF_EVENT_STATE_ACTIVE;
        event->oncpu = smp_processor_id();
+
+       /*
+        * Unthrottle events, since we scheduled we might have missed several
+        * ticks already, also for a heavily scheduling task there is little
+        * guarantee it'll get a tick in a timely manner.
+        */
+       if (unlikely(event->hw.interrupts == MAX_INTERRUPTS)) {
+               perf_log_throttle(event, 1);
+               event->hw.interrupts = 0;
+       }
+
        /*
         * The new state must be visible before we turn it on in the hardware:
         */
@@ -1661,10 +1676,6 @@ void __perf_event_task_sched_in(struct task_struct *task)
        }
 }
 
-#define MAX_INTERRUPTS (~0ULL)
-
-static void perf_log_throttle(struct perf_event *event, int enable);
-
 static u64 perf_calculate_period(struct perf_event *event, u64 nsec, u64 count)
 {
        u64 frequency = event->attr.sample_freq;
index 2ddbdc7..3623152 100644 (file)
@@ -262,25 +262,47 @@ int dmesg_restrict = 1;
 int dmesg_restrict;
 #endif
 
+static int syslog_action_restricted(int type)
+{
+       if (dmesg_restrict)
+               return 1;
+       /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
+       return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
+}
+
+static int check_syslog_permissions(int type, bool from_file)
+{
+       /*
+        * If this is from /proc/kmsg and we've already opened it, then we've
+        * already done the capabilities checks at open time.
+        */
+       if (from_file && type != SYSLOG_ACTION_OPEN)
+               return 0;
+
+       if (syslog_action_restricted(type)) {
+               if (capable(CAP_SYSLOG))
+                       return 0;
+               /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
+               if (capable(CAP_SYS_ADMIN)) {
+                       WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
+                                "but no CAP_SYSLOG (deprecated).\n");
+                       return 0;
+               }
+               return -EPERM;
+       }
+       return 0;
+}
+
 int do_syslog(int type, char __user *buf, int len, bool from_file)
 {
        unsigned i, j, limit, count;
        int do_clear = 0;
        char c;
-       int error = 0;
+       int error;
 
-       /*
-        * If this is from /proc/kmsg we only do the capabilities checks
-        * at open time.
-        */
-       if (type == SYSLOG_ACTION_OPEN || !from_file) {
-               if (dmesg_restrict && !capable(CAP_SYSLOG))
-                       goto warn; /* switch to return -EPERM after 2.6.39 */
-               if ((type != SYSLOG_ACTION_READ_ALL &&
-                    type != SYSLOG_ACTION_SIZE_BUFFER) &&
-                   !capable(CAP_SYSLOG))
-                       goto warn; /* switch to return -EPERM after 2.6.39 */
-       }
+       error = check_syslog_permissions(type, from_file);
+       if (error)
+               goto out;
 
        error = security_syslog(type);
        if (error)
@@ -423,12 +445,6 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
        }
 out:
        return error;
-warn:
-       /* remove after 2.6.39 */
-       if (capable(CAP_SYS_ADMIN))
-               WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
-                 "but no CAP_SYSLOG (deprecated and denied).\n");
-       return -EPERM;
 }
 
 SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
index 99bbaa3..1708b1e 100644 (file)
@@ -313,7 +313,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data)
                child->exit_code = data;
                dead = __ptrace_detach(current, child);
                if (!child->exit_state)
-                       wake_up_process(child);
+                       wake_up_state(child, TASK_TRACED | TASK_STOPPED);
        }
        write_unlock_irq(&tasklist_lock);
 
index 32a19f9..3258455 100644 (file)
@@ -41,7 +41,7 @@ static void print_name_offset(struct seq_file *m, void *sym)
        char symname[KSYM_NAME_LEN];
 
        if (lookup_symbol_name((unsigned long)sym, symname) < 0)
-               SEQ_printf(m, "<%p>", sym);
+               SEQ_printf(m, "<%pK>", sym);
        else
                SEQ_printf(m, "%s", symname);
 }
@@ -112,7 +112,7 @@ next_one:
 static void
 print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
 {
-       SEQ_printf(m, "  .base:       %p\n", base);
+       SEQ_printf(m, "  .base:       %pK\n", base);
        SEQ_printf(m, "  .index:      %d\n",
                        base->index);
        SEQ_printf(m, "  .resolution: %Lu nsecs\n",
index d53ce66..d645992 100644 (file)
@@ -959,7 +959,7 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
  *
  * Synchronization rules: Callers must prevent restarting of the timer,
  * otherwise this function is meaningless. It must not be called from
- * hardirq contexts. The caller must not hold locks which would prevent
+ * interrupt contexts. The caller must not hold locks which would prevent
  * completion of the timer's handler. The timer's handler must not call
  * add_timer_on(). Upon exit the timer is not queued and the handler is
  * not running on any CPU.
@@ -971,12 +971,10 @@ int del_timer_sync(struct timer_list *timer)
 #ifdef CONFIG_LOCKDEP
        unsigned long flags;
 
-       raw_local_irq_save(flags);
-       local_bh_disable();
+       local_irq_save(flags);
        lock_map_acquire(&timer->lockdep_map);
        lock_map_release(&timer->lockdep_map);
-       _local_bh_enable();
-       raw_local_irq_restore(flags);
+       local_irq_restore(flags);
 #endif
        /*
         * don't use it in hardirq context, because it
index 153562d..d95721f 100644 (file)
@@ -138,6 +138,13 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
                     !blk_tracer_enabled))
                return;
 
+       /*
+        * If the BLK_TC_NOTIFY action mask isn't set, don't send any note
+        * message to the trace.
+        */
+       if (!(bt->act_mask & BLK_TC_NOTIFY))
+               return;
+
        local_irq_save(flags);
        buf = per_cpu_ptr(bt->msg_data, smp_processor_id());
        va_start(args, fmt);
index 3967c23..2b97418 100644 (file)
@@ -805,7 +805,7 @@ config ARCH_WANT_FRAME_POINTERS
 config FRAME_POINTER
        bool "Compile the kernel with frame pointers"
        depends on DEBUG_KERNEL && \
-               (CRIS || M68K || M68KNOMMU || FRV || UML || \
+               (CRIS || M68K || FRV || UML || \
                 AVR32 || SUPERH || BLACKFIN || MN10300) || \
                ARCH_WANT_FRAME_POINTERS
        default y if (DEBUG_INFO && UML) || ARCH_WANT_FRAME_POINTERS
index b6c1ce3..3e29781 100644 (file)
@@ -1811,6 +1811,8 @@ static void collapse_huge_page(struct mm_struct *mm,
        /* VM_PFNMAP vmas may have vm_ops null but vm_file set */
        if (!vma->anon_vma || vma->vm_ops || vma->vm_file)
                goto out;
+       if (is_vma_temporary_stack(vma))
+               goto out;
        VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma));
 
        pgd = pgd_offset(mm, address);
@@ -1852,7 +1854,6 @@ static void collapse_huge_page(struct mm_struct *mm,
                set_pmd_at(mm, address, pmd, _pmd);
                spin_unlock(&mm->page_table_lock);
                anon_vma_unlock(vma->anon_vma);
-               mem_cgroup_uncharge_page(new_page);
                goto out;
        }
 
@@ -1898,6 +1899,7 @@ out_up_write:
        return;
 
 out:
+       mem_cgroup_uncharge_page(new_page);
 #ifdef CONFIG_NUMA
        put_page(new_page);
 #endif
@@ -2032,32 +2034,27 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages,
                if ((!(vma->vm_flags & VM_HUGEPAGE) &&
                     !khugepaged_always()) ||
                    (vma->vm_flags & VM_NOHUGEPAGE)) {
+               skip:
                        progress++;
                        continue;
                }
-
                /* VM_PFNMAP vmas may have vm_ops null but vm_file set */
-               if (!vma->anon_vma || vma->vm_ops || vma->vm_file) {
-                       khugepaged_scan.address = vma->vm_end;
-                       progress++;
-                       continue;
-               }
+               if (!vma->anon_vma || vma->vm_ops || vma->vm_file)
+                       goto skip;
+               if (is_vma_temporary_stack(vma))
+                       goto skip;
+
                VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma));
 
                hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
                hend = vma->vm_end & HPAGE_PMD_MASK;
-               if (hstart >= hend) {
-                       progress++;
-                       continue;
-               }
+               if (hstart >= hend)
+                       goto skip;
+               if (khugepaged_scan.address > hend)
+                       goto skip;
                if (khugepaged_scan.address < hstart)
                        khugepaged_scan.address = hstart;
-               if (khugepaged_scan.address > hend) {
-                       khugepaged_scan.address = hend + HPAGE_PMD_SIZE;
-                       progress++;
-                       continue;
-               }
-               BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK);
+               VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK);
 
                while (khugepaged_scan.address < hend) {
                        int ret;
@@ -2086,7 +2083,7 @@ breakouterloop:
 breakouterloop_mmap_sem:
 
        spin_lock(&khugepaged_mm_lock);
-       BUG_ON(khugepaged_scan.mm_slot != mm_slot);
+       VM_BUG_ON(khugepaged_scan.mm_slot != mm_slot);
        /*
         * Release the current mm_slot if this mm is about to die, or
         * if we scanned all vmas of this mm.
@@ -2241,9 +2238,9 @@ static int khugepaged(void *none)
 
        for (;;) {
                mutex_unlock(&khugepaged_mutex);
-               BUG_ON(khugepaged_thread != current);
+               VM_BUG_ON(khugepaged_thread != current);
                khugepaged_loop();
-               BUG_ON(khugepaged_thread != current);
+               VM_BUG_ON(khugepaged_thread != current);
 
                mutex_lock(&khugepaged_mutex);
                if (!khugepaged_enabled())
index bdba245..4618fda 100644 (file)
@@ -137,8 +137,6 @@ static phys_addr_t __init_memblock memblock_find_base(phys_addr_t size,
 
        BUG_ON(0 == size);
 
-       size = memblock_align_up(size, align);
-
        /* Pump up max_addr */
        if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
                end = memblock.current_limit;
index 31250fa..8e8c183 100644 (file)
@@ -2219,7 +2219,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
                                                         &ptl);
                        if (!pte_same(*page_table, orig_pte)) {
                                unlock_page(old_page);
-                               page_cache_release(old_page);
                                goto unlock;
                        }
                        page_cache_release(old_page);
@@ -2289,7 +2288,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
                                                         &ptl);
                        if (!pte_same(*page_table, orig_pte)) {
                                unlock_page(old_page);
-                               page_cache_release(old_page);
                                goto unlock;
                        }
 
@@ -2367,16 +2365,6 @@ gotten:
        }
        __SetPageUptodate(new_page);
 
-       /*
-        * Don't let another task, with possibly unlocked vma,
-        * keep the mlocked page.
-        */
-       if ((vma->vm_flags & VM_LOCKED) && old_page) {
-               lock_page(old_page);    /* for LRU manipulation */
-               clear_page_mlock(old_page);
-               unlock_page(old_page);
-       }
-
        if (mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))
                goto oom_free_new;
 
@@ -2444,10 +2432,20 @@ gotten:
 
        if (new_page)
                page_cache_release(new_page);
-       if (old_page)
-               page_cache_release(old_page);
 unlock:
        pte_unmap_unlock(page_table, ptl);
+       if (old_page) {
+               /*
+                * Don't let another task, with possibly unlocked vma,
+                * keep the mlocked page.
+                */
+               if ((ret & VM_FAULT_WRITE) && (vma->vm_flags & VM_LOCKED)) {
+                       lock_page(old_page);    /* LRU manipulation */
+                       munlock_vma_page(old_page);
+                       unlock_page(old_page);
+               }
+               page_cache_release(old_page);
+       }
        return ret;
 oom_free_new:
        page_cache_release(new_page);
@@ -3053,12 +3051,6 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                                goto out;
                        }
                        charged = 1;
-                       /*
-                        * Don't let another task, with possibly unlocked vma,
-                        * keep the mlocked page.
-                        */
-                       if (vma->vm_flags & VM_LOCKED)
-                               clear_page_mlock(vmf.page);
                        copy_user_highpage(page, vmf.page, address, vma);
                        __SetPageUptodate(page);
                } else {
index 148c6e6..17497d0 100644 (file)
@@ -1882,12 +1882,12 @@ static void shrink_zone(int priority, struct zone *zone,
        unsigned long nr[NR_LRU_LISTS];
        unsigned long nr_to_scan;
        enum lru_list l;
-       unsigned long nr_reclaimed;
+       unsigned long nr_reclaimed, nr_scanned;
        unsigned long nr_to_reclaim = sc->nr_to_reclaim;
-       unsigned long nr_scanned = sc->nr_scanned;
 
 restart:
        nr_reclaimed = 0;
+       nr_scanned = sc->nr_scanned;
        get_scan_count(zone, sc, nr, priority);
 
        while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
index ee41fef..d1a6113 100644 (file)
@@ -50,12 +50,12 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
                skb = tfp->skb;
        }
 
+       if (skb_linearize(skb) < 0 || skb_linearize(tmp_skb) < 0)
+               goto err;
+
        skb_pull(tmp_skb, sizeof(struct unicast_frag_packet));
-       if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) {
-               /* free buffered skb, skb will be freed later */
-               kfree_skb(tfp->skb);
-               return NULL;
-       }
+       if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0)
+               goto err;
 
        /* move free entry to end */
        tfp->skb = NULL;
@@ -70,6 +70,11 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
        unicast_packet->packet_type = BAT_UNICAST;
 
        return skb;
+
+err:
+       /* free buffered skb, skb will be freed later */
+       kfree_skb(tfp->skb);
+       return NULL;
 }
 
 static void frag_create_entry(struct list_head *head, struct sk_buff *skb)
index fa9dab3..6008d6d 100644 (file)
@@ -394,9 +394,7 @@ static void ipcaif_net_setup(struct net_device *dev)
        priv->conn_req.sockaddr.u.dgm.connection_id = -1;
        priv->flowenabled = false;
 
-       ASSERT_RTNL();
        init_waitqueue_head(&priv->netmgmt_wq);
-       list_add(&priv->list_field, &chnl_net_list);
 }
 
 
@@ -453,6 +451,8 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
        ret = register_netdevice(dev);
        if (ret)
                pr_warn("device rtml registration failed\n");
+       else
+               list_add(&caifdev->list_field, &chnl_net_list);
        return ret;
 }
 
index b6d0bf8..8e726cb 100644 (file)
@@ -5660,30 +5660,35 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 
        dev_net_set(dev, &init_net);
 
+       dev->gso_max_size = GSO_MAX_SIZE;
+
+       INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list);
+       dev->ethtool_ntuple_list.count = 0;
+       INIT_LIST_HEAD(&dev->napi_list);
+       INIT_LIST_HEAD(&dev->unreg_list);
+       INIT_LIST_HEAD(&dev->link_watch_list);
+       dev->priv_flags = IFF_XMIT_DST_RELEASE;
+       setup(dev);
+
        dev->num_tx_queues = txqs;
        dev->real_num_tx_queues = txqs;
        if (netif_alloc_netdev_queues(dev))
-               goto free_pcpu;
+               goto free_all;
 
 #ifdef CONFIG_RPS
        dev->num_rx_queues = rxqs;
        dev->real_num_rx_queues = rxqs;
        if (netif_alloc_rx_queues(dev))
-               goto free_pcpu;
+               goto free_all;
 #endif
 
-       dev->gso_max_size = GSO_MAX_SIZE;
-
-       INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list);
-       dev->ethtool_ntuple_list.count = 0;
-       INIT_LIST_HEAD(&dev->napi_list);
-       INIT_LIST_HEAD(&dev->unreg_list);
-       INIT_LIST_HEAD(&dev->link_watch_list);
-       dev->priv_flags = IFF_XMIT_DST_RELEASE;
-       setup(dev);
        strcpy(dev->name, name);
        return dev;
 
+free_all:
+       free_netdev(dev);
+       return NULL;
+
 free_pcpu:
        free_percpu(dev->pcpu_refcnt);
        kfree(dev->_tx);
index 4bc8a92..9cd73b1 100644 (file)
@@ -1822,6 +1822,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
                *cookie ^= 2;
                IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN;
                local->hw_roc_skb = skb;
+               local->hw_roc_skb_for_status = skb;
                mutex_unlock(&local->mtx);
 
                return 0;
@@ -1875,6 +1876,7 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
                if (ret == 0) {
                        kfree_skb(local->hw_roc_skb);
                        local->hw_roc_skb = NULL;
+                       local->hw_roc_skb_for_status = NULL;
                }
 
                mutex_unlock(&local->mtx);
index c47d7c0..533fd32 100644 (file)
@@ -953,7 +953,7 @@ struct ieee80211_local {
 
        struct ieee80211_channel *hw_roc_channel;
        struct net_device *hw_roc_dev;
-       struct sk_buff *hw_roc_skb;
+       struct sk_buff *hw_roc_skb, *hw_roc_skb_for_status;
        struct work_struct hw_roc_start, hw_roc_done;
        enum nl80211_channel_type hw_roc_channel_type;
        unsigned int hw_roc_duration;
index 38a7972..071ac95 100644 (file)
@@ -323,6 +323,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
                struct ieee80211_work *wk;
+               u64 cookie = (unsigned long)skb;
 
                rcu_read_lock();
                list_for_each_entry_rcu(wk, &local->work_list, list) {
@@ -334,8 +335,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                        break;
                }
                rcu_read_unlock();
+               if (local->hw_roc_skb_for_status == skb) {
+                       cookie = local->hw_roc_cookie ^ 2;
+                       local->hw_roc_skb_for_status = NULL;
+               }
                cfg80211_mgmt_tx_status(
-                       skb->dev, (unsigned long) skb, skb->data, skb->len,
+                       skb->dev, cookie, skb->data, skb->len,
                        !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
        }
 
index b64b42b..b0beaa5 100644 (file)
@@ -1547,7 +1547,7 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
                skb_orphan(skb);
        }
 
-       if (skb_header_cloned(skb))
+       if (skb_cloned(skb))
                I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
        else if (head_need || tail_need)
                I802_DEBUG_INC(local->tx_expand_skb_head);
index e615119..84f4fcc 100644 (file)
@@ -942,8 +942,15 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
        if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
                nf_conntrack_event_cache(IPCT_REPLY, ct);
 out:
-       if (tmpl)
-               nf_ct_put(tmpl);
+       if (tmpl) {
+               /* Special case: we have to repeat this hook, assign the
+                * template again to this packet. We assume that this packet
+                * has no conntrack assigned. This is used by nf_ct_tcp. */
+               if (ret == NF_REPEAT)
+                       skb->nfct = (struct nf_conntrack *)tmpl;
+               else
+                       nf_ct_put(tmpl);
+       }
 
        return ret;
 }
index 55187c8..4062075 100644 (file)
 #include <net/sock.h>
 #include <net/x25.h>
 
-/*
- * Parse a set of facilities into the facilities structures. Unrecognised
- *     facilities are written to the debug log file.
+/**
+ * x25_parse_facilities - Parse facilities from skb into the facilities structs
+ *
+ * @skb: sk_buff to parse
+ * @facilities: Regular facilites, updated as facilities are found
+ * @dte_facs: ITU DTE facilities, updated as DTE facilities are found
+ * @vc_fac_mask: mask is updated with all facilities found
+ *
+ * Return codes:
+ *  -1 - Parsing error, caller should drop call and clean up
+ *   0 - Parse OK, this skb has no facilities
+ *  >0 - Parse OK, returns the length of the facilities header
+ *
  */
 int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
@@ -62,7 +72,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                switch (*p & X25_FAC_CLASS_MASK) {
                case X25_FAC_CLASS_A:
                        if (len < 2)
-                               return 0;
+                               return -1;
                        switch (*p) {
                        case X25_FAC_REVERSE:
                                if((p[1] & 0x81) == 0x81) {
@@ -107,7 +117,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                        break;
                case X25_FAC_CLASS_B:
                        if (len < 3)
-                               return 0;
+                               return -1;
                        switch (*p) {
                        case X25_FAC_PACKET_SIZE:
                                facilities->pacsize_in  = p[1];
@@ -130,7 +140,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                        break;
                case X25_FAC_CLASS_C:
                        if (len < 4)
-                               return 0;
+                               return -1;
                        printk(KERN_DEBUG "X.25: unknown facility %02X, "
                               "values %02X, %02X, %02X\n",
                               p[0], p[1], p[2], p[3]);
@@ -139,18 +149,18 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                        break;
                case X25_FAC_CLASS_D:
                        if (len < p[1] + 2)
-                               return 0;
+                               return -1;
                        switch (*p) {
                        case X25_FAC_CALLING_AE:
                                if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
-                                       return 0;
+                                       return -1;
                                dte_facs->calling_len = p[2];
                                memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
                                *vc_fac_mask |= X25_MASK_CALLING_AE;
                                break;
                        case X25_FAC_CALLED_AE:
                                if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
-                                       return 0;
+                                       return -1;
                                dte_facs->called_len = p[2];
                                memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
                                *vc_fac_mask |= X25_MASK_CALLED_AE;
index f729f02..15de65f 100644 (file)
@@ -91,10 +91,10 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
 {
        struct x25_address source_addr, dest_addr;
        int len;
+       struct x25_sock *x25 = x25_sk(sk);
 
        switch (frametype) {
                case X25_CALL_ACCEPTED: {
-                       struct x25_sock *x25 = x25_sk(sk);
 
                        x25_stop_timer(sk);
                        x25->condition = 0x00;
@@ -113,14 +113,16 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                                                &dest_addr);
                        if (len > 0)
                                skb_pull(skb, len);
+                       else if (len < 0)
+                               goto out_clear;
 
                        len = x25_parse_facilities(skb, &x25->facilities,
                                                &x25->dte_facilities,
                                                &x25->vc_facil_mask);
                        if (len > 0)
                                skb_pull(skb, len);
-                       else
-                               return -1;
+                       else if (len < 0)
+                               goto out_clear;
                        /*
                         *      Copy any Call User Data.
                         */
@@ -144,6 +146,12 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
        }
 
        return 0;
+
+out_clear:
+       x25_write_internal(sk, X25_CLEAR_REQUEST);
+       x25->state = X25_STATE_2;
+       x25_start_t23timer(sk);
+       return 0;
 }
 
 /*
index 4cbc942..2130692 100644 (file)
@@ -396,9 +396,12 @@ void __exit x25_link_free(void)
        write_lock_bh(&x25_neigh_list_lock);
 
        list_for_each_safe(entry, tmp, &x25_neigh_list) {
+               struct net_device *dev;
+
                nb = list_entry(entry, struct x25_neigh, node);
+               dev = nb->dev;
                __x25_remove_neigh(nb);
-               dev_put(nb->dev);
+               dev_put(dev);
        }
        write_unlock_bh(&x25_neigh_list_lock);
 }
index b0b2357..f6cbc3d 100644 (file)
@@ -238,12 +238,12 @@ EOF
 fi
 
 # Build header package
-find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$
-find arch/x86/include include scripts -type f >> /tmp/files$$
+(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$)
+(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> /tmp/files$$)
 (cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$)
 destdir=$kernel_headers_dir/usr/src/linux-headers-$version
 mkdir -p "$destdir"
-tar -c -f - -T /tmp/files$$ | (cd $destdir; tar -xf -)
+(cd $srctree; tar -c -f - -T /tmp/files$$) | (cd $destdir; tar -xf -)
 (cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -)
 rm -f /tmp/files$$ /tmp/objfiles$$
 arch=$(dpkg --print-architecture)
index 739e403..7b7308a 100644 (file)
@@ -154,10 +154,9 @@ int security_capset(struct cred *new, const struct cred *old,
                                    effective, inheritable, permitted);
 }
 
-int security_capable(int cap)
+int security_capable(const struct cred *cred, int cap)
 {
-       return security_ops->capable(current, current_cred(), cap,
-                                    SECURITY_CAP_AUDIT);
+       return security_ops->capable(current, cred, cap, SECURITY_CAP_AUDIT);
 }
 
 int security_real_capable(struct task_struct *tsk, int cap)
index 7730575..b8b31c4 100644 (file)
@@ -45,12 +45,13 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
 {
        struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
        struct snd_timer *t = stime->timer;
+       unsigned long oruns;
 
        if (!atomic_read(&stime->running))
                return HRTIMER_NORESTART;
 
-       hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
-       snd_timer_interrupt(stime->timer, t->sticks);
+       oruns = hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
+       snd_timer_interrupt(stime->timer, t->sticks * oruns);
 
        if (!atomic_read(&stime->running))
                return HRTIMER_NORESTART;
@@ -104,7 +105,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
 }
 
 static struct snd_timer_hardware hrtimer_hw = {
-       .flags =        SNDRV_TIMER_HW_AUTO,
+       .flags =        SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_TASKLET,
        .open =         snd_hrtimer_open,
        .close =        snd_hrtimer_close,
        .start =        snd_hrtimer_start,
index 2e91a99..0baffcd 100644 (file)
@@ -2703,7 +2703,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
        if (err < 0)
                goto out_free;
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
-       if (patch[dev]) {
+       if (patch[dev] && *patch[dev]) {
                snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
                           patch[dev]);
                err = snd_hda_load_patch(chip->bus, patch[dev]);
index 2d5b83f..a587677 100644 (file)
@@ -642,6 +642,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
                        hdmi_ai->ver            = 0x01;
                        hdmi_ai->len            = 0x0a;
                        hdmi_ai->CC02_CT47      = channels - 1;
+                       hdmi_ai->CA             = ca;
                        hdmi_checksum_audio_infoframe(hdmi_ai);
                } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */
                        struct dp_audio_infoframe *dp_ai;
@@ -651,6 +652,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
                        dp_ai->len              = 0x1b;
                        dp_ai->ver              = 0x11 << 2;
                        dp_ai->CC02_CT47        = channels - 1;
+                       dp_ai->CA               = ca;
                } else {
                        snd_printd("HDMI: unknown connection type at pin %d\n",
                                   pin_nid);
index 2fa9ed9..3328a25 100644 (file)
@@ -2290,6 +2290,29 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0f, 2, 0x0,
+               HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0f, 2, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Side Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Side Playback Switch", 0x0e, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
+
 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -10359,7 +10382,7 @@ static struct alc_config_preset alc882_presets[] = {
                .init_hook = alc_automute_amp,
        },
        [ALC888_ACER_ASPIRE_4930G] = {
-               .mixers = { alc888_base_mixer,
+               .mixers = { alc888_acer_aspire_4930g_mixer,
                                alc883_chmode_mixer },
                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
                                alc888_acer_aspire_4930g_verbs },
@@ -18802,6 +18825,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
                                        ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
                           ALC663_ASUS_H13),
+       SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
        {}
 };
 
@@ -19494,6 +19518,7 @@ static const struct alc_fixup alc662_fixups[] = {
 };
 
 static struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
index 3351f77..37b8aa8 100644 (file)
@@ -1287,9 +1287,9 @@ SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
 
-SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
+SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL,
                     0, WM8994_POWER_MANAGEMENT_4, 9, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
+SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL,
                     0, WM8994_POWER_MANAGEMENT_4, 8, 0),
 SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
                      WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
@@ -1298,9 +1298,9 @@ SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
                      WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
                      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
-SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
+SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL,
                     0, WM8994_POWER_MANAGEMENT_4, 11, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
+SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL,
                     0, WM8994_POWER_MANAGEMENT_4, 10, 0),
 SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
                      WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
@@ -1345,6 +1345,7 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
 
 SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
 
 SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
@@ -1546,6 +1547,11 @@ static const struct snd_soc_dapm_route intercon[] = {
        { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
        { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
 
+       { "AIF1ADCDAT", NULL, "AIF1ADC1L" },
+       { "AIF1ADCDAT", NULL, "AIF1ADC1R" },
+       { "AIF1ADCDAT", NULL, "AIF1ADC2L" },
+       { "AIF1ADCDAT", NULL, "AIF1ADC2R" },
+
        { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
 
        /* AIF3 output */
@@ -1578,6 +1584,13 @@ static const struct snd_soc_dapm_route intercon[] = {
        { "Right Headphone Mux", "DAC", "DAC1R" },
 };
 
+static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
+       { "AIF1DACDAT", NULL, "AIF2DACDAT" },
+       { "AIF2DACDAT", NULL, "AIF1DACDAT" },
+       { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
+       { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
+};
+
 static const struct snd_soc_dapm_route wm8994_intercon[] = {
        { "AIF2DACL", NULL, "AIF2DAC Mux" },
        { "AIF2DACR", NULL, "AIF2DAC Mux" },
@@ -3129,6 +3142,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        case WM8994:
                snd_soc_dapm_add_routes(dapm, wm8994_intercon,
                                        ARRAY_SIZE(wm8994_intercon));
+
+               if (wm8994->revision < 4)
+                       snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
+                                               ARRAY_SIZE(wm8994_revd_intercon));
+                       
                break;
        case WM8958:
                snd_soc_dapm_add_routes(dapm, wm8958_intercon,
index b36f0b3..fe79842 100644 (file)
@@ -218,7 +218,19 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
                .ops = &evm_spdif_ops,
        },
 };
-static struct snd_soc_dai_link da8xx_evm_dai = {
+
+static struct snd_soc_dai_link da830_evm_dai = {
+       .name = "TLV320AIC3X",
+       .stream_name = "AIC3X",
+       .cpu_dai_name = "davinci-mcasp.1",
+       .codec_dai_name = "tlv320aic3x-hifi",
+       .codec_name = "tlv320aic3x-codec.1-0018",
+       .platform_name = "davinci-pcm-audio",
+       .init = evm_aic3x_init,
+       .ops = &evm_ops,
+};
+
+static struct snd_soc_dai_link da850_evm_dai = {
        .name = "TLV320AIC3X",
        .stream_name = "AIC3X",
        .cpu_dai_name= "davinci-mcasp.0",
@@ -259,13 +271,13 @@ static struct snd_soc_card dm6467_snd_soc_card_evm = {
 
 static struct snd_soc_card da830_snd_soc_card = {
        .name = "DA830/OMAP-L137 EVM",
-       .dai_link = &da8xx_evm_dai,
+       .dai_link = &da830_evm_dai,
        .num_links = 1,
 };
 
 static struct snd_soc_card da850_snd_soc_card = {
        .name = "DA850/OMAP-L138 EVM",
-       .dai_link = &da8xx_evm_dai,
+       .dai_link = &da850_evm_dai,
        .num_links = 1,
 };
 
index c4b6061..c3f6f1e 100644 (file)
@@ -1449,6 +1449,7 @@ static int soc_post_component_init(struct snd_soc_card *card,
                rtd = &card->rtd_aux[num];
                name = aux_dev->name;
        }
+       rtd->card = card;
 
        /* machine controls, routes and widgets are not prefixed */
        temp = codec->name_prefix;
@@ -1471,7 +1472,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
 
        /* register the rtd device */
        rtd->codec = codec;
-       rtd->card = card;
        rtd->dev.parent = card->dev;
        rtd->dev.release = rtd_release;
        rtd->dev.init_name = name;
index 7df89b3..85af605 100644 (file)
@@ -95,7 +95,7 @@ enum {
 };
 
 
-/*E-mu 0202(0404) eXtension Unit(XU) control*/
+/*E-mu 0202/0404/0204 eXtension Unit(XU) control*/
 enum {
        USB_XU_CLOCK_RATE               = 0xe301,
        USB_XU_CLOCK_SOURCE             = 0xe302,
@@ -1566,7 +1566,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
                        cval->initialized = 1;
                } else {
                        if (type == USB_XU_CLOCK_RATE) {
-                               /* E-Mu USB 0404/0202/TrackerPre
+                               /* E-Mu USB 0404/0202/TrackerPre/0204
                                 * samplerate control quirk
                                 */
                                cval->min = 0;
index 3599987..921a86f 100644 (file)
        .idProduct = 0x3f0a,
        .bInterfaceClass = USB_CLASS_AUDIO,
 },
+{
+       /* E-Mu 0204 USB */
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+       .idVendor = 0x041e,
+       .idProduct = 0x3f19,
+       .bInterfaceClass = USB_CLASS_AUDIO,
+},
 
 /*
  * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
index cf8bf08..e314cdb 100644 (file)
@@ -532,7 +532,7 @@ int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat
 }
 
 /*
- * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
+ * For E-Mu 0404USB/0202USB/TrackerPre/0204 sample rate should be set for device,
  * not for interface.
  */
 
@@ -589,6 +589,7 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
        case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
        case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
        case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
+       case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
                set_format_emu_quirk(subs, fmt);
                break;
        }
index 4c6983d..362a0cb 100644 (file)
@@ -72,7 +72,7 @@ int need_reinitialize;
 
 int num_cpus;
 
-typedef struct per_cpu_counters {
+struct counters {
        unsigned long long tsc;         /* per thread */
        unsigned long long aperf;       /* per thread */
        unsigned long long mperf;       /* per thread */
@@ -88,13 +88,13 @@ typedef struct per_cpu_counters {
        int pkg;
        int core;
        int cpu;
-       struct per_cpu_counters *next;
-} PCC;
+       struct counters *next;
+};
 
-PCC *pcc_even;
-PCC *pcc_odd;
-PCC *pcc_delta;
-PCC *pcc_average;
+struct counters *cnt_even;
+struct counters *cnt_odd;
+struct counters *cnt_delta;
+struct counters *cnt_average;
 struct timeval tv_even;
 struct timeval tv_odd;
 struct timeval tv_delta;
@@ -125,7 +125,7 @@ unsigned long long get_msr(int cpu, off_t offset)
        return msr;
 }
 
-void print_header()
+void print_header(void)
 {
        if (show_pkg)
                fprintf(stderr, "pkg ");
@@ -160,39 +160,39 @@ void print_header()
        putc('\n', stderr);
 }
 
-void dump_pcc(PCC *pcc)
+void dump_cnt(struct counters *cnt)
 {
-       fprintf(stderr, "package: %d ", pcc->pkg);
-       fprintf(stderr, "core:: %d ", pcc->core);
-       fprintf(stderr, "CPU: %d ", pcc->cpu);
-       fprintf(stderr, "TSC: %016llX\n", pcc->tsc);
-       fprintf(stderr, "c3: %016llX\n", pcc->c3);
-       fprintf(stderr, "c6: %016llX\n", pcc->c6);
-       fprintf(stderr, "c7: %016llX\n", pcc->c7);
-       fprintf(stderr, "aperf: %016llX\n", pcc->aperf);
-       fprintf(stderr, "pc2: %016llX\n", pcc->pc2);
-       fprintf(stderr, "pc3: %016llX\n", pcc->pc3);
-       fprintf(stderr, "pc6: %016llX\n", pcc->pc6);
-       fprintf(stderr, "pc7: %016llX\n", pcc->pc7);
-       fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, pcc->extra_msr);
+       fprintf(stderr, "package: %d ", cnt->pkg);
+       fprintf(stderr, "core:: %d ", cnt->core);
+       fprintf(stderr, "CPU: %d ", cnt->cpu);
+       fprintf(stderr, "TSC: %016llX\n", cnt->tsc);
+       fprintf(stderr, "c3: %016llX\n", cnt->c3);
+       fprintf(stderr, "c6: %016llX\n", cnt->c6);
+       fprintf(stderr, "c7: %016llX\n", cnt->c7);
+       fprintf(stderr, "aperf: %016llX\n", cnt->aperf);
+       fprintf(stderr, "pc2: %016llX\n", cnt->pc2);
+       fprintf(stderr, "pc3: %016llX\n", cnt->pc3);
+       fprintf(stderr, "pc6: %016llX\n", cnt->pc6);
+       fprintf(stderr, "pc7: %016llX\n", cnt->pc7);
+       fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, cnt->extra_msr);
 }
 
-void dump_list(PCC *pcc)
+void dump_list(struct counters *cnt)
 {
-       printf("dump_list 0x%p\n", pcc);
+       printf("dump_list 0x%p\n", cnt);
 
-       for (; pcc; pcc = pcc->next)
-               dump_pcc(pcc);
+       for (; cnt; cnt = cnt->next)
+               dump_cnt(cnt);
 }
 
-void print_pcc(PCC *p)
+void print_cnt(struct counters *p)
 {
        double interval_float;
 
        interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
 
        /* topology columns, print blanks on 1st (average) line */
-       if (p == pcc_average) {
+       if (p == cnt_average) {
                if (show_pkg)
                        fprintf(stderr, "    ");
                if (show_core)
@@ -262,24 +262,24 @@ void print_pcc(PCC *p)
        putc('\n', stderr);
 }
 
-void print_counters(PCC *cnt)
+void print_counters(struct counters *counters)
 {
-       PCC *pcc;
+       struct counters *cnt;
 
        print_header();
 
        if (num_cpus > 1)
-               print_pcc(pcc_average);
+               print_cnt(cnt_average);
 
-       for (pcc = cnt; pcc != NULL; pcc = pcc->next)
-               print_pcc(pcc);
+       for (cnt = counters; cnt != NULL; cnt = cnt->next)
+               print_cnt(cnt);
 
 }
 
 #define SUBTRACT_COUNTER(after, before, delta) (delta = (after - before), (before > after))
 
-
-int compute_delta(PCC *after, PCC *before, PCC *delta)
+int compute_delta(struct counters *after,
+       struct counters *before, struct counters *delta)
 {
        int errors = 0;
        int perf_err = 0;
@@ -391,20 +391,20 @@ int compute_delta(PCC *after, PCC *before, PCC *delta)
                delta->extra_msr = after->extra_msr;
                if (errors) {
                        fprintf(stderr, "ERROR cpu%d before:\n", before->cpu);
-                       dump_pcc(before);
+                       dump_cnt(before);
                        fprintf(stderr, "ERROR cpu%d after:\n", before->cpu);
-                       dump_pcc(after);
+                       dump_cnt(after);
                        errors = 0;
                }
        }
        return 0;
 }
 
-void compute_average(PCC *delta, PCC *avg)
+void compute_average(struct counters *delta, struct counters *avg)
 {
-       PCC *sum;
+       struct counters *sum;
 
-       sum = calloc(1, sizeof(PCC));
+       sum = calloc(1, sizeof(struct counters));
        if (sum == NULL) {
                perror("calloc sum");
                exit(1);
@@ -438,35 +438,34 @@ void compute_average(PCC *delta, PCC *avg)
        free(sum);
 }
 
-void get_counters(PCC *pcc)
+void get_counters(struct counters *cnt)
 {
-       for ( ; pcc; pcc = pcc->next) {
-               pcc->tsc = get_msr(pcc->cpu, MSR_TSC);
+       for ( ; cnt; cnt = cnt->next) {
+               cnt->tsc = get_msr(cnt->cpu, MSR_TSC);
                if (do_nhm_cstates)
-                       pcc->c3 = get_msr(pcc->cpu, MSR_CORE_C3_RESIDENCY);
+                       cnt->c3 = get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY);
                if (do_nhm_cstates)
-                       pcc->c6 = get_msr(pcc->cpu, MSR_CORE_C6_RESIDENCY);
+                       cnt->c6 = get_msr(cnt->cpu, MSR_CORE_C6_RESIDENCY);
                if (do_snb_cstates)
-                       pcc->c7 = get_msr(pcc->cpu, MSR_CORE_C7_RESIDENCY);
+                       cnt->c7 = get_msr(cnt->cpu, MSR_CORE_C7_RESIDENCY);
                if (has_aperf)
-                       pcc->aperf = get_msr(pcc->cpu, MSR_APERF);
+                       cnt->aperf = get_msr(cnt->cpu, MSR_APERF);
                if (has_aperf)
-                       pcc->mperf = get_msr(pcc->cpu, MSR_MPERF);
+                       cnt->mperf = get_msr(cnt->cpu, MSR_MPERF);
                if (do_snb_cstates)
-                       pcc->pc2 = get_msr(pcc->cpu, MSR_PKG_C2_RESIDENCY);
+                       cnt->pc2 = get_msr(cnt->cpu, MSR_PKG_C2_RESIDENCY);
                if (do_nhm_cstates)
-                       pcc->pc3 = get_msr(pcc->cpu, MSR_PKG_C3_RESIDENCY);
+                       cnt->pc3 = get_msr(cnt->cpu, MSR_PKG_C3_RESIDENCY);
                if (do_nhm_cstates)
-                       pcc->pc6 = get_msr(pcc->cpu, MSR_PKG_C6_RESIDENCY);
+                       cnt->pc6 = get_msr(cnt->cpu, MSR_PKG_C6_RESIDENCY);
                if (do_snb_cstates)
-                       pcc->pc7 = get_msr(pcc->cpu, MSR_PKG_C7_RESIDENCY);
+                       cnt->pc7 = get_msr(cnt->cpu, MSR_PKG_C7_RESIDENCY);
                if (extra_msr_offset)
-                       pcc->extra_msr = get_msr(pcc->cpu, extra_msr_offset);
+                       cnt->extra_msr = get_msr(cnt->cpu, extra_msr_offset);
        }
 }
 
-
-void print_nehalem_info()
+void print_nehalem_info(void)
 {
        unsigned long long msr;
        unsigned int ratio;
@@ -514,38 +513,38 @@ void print_nehalem_info()
 
 }
 
-void free_counter_list(PCC *list)
+void free_counter_list(struct counters *list)
 {
-       PCC *p;
+       struct counters *p;
 
        for (p = list; p; ) {
-               PCC *free_me;
+               struct counters *free_me;
 
                free_me = p;
                p = p->next;
                free(free_me);
        }
-       return;
 }
 
 void free_all_counters(void)
 {
-       free_counter_list(pcc_even);
-       pcc_even = NULL;
+       free_counter_list(cnt_even);
+       cnt_even = NULL;
 
-       free_counter_list(pcc_odd);
-       pcc_odd = NULL;
+       free_counter_list(cnt_odd);
+       cnt_odd = NULL;
 
-       free_counter_list(pcc_delta);
-       pcc_delta = NULL;
+       free_counter_list(cnt_delta);
+       cnt_delta = NULL;
 
-       free_counter_list(pcc_average);
-       pcc_average = NULL;
+       free_counter_list(cnt_average);
+       cnt_average = NULL;
 }
 
-void insert_cpu_counters(PCC **list, PCC *new)
+void insert_counters(struct counters **list,
+       struct counters *new)
 {
-       PCC *prev;
+       struct counters *prev;
 
        /*
         * list was empty
@@ -594,18 +593,16 @@ void insert_cpu_counters(PCC **list, PCC *new)
         */
        new->next = prev->next;
        prev->next = new;
-
-       return;
 }
 
-void alloc_new_cpu_counters(int pkg, int core, int cpu)
+void alloc_new_counters(int pkg, int core, int cpu)
 {
-       PCC *new;
+       struct counters *new;
 
        if (verbose > 1)
                printf("pkg%d core%d, cpu%d\n", pkg, core, cpu);
 
-       new = (PCC *)calloc(1, sizeof(PCC));
+       new = (struct counters *)calloc(1, sizeof(struct counters));
        if (new == NULL) {
                perror("calloc");
                exit(1);
@@ -613,9 +610,10 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu)
        new->pkg = pkg;
        new->core = core;
        new->cpu = cpu;
-       insert_cpu_counters(&pcc_odd, new);
+       insert_counters(&cnt_odd, new);
 
-       new = (PCC *)calloc(1, sizeof(PCC));
+       new = (struct counters *)calloc(1,
+               sizeof(struct counters));
        if (new == NULL) {
                perror("calloc");
                exit(1);
@@ -623,9 +621,9 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu)
        new->pkg = pkg;
        new->core = core;
        new->cpu = cpu;
-       insert_cpu_counters(&pcc_even, new);
+       insert_counters(&cnt_even, new);
 
-       new = (PCC *)calloc(1, sizeof(PCC));
+       new = (struct counters *)calloc(1, sizeof(struct counters));
        if (new == NULL) {
                perror("calloc");
                exit(1);
@@ -633,9 +631,9 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu)
        new->pkg = pkg;
        new->core = core;
        new->cpu = cpu;
-       insert_cpu_counters(&pcc_delta, new);
+       insert_counters(&cnt_delta, new);
 
-       new = (PCC *)calloc(1, sizeof(PCC));
+       new = (struct counters *)calloc(1, sizeof(struct counters));
        if (new == NULL) {
                perror("calloc");
                exit(1);
@@ -643,7 +641,7 @@ void alloc_new_cpu_counters(int pkg, int core, int cpu)
        new->pkg = pkg;
        new->core = core;
        new->cpu = cpu;
-       pcc_average = new;
+       cnt_average = new;
 }
 
 int get_physical_package_id(int cpu)
@@ -719,7 +717,7 @@ void re_initialize(void)
 {
        printf("turbostat: topology changed, re-initializing.\n");
        free_all_counters();
-       num_cpus = for_all_cpus(alloc_new_cpu_counters);
+       num_cpus = for_all_cpus(alloc_new_counters);
        need_reinitialize = 0;
        printf("num_cpus is now %d\n", num_cpus);
 }
@@ -728,7 +726,7 @@ void dummy(int pkg, int core, int cpu) { return; }
 /*
  * check to see if a cpu came on-line
  */
-void verify_num_cpus()
+void verify_num_cpus(void)
 {
        int new_num_cpus;
 
@@ -740,14 +738,12 @@ void verify_num_cpus()
                                num_cpus, new_num_cpus);
                need_reinitialize = 1;
        }
-
-       return;
 }
 
 void turbostat_loop()
 {
 restart:
-       get_counters(pcc_even);
+       get_counters(cnt_even);
        gettimeofday(&tv_even, (struct timezone *)NULL);
 
        while (1) {
@@ -757,24 +753,24 @@ restart:
                        goto restart;
                }
                sleep(interval_sec);
-               get_counters(pcc_odd);
+               get_counters(cnt_odd);
                gettimeofday(&tv_odd, (struct timezone *)NULL);
 
-               compute_delta(pcc_odd, pcc_even, pcc_delta);
+               compute_delta(cnt_odd, cnt_even, cnt_delta);
                timersub(&tv_odd, &tv_even, &tv_delta);
-               compute_average(pcc_delta, pcc_average);
-               print_counters(pcc_delta);
+               compute_average(cnt_delta, cnt_average);
+               print_counters(cnt_delta);
                if (need_reinitialize) {
                        re_initialize();
                        goto restart;
                }
                sleep(interval_sec);
-               get_counters(pcc_even);
+               get_counters(cnt_even);
                gettimeofday(&tv_even, (struct timezone *)NULL);
-               compute_delta(pcc_even, pcc_odd, pcc_delta);
+               compute_delta(cnt_even, cnt_odd, cnt_delta);
                timersub(&tv_even, &tv_odd, &tv_delta);
-               compute_average(pcc_delta, pcc_average);
-               print_counters(pcc_delta);
+               compute_average(cnt_delta, cnt_average);
+               print_counters(cnt_delta);
        }
 }
 
@@ -892,7 +888,7 @@ void check_cpuid()
         * this check is valid for both Intel and AMD
         */
        asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007));
-       has_invariant_tsc = edx && (1 << 8);
+       has_invariant_tsc = edx & (1 << 8);
 
        if (!has_invariant_tsc) {
                fprintf(stderr, "No invariant TSC\n");
@@ -905,7 +901,7 @@ void check_cpuid()
         */
 
        asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6));
-       has_aperf = ecx && (1 << 0);
+       has_aperf = ecx & (1 << 0);
        if (!has_aperf) {
                fprintf(stderr, "No APERF MSR\n");
                exit(1);
@@ -952,7 +948,7 @@ void turbostat_init()
        check_dev_msr();
        check_super_user();
 
-       num_cpus = for_all_cpus(alloc_new_cpu_counters);
+       num_cpus = for_all_cpus(alloc_new_counters);
 
        if (verbose)
                print_nehalem_info();
@@ -962,7 +958,7 @@ int fork_it(char **argv)
 {
        int retval;
        pid_t child_pid;
-       get_counters(pcc_even);
+       get_counters(cnt_even);
        gettimeofday(&tv_even, (struct timezone *)NULL);
 
        child_pid = fork();
@@ -985,14 +981,14 @@ int fork_it(char **argv)
                        exit(1);
                }
        }
-       get_counters(pcc_odd);
+       get_counters(cnt_odd);
        gettimeofday(&tv_odd, (struct timezone *)NULL);
-       retval = compute_delta(pcc_odd, pcc_even, pcc_delta);
+       retval = compute_delta(cnt_odd, cnt_even, cnt_delta);
 
        timersub(&tv_odd, &tv_even, &tv_delta);
-       compute_average(pcc_delta, pcc_average);
+       compute_average(cnt_delta, cnt_average);
        if (!retval)
-               print_counters(pcc_delta);
+               print_counters(cnt_delta);
 
        fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);;