Merge tag 'staging-3.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 May 2013 16:27:49 +0000 (09:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 May 2013 16:27:49 +0000 (09:27 -0700)
Pull staging driver fixes from Greg Kroah-Hartman:
 "Here are some staging tree driver fixes for 3.10-rc2

  The drivers/iio/ changes are here as they are still tied into
  drivers/staging/iio/.

  Nothing major, just a number of small bugfixes, and a larger
  documentation update for the ramster code."

* tag 'staging-3.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (28 commits)
  staging: dwc2: remove compile warning for USB_DWC2_TRACK_MISSED_SOFS
  iio: exynos_adc: fix wrong structure extration in suspend and resume
  iio:common:st: added disable function after read info raw data
  iio: dac: Fix build error when CONFIG_SPI_MASTER=y && CONFIG_I2C=m
  staging:iio:light:tsl2x7x: fix the error handling in tsl2x7x_probe()
  staging/iio/mxs-lradc: fix preenable for multiple buffers
  staging: imx-drm: imx-tve: Check the return value of 'regulator_enable()'
  staging: video: imx: Select VIDEOMODE_HELPERS for parallel display
  staging: ramster: add how-to document
  staging: dwc2: Fix dma-enabled platform devices using a default dma_mask
  staging: vt6656: [bug] Fix missing spin lock in iwctl_siwpower.
  staging: Swap zram and zsmalloc in Kconfig
  staging: android: logger: use kuid_t instead of uid_t
  staging: zcache: Fix incorrect module_param_array types
  staging/solo6x10: depend on CONFIG_FONTS
  staging/drm: imx: add missing dependencies
  staging: ste_rmi4: Suppress 'ignoring return value of â€˜regulator_enable()' warning
  staging: sep: fix driver build and kconfig
  staging: nvec: cleanup childs on remove
  staging: nvec: implement unregistering of notifiers
  ...

538 files changed:
Documentation/devicetree/bindings/drm/exynos/hdmi.txt [deleted file]
Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt [deleted file]
Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt [deleted file]
Documentation/devicetree/bindings/drm/exynos/mixer.txt [deleted file]
Documentation/devicetree/bindings/video/exynos_hdmi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/exynos_hdmiddc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/exynos_hdmiphy.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/exynos_mixer.txt [new file with mode: 0644]
Documentation/devicetree/usage-model.txt
Documentation/kernel-parameters.txt
Documentation/kernel-per-CPU-kthreads.txt [new file with mode: 0644]
Documentation/power/devices.txt
Documentation/power/interface.txt
Documentation/power/notifiers.txt
Documentation/power/states.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/common/mcpm_platsmp.c
arch/arm/configs/omap1_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/include/asm/cmpxchg.h
arch/arm/kernel/smp.c
arch/arm/mach-tegra/tegra2_emc.c
arch/arm/plat-samsung/adc.c
arch/arm/xen/enlighten.c
arch/arm64/Kconfig
arch/arm64/include/asm/assembler.h
arch/arm64/kernel/debug-monitors.c
arch/arm64/kernel/early_printk.c
arch/arm64/kernel/setup.c
arch/arm64/mm/cache.S
arch/arm64/mm/proc.S
arch/avr32/Kconfig
arch/avr32/include/asm/Kbuild
arch/avr32/include/asm/numnodes.h [deleted file]
arch/avr32/include/asm/param.h [deleted file]
arch/avr32/include/uapi/asm/Kbuild
arch/avr32/include/uapi/asm/param.h [deleted file]
arch/avr32/kernel/module.c
arch/mips/alchemy/board-gpr.c
arch/mips/alchemy/common/time.c
arch/mips/ath79/setup.c
arch/mips/cobalt/reset.c
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1235_defconfig
arch/mips/configs/lemote2f_defconfig
arch/mips/include/asm/clock.h
arch/mips/include/asm/idle.h [new file with mode: 0644]
arch/mips/include/asm/io.h
arch/mips/include/asm/kvm.h [deleted file]
arch/mips/include/asm/kvm_host.h
arch/mips/include/asm/mmu_context.h
arch/mips/include/asm/page.h
arch/mips/include/asm/processor.h
arch/mips/include/uapi/asm/kvm.h [new file with mode: 0644]
arch/mips/include/uapi/asm/unistd.h
arch/mips/kernel/Makefile
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/crash_dump.c
arch/mips/kernel/genex.S
arch/mips/kernel/idle.c [new file with mode: 0644]
arch/mips/kernel/kprobes.c
arch/mips/kernel/proc.c
arch/mips/kernel/process.c
arch/mips/kernel/scall64-64.S
arch/mips/kernel/smp.c
arch/mips/kernel/smtc.c
arch/mips/kernel/traps.c
arch/mips/kvm/kvm_mips_emul.c
arch/mips/kvm/kvm_tlb.c
arch/mips/lantiq/xway/gptu.c
arch/mips/lib/dump_tlb.c
arch/mips/lib/r3k_dump_tlb.c
arch/mips/loongson/common/reset.c
arch/mips/loongson1/common/reset.c
arch/mips/mm/tlb-r3k.c
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlb-r8k.c
arch/mips/mm/tlbex.c
arch/mips/netlogic/xlp/setup.c
arch/mips/netlogic/xlr/setup.c
arch/mips/pmcs-msp71xx/msp_prom.c
arch/mips/pmcs-msp71xx/msp_setup.c
arch/mips/ralink/dts/rt3050.dtsi
arch/mips/ralink/dts/rt3052_eval.dts
arch/mips/txx9/generic/setup.c
arch/mips/vr41xx/common/pmu.c
arch/mips/wrppmc/reset.c
arch/parisc/Kconfig
arch/parisc/Makefile
arch/parisc/include/asm/hardirq.h
arch/parisc/include/asm/processor.h
arch/parisc/kernel/entry.S
arch/parisc/kernel/irq.c
arch/parisc/mm/init.c
arch/powerpc/Kconfig.debug
arch/powerpc/configs/ps3_defconfig
arch/powerpc/include/asm/context_tracking.h [new file with mode: 0644]
arch/powerpc/include/asm/firmware.h
arch/powerpc/include/asm/hw_irq.h
arch/powerpc/include/asm/opal.h
arch/powerpc/include/asm/pgalloc-64.h
arch/powerpc/include/asm/pte-hash64-64k.h
arch/powerpc/include/asm/rtas.h
arch/powerpc/include/asm/thread_info.h
arch/powerpc/include/asm/udbg.h
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/kernel/machine_kexec_64.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kernel/signal.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/udbg.c
arch/powerpc/mm/fault.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/init_64.c
arch/powerpc/perf/core-book3s.c
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/powernv/pci.h
arch/powerpc/platforms/powernv/powernv.h
arch/powerpc/platforms/powernv/setup.c
arch/powerpc/platforms/powernv/smp.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/suspend.c
arch/powerpc/platforms/wsp/ics.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/ehv_pic.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/udbg_memcons.c [new file with mode: 0644]
arch/powerpc/sysdev/xics/ics-opal.c
arch/s390/Kconfig
arch/s390/include/asm/ftrace.h
arch/s390/include/asm/page.h
arch/s390/include/asm/pgtable.h
arch/s390/kernel/dis.c
arch/s390/kernel/ftrace.c
arch/s390/kernel/mcount.S
arch/s390/kernel/mcount64.S
arch/s390/kernel/smp.c
arch/s390/mm/pgtable.c
arch/x86/Kconfig
arch/x86/kernel/head64.c
arch/x86/kernel/microcode_intel_early.c
arch/x86/kernel/process.c
arch/x86/mm/init.c
drivers/acpi/ac.c
drivers/acpi/ec.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_idle.c
drivers/acpi/scan.c
drivers/acpi/video.c
drivers/ata/pata_ep93xx.c
drivers/base/bus.c
drivers/base/core.c
drivers/base/power/common.c
drivers/block/rbd.c
drivers/char/hw_random/mxc-rnga.c
drivers/char/hw_random/omap-rng.c
drivers/char/ipmi/ipmi_bt_sm.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/lp.c
drivers/char/ttyprintk.c
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/arm_big_little.c
drivers/cpufreq/arm_big_little.h
drivers/cpufreq/arm_big_little_dt.c
drivers/cpufreq/cpufreq-cpu0.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/kirkwood-cpufreq.c
drivers/cpufreq/loongson2_cpufreq.c
drivers/dma/tegra20-apb-dma.c
drivers/gpio/gpio-mvebu.c
drivers/gpio/gpio-tegra.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_encoder_slave.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
drivers/gpu/drm/nouveau/core/subdev/bios/init.c
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/qxl/qxl_cmd.c
drivers/gpu/drm/qxl/qxl_display.c
drivers/gpu/drm/qxl/qxl_drv.h
drivers/gpu/drm/qxl/qxl_ioctl.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_hdmi.c
drivers/gpu/drm/radeon/r300_cmdbuf.c
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_family.h
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/radeon/sid.h
drivers/gpu/host1x/drm/dc.c
drivers/hv/channel_mgmt.c
drivers/hwmon/abituguru.c
drivers/hwmon/iio_hwmon.c
drivers/hwmon/nct6775.c
drivers/hwmon/tmp401.c
drivers/i2c/busses/i2c-designware-core.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-sirf.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/i2c-core.c
drivers/leds/leds-gpio.c
drivers/lguest/page_tables.c
drivers/md/dm-thin.c
drivers/memory/emif.c
drivers/mfd/Kconfig
drivers/mfd/ab8500-core.c
drivers/mfd/ab8500-debugfs.c
drivers/mfd/ab8500-gpadc.c
drivers/mfd/ab8500-sysctrl.c
drivers/mfd/abx500-core.c
drivers/mfd/cros_ec_spi.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/intel_msic.c
drivers/mfd/si476x-cmd.c
drivers/misc/atmel-ssc.c
drivers/misc/dummy-irq.c
drivers/misc/mei/bus.c
drivers/misc/mei/main.c
drivers/misc/vmw_vmci/Kconfig
drivers/misc/vmw_vmci/vmci_queue_pair.c
drivers/mmc/host/mmci.c
drivers/mtd/nand/lpc32xx_mlc.c
drivers/net/caif/Kconfig
drivers/net/ethernet/3com/3c59x.c
drivers/net/ethernet/brocade/bna/bnad.c
drivers/net/ethernet/cadence/Kconfig
drivers/net/ethernet/calxeda/Kconfig
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/mellanox/mlx4/en_resources.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/stmicro/stmmac/Kconfig
drivers/net/macvlan.c
drivers/net/ntb_netdev.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/ntb/ntb_hw.c
drivers/ntb/ntb_transport.c
drivers/of/base.c
drivers/pinctrl/pinctrl-abx500.c
drivers/pinctrl/pinctrl-coh901.c
drivers/pinctrl/pinctrl-exynos5440.c
drivers/pinctrl/pinctrl-lantiq.c
drivers/pinctrl/pinctrl-samsung.c
drivers/pinctrl/pinctrl-single.c
drivers/pinctrl/pinctrl-xway.c
drivers/pinctrl/vt8500/pinctrl-wm8750.c
drivers/pwm/pwm-imx.c
drivers/pwm/pwm-puv3.c
drivers/pwm/pwm-pxa.c
drivers/pwm/pwm-tegra.c
drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/pwm-tipwmss.c
drivers/pwm/pwm-vt8500.c
drivers/rtc/Kconfig
drivers/rtc/rtc-nuc900.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-tegra.c
drivers/s390/block/xpram.c
drivers/s390/cio/chp.c
drivers/s390/cio/chsc.h
drivers/spi/spi-atmel.c
drivers/spi/spi-davinci.c
drivers/spi/spi-tegra20-sflash.c
drivers/spi/spi.c
drivers/staging/dwc2/Kconfig
drivers/staging/dwc2/platform.c
drivers/staging/gdm72xx/Kconfig
drivers/staging/nvec/nvec.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_erl1.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/target/iscsi/iscsi_target_parameters.h
drivers/target/target_core_configfs.c
drivers/target/target_core_device.c
drivers/target/target_core_file.c
drivers/target/target_core_iblock.c
drivers/target/target_core_internal.h
drivers/target/target_core_rd.c
drivers/target/target_core_rd.h
drivers/target/target_core_transport.c
drivers/thermal/armada_thermal.c
drivers/thermal/dove_thermal.c
drivers/thermal/exynos_thermal.c
drivers/uio/Kconfig
drivers/usb/atm/cxacru.c
drivers/usb/chipidea/Kconfig
drivers/usb/chipidea/ci13xxx_imx.c
drivers/usb/chipidea/core.c
drivers/usb/core/Kconfig
drivers/usb/core/quirks.c
drivers/usb/dwc3/Kconfig
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/bcm63xx_udc.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/f_ecm.c
drivers/usb/gadget/f_subset.c
drivers/usb/gadget/f_uac2.c
drivers/usb/gadget/fusb300_udc.c
drivers/usb/gadget/imx_udc.c
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/gadget/zero.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-atmel.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-orion.c
drivers/usb/host/ehci-s5p.c
drivers/usb/host/ehci-spear.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-exynos.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-nxp.c
drivers/usb/host/ohci-omap3.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-spear.c
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/uhci-hub.c
drivers/usb/host/uhci-platform.c
drivers/usb/host/uhci-q.c
drivers/usb/host/xhci-mem.c
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/omap2430.c
drivers/usb/phy/Kconfig
drivers/usb/phy/phy-ab8500-usb.c
drivers/usb/phy/phy-fsl-usb.c
drivers/usb/phy/phy-gpio-vbus-usb.c
drivers/usb/phy/phy-isp1301.c
drivers/usb/phy/phy-mv-u3d-usb.c
drivers/usb/phy/phy-mv-usb.c
drivers/usb/phy/phy-mxs-usb.c
drivers/usb/phy/phy-nop.c
drivers/usb/phy/phy-samsung-usb2.c
drivers/usb/phy/phy-samsung-usb3.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/generic.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/option.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/realtek_cr.c
drivers/vhost/vringh.c
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/vrfb.c
drivers/w1/masters/omap_hdq.c
drivers/watchdog/ath79_wdt.c
drivers/watchdog/davinci_wdt.c
drivers/watchdog/imx2_wdt.c
drivers/xen/Kconfig
drivers/xen/balloon.c
drivers/xen/privcmd.c
drivers/xen/tmem.c
drivers/xen/xen-selfballoon.c
drivers/xen/xenbus/xenbus_dev_backend.c
fs/btrfs/backref.c
fs/btrfs/check-integrity.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-ref.h
fs/btrfs/dev-replace.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/free-space-cache.c
fs/btrfs/free-space-cache.h
fs/btrfs/inode-map.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/raid56.c
fs/btrfs/relocation.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/extents_status.c
fs/ext4/extents_status.h
fs/ext4/file.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/page-io.c
include/acpi/acpiosxf.h
include/acpi/processor.h
include/drm/drmP.h
include/drm/drm_fb_helper.h
include/drm/drm_os_linux.h
include/drm/drm_pciids.h
include/linux/journal-head.h
include/linux/kref.h
include/linux/mfd/abx500/ab8500.h
include/linux/mlx4/qp.h
include/linux/of_platform.h
include/linux/pinctrl/pinconf-generic.h
include/linux/printk.h
include/linux/socket.h
include/linux/spi/spi.h
include/linux/time.h
include/linux/uio.h
include/linux/usb/gadget.h
include/linux/usb/serial.h
include/net/sock.h
include/target/target_core_base.h
include/trace/events/ext4.h
include/uapi/linux/virtio_console.h
kernel/cpu/idle.c
kernel/events/core.c
kernel/kmod.c
kernel/module.c
kernel/rcutree_plugin.h
kernel/time/Kconfig
kernel/time/tick-broadcast.c
kernel/time/tick-sched.c
kernel/timer.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_kprobe.c
kernel/workqueue.c
lib/Makefile
lib/iovec.c [new file with mode: 0644]
lib/klist.c
mm/page_alloc.c
net/batman-adv/distributed-arp-table.c
net/batman-adv/main.c
net/batman-adv/network-coding.c
net/ceph/osd_client.c
net/core/iovec.c
net/core/sock.c
net/ipv4/ip_output.c
net/ipv6/ip6_gre.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/udp_impl.h
net/ipv6/udplite.c
net/ipv6/xfrm6_policy.c
scripts/package/Makefile
sound/aoa/fabrics/layout.c
sound/aoa/soundbus/i2sbus/core.c
sound/oss/Kconfig
sound/pci/hda/hda_generic.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/ab8500-codec.h
sound/soc/codecs/da7213.c
sound/soc/codecs/wm0010.c
sound/soc/fsl/imx-ssi.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/usb/proc.c

diff --git a/Documentation/devicetree/bindings/drm/exynos/hdmi.txt b/Documentation/devicetree/bindings/drm/exynos/hdmi.txt
deleted file mode 100644 (file)
index 589edee..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-Device-Tree bindings for drm hdmi driver
-
-Required properties:
-- compatible: value should be "samsung,exynos5-hdmi".
-- reg: physical base address of the hdmi and length of memory mapped
-       region.
-- interrupts: interrupt number to the cpu.
-- hpd-gpio: following information about the hotplug gpio pin.
-       a) phandle of the gpio controller node.
-       b) pin number within the gpio controller.
-       c) pin function mode.
-       d) optional flags and pull up/down.
-       e) drive strength.
-
-Example:
-
-       hdmi {
-               compatible = "samsung,exynos5-hdmi";
-               reg = <0x14530000 0x100000>;
-               interrupts = <0 95 0>;
-               hpd-gpio = <&gpx3 7 0xf 1 3>;
-       };
diff --git a/Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt b/Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt
deleted file mode 100644 (file)
index fa166d9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Device-Tree bindings for hdmiddc driver
-
-Required properties:
-- compatible: value should be "samsung,exynos5-hdmiddc".
-- reg: I2C address of the hdmiddc device.
-
-Example:
-
-       hdmiddc {
-               compatible = "samsung,exynos5-hdmiddc";
-               reg = <0x50>;
-       };
diff --git a/Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt b/Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt
deleted file mode 100644 (file)
index 858f4f9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Device-Tree bindings for hdmiphy driver
-
-Required properties:
-- compatible: value should be "samsung,exynos5-hdmiphy".
-- reg: I2C address of the hdmiphy device.
-
-Example:
-
-       hdmiphy {
-               compatible = "samsung,exynos5-hdmiphy";
-               reg = <0x38>;
-       };
diff --git a/Documentation/devicetree/bindings/drm/exynos/mixer.txt b/Documentation/devicetree/bindings/drm/exynos/mixer.txt
deleted file mode 100644 (file)
index 9b2ea03..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Device-Tree bindings for mixer driver
-
-Required properties:
-- compatible: value should be "samsung,exynos5-mixer".
-- reg: physical base address of the mixer and length of memory mapped
-       region.
-- interrupts: interrupt number to the cpu.
-
-Example:
-
-       mixer {
-               compatible = "samsung,exynos5-mixer";
-               reg = <0x14450000 0x10000>;
-               interrupts = <0 94 0>;
-       };
diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
new file mode 100644 (file)
index 0000000..589edee
--- /dev/null
@@ -0,0 +1,22 @@
+Device-Tree bindings for drm hdmi driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-hdmi".
+- reg: physical base address of the hdmi and length of memory mapped
+       region.
+- interrupts: interrupt number to the cpu.
+- hpd-gpio: following information about the hotplug gpio pin.
+       a) phandle of the gpio controller node.
+       b) pin number within the gpio controller.
+       c) pin function mode.
+       d) optional flags and pull up/down.
+       e) drive strength.
+
+Example:
+
+       hdmi {
+               compatible = "samsung,exynos5-hdmi";
+               reg = <0x14530000 0x100000>;
+               interrupts = <0 95 0>;
+               hpd-gpio = <&gpx3 7 0xf 1 3>;
+       };
diff --git a/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt b/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt
new file mode 100644 (file)
index 0000000..fa166d9
--- /dev/null
@@ -0,0 +1,12 @@
+Device-Tree bindings for hdmiddc driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-hdmiddc".
+- reg: I2C address of the hdmiddc device.
+
+Example:
+
+       hdmiddc {
+               compatible = "samsung,exynos5-hdmiddc";
+               reg = <0x50>;
+       };
diff --git a/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt b/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
new file mode 100644 (file)
index 0000000..858f4f9
--- /dev/null
@@ -0,0 +1,12 @@
+Device-Tree bindings for hdmiphy driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-hdmiphy".
+- reg: I2C address of the hdmiphy device.
+
+Example:
+
+       hdmiphy {
+               compatible = "samsung,exynos5-hdmiphy";
+               reg = <0x38>;
+       };
diff --git a/Documentation/devicetree/bindings/video/exynos_mixer.txt b/Documentation/devicetree/bindings/video/exynos_mixer.txt
new file mode 100644 (file)
index 0000000..9b2ea03
--- /dev/null
@@ -0,0 +1,15 @@
+Device-Tree bindings for mixer driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-mixer".
+- reg: physical base address of the mixer and length of memory mapped
+       region.
+- interrupts: interrupt number to the cpu.
+
+Example:
+
+       mixer {
+               compatible = "samsung,exynos5-mixer";
+               reg = <0x14450000 0x10000>;
+               interrupts = <0 94 0>;
+       };
index ef9d06c9f8fde9341c3dc1926f83524fb7a47396..0efedaad5165d74a1ef8273fe1ff9491c096d97a 100644 (file)
@@ -191,9 +191,11 @@ Linux it will look something like this:
        };
 
 The bootargs property contains the kernel arguments, and the initrd-*
-properties define the address and size of an initrd blob.  The
-chosen node may also optionally contain an arbitrary number of
-additional properties for platform-specific configuration data.
+properties define the address and size of an initrd blob.  Note that
+initrd-end is the first address after the initrd image, so this doesn't
+match the usual semantic of struct resource.  The chosen node may also
+optionally contain an arbitrary number of additional properties for
+platform-specific configuration data.
 
 During early boot, the architecture setup code calls of_scan_flat_dt()
 several times with different helper callbacks to parse device tree
index c3bfacb92910dc8d044bec88122c4a85328ed8d5..6e3b18a8afc6a8749d3d91fd559e2bd5c62cadfc 100644 (file)
@@ -3005,6 +3005,27 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        Force threading of all interrupt handlers except those
                        marked explicitly IRQF_NO_THREAD.
 
+       tmem            [KNL,XEN]
+                       Enable the Transcendent memory driver if built-in.
+
+       tmem.cleancache=0|1 [KNL, XEN]
+                       Default is on (1). Disable the usage of the cleancache
+                       API to send anonymous pages to the hypervisor.
+
+       tmem.frontswap=0|1 [KNL, XEN]
+                       Default is on (1). Disable the usage of the frontswap
+                       API to send swap pages to the hypervisor. If disabled
+                       the selfballooning and selfshrinking are force disabled.
+
+       tmem.selfballooning=0|1 [KNL, XEN]
+                       Default is on (1). Disable the driving of swap pages
+                       to the hypervisor.
+
+       tmem.selfshrinking=0|1 [KNL, XEN]
+                       Default is on (1). Partial swapoff that immediately
+                       transfers pages from Xen hypervisor back to the
+                       kernel based on different criteria.
+
        topology=       [S390]
                        Format: {off | on}
                        Specify if the kernel should make use of the cpu
diff --git a/Documentation/kernel-per-CPU-kthreads.txt b/Documentation/kernel-per-CPU-kthreads.txt
new file mode 100644 (file)
index 0000000..cbf7ae4
--- /dev/null
@@ -0,0 +1,202 @@
+REDUCING OS JITTER DUE TO PER-CPU KTHREADS
+
+This document lists per-CPU kthreads in the Linux kernel and presents
+options to control their OS jitter.  Note that non-per-CPU kthreads are
+not listed here.  To reduce OS jitter from non-per-CPU kthreads, bind
+them to a "housekeeping" CPU dedicated to such work.
+
+
+REFERENCES
+
+o      Documentation/IRQ-affinity.txt:  Binding interrupts to sets of CPUs.
+
+o      Documentation/cgroups:  Using cgroups to bind tasks to sets of CPUs.
+
+o      man taskset:  Using the taskset command to bind tasks to sets
+       of CPUs.
+
+o      man sched_setaffinity:  Using the sched_setaffinity() system
+       call to bind tasks to sets of CPUs.
+
+o      /sys/devices/system/cpu/cpuN/online:  Control CPU N's hotplug state,
+       writing "0" to offline and "1" to online.
+
+o      In order to locate kernel-generated OS jitter on CPU N:
+
+               cd /sys/kernel/debug/tracing
+               echo 1 > max_graph_depth # Increase the "1" for more detail
+               echo function_graph > current_tracer
+               # run workload
+               cat per_cpu/cpuN/trace
+
+
+KTHREADS
+
+Name: ehca_comp/%u
+Purpose: Periodically process Infiniband-related work.
+To reduce its OS jitter, do any of the following:
+1.     Don't use eHCA Infiniband hardware, instead choosing hardware
+       that does not require per-CPU kthreads.  This will prevent these
+       kthreads from being created in the first place.  (This will
+       work for most people, as this hardware, though important, is
+       relatively old and is produced in relatively low unit volumes.)
+2.     Do all eHCA-Infiniband-related work on other CPUs, including
+       interrupts.
+3.     Rework the eHCA driver so that its per-CPU kthreads are
+       provisioned only on selected CPUs.
+
+
+Name: irq/%d-%s
+Purpose: Handle threaded interrupts.
+To reduce its OS jitter, do the following:
+1.     Use irq affinity to force the irq threads to execute on
+       some other CPU.
+
+Name: kcmtpd_ctr_%d
+Purpose: Handle Bluetooth work.
+To reduce its OS jitter, do one of the following:
+1.     Don't use Bluetooth, in which case these kthreads won't be
+       created in the first place.
+2.     Use irq affinity to force Bluetooth-related interrupts to
+       occur on some other CPU and furthermore initiate all
+       Bluetooth activity on some other CPU.
+
+Name: ksoftirqd/%u
+Purpose: Execute softirq handlers when threaded or when under heavy load.
+To reduce its OS jitter, each softirq vector must be handled
+separately as follows:
+TIMER_SOFTIRQ:  Do all of the following:
+1.     To the extent possible, keep the CPU out of the kernel when it
+       is non-idle, for example, by avoiding system calls and by forcing
+       both kernel threads and interrupts to execute elsewhere.
+2.     Build with CONFIG_HOTPLUG_CPU=y.  After boot completes, force
+       the CPU offline, then bring it back online.  This forces
+       recurring timers to migrate elsewhere.  If you are concerned
+       with multiple CPUs, force them all offline before bringing the
+       first one back online.  Once you have onlined the CPUs in question,
+       do not offline any other CPUs, because doing so could force the
+       timer back onto one of the CPUs in question.
+NET_TX_SOFTIRQ and NET_RX_SOFTIRQ:  Do all of the following:
+1.     Force networking interrupts onto other CPUs.
+2.     Initiate any network I/O on other CPUs.
+3.     Once your application has started, prevent CPU-hotplug operations
+       from being initiated from tasks that might run on the CPU to
+       be de-jittered.  (It is OK to force this CPU offline and then
+       bring it back online before you start your application.)
+BLOCK_SOFTIRQ:  Do all of the following:
+1.     Force block-device interrupts onto some other CPU.
+2.     Initiate any block I/O on other CPUs.
+3.     Once your application has started, prevent CPU-hotplug operations
+       from being initiated from tasks that might run on the CPU to
+       be de-jittered.  (It is OK to force this CPU offline and then
+       bring it back online before you start your application.)
+BLOCK_IOPOLL_SOFTIRQ:  Do all of the following:
+1.     Force block-device interrupts onto some other CPU.
+2.     Initiate any block I/O and block-I/O polling on other CPUs.
+3.     Once your application has started, prevent CPU-hotplug operations
+       from being initiated from tasks that might run on the CPU to
+       be de-jittered.  (It is OK to force this CPU offline and then
+       bring it back online before you start your application.)
+TASKLET_SOFTIRQ: Do one or more of the following:
+1.     Avoid use of drivers that use tasklets.  (Such drivers will contain
+       calls to things like tasklet_schedule().)
+2.     Convert all drivers that you must use from tasklets to workqueues.
+3.     Force interrupts for drivers using tasklets onto other CPUs,
+       and also do I/O involving these drivers on other CPUs.
+SCHED_SOFTIRQ: Do all of the following:
+1.     Avoid sending scheduler IPIs to the CPU to be de-jittered,
+       for example, ensure that at most one runnable kthread is present
+       on that CPU.  If a thread that expects to run on the de-jittered
+       CPU awakens, the scheduler will send an IPI that can result in
+       a subsequent SCHED_SOFTIRQ.
+2.     Build with CONFIG_RCU_NOCB_CPU=y, CONFIG_RCU_NOCB_CPU_ALL=y,
+       CONFIG_NO_HZ_FULL=y, and, in addition, ensure that the CPU
+       to be de-jittered is marked as an adaptive-ticks CPU using the
+       "nohz_full=" boot parameter.  This reduces the number of
+       scheduler-clock interrupts that the de-jittered CPU receives,
+       minimizing its chances of being selected to do the load balancing
+       work that runs in SCHED_SOFTIRQ context.
+3.     To the extent possible, keep the CPU out of the kernel when it
+       is non-idle, for example, by avoiding system calls and by
+       forcing both kernel threads and interrupts to execute elsewhere.
+       This further reduces the number of scheduler-clock interrupts
+       received by the de-jittered CPU.
+HRTIMER_SOFTIRQ:  Do all of the following:
+1.     To the extent possible, keep the CPU out of the kernel when it
+       is non-idle.  For example, avoid system calls and force both
+       kernel threads and interrupts to execute elsewhere.
+2.     Build with CONFIG_HOTPLUG_CPU=y.  Once boot completes, force the
+       CPU offline, then bring it back online.  This forces recurring
+       timers to migrate elsewhere.  If you are concerned with multiple
+       CPUs, force them all offline before bringing the first one
+       back online.  Once you have onlined the CPUs in question, do not
+       offline any other CPUs, because doing so could force the timer
+       back onto one of the CPUs in question.
+RCU_SOFTIRQ:  Do at least one of the following:
+1.     Offload callbacks and keep the CPU in either dyntick-idle or
+       adaptive-ticks state by doing all of the following:
+       a.      Build with CONFIG_RCU_NOCB_CPU=y, CONFIG_RCU_NOCB_CPU_ALL=y,
+               CONFIG_NO_HZ_FULL=y, and, in addition ensure that the CPU
+               to be de-jittered is marked as an adaptive-ticks CPU using
+               the "nohz_full=" boot parameter.  Bind the rcuo kthreads
+               to housekeeping CPUs, which can tolerate OS jitter.
+       b.      To the extent possible, keep the CPU out of the kernel
+               when it is non-idle, for example, by avoiding system
+               calls and by forcing both kernel threads and interrupts
+               to execute elsewhere.
+2.     Enable RCU to do its processing remotely via dyntick-idle by
+       doing all of the following:
+       a.      Build with CONFIG_NO_HZ=y and CONFIG_RCU_FAST_NO_HZ=y.
+       b.      Ensure that the CPU goes idle frequently, allowing other
+               CPUs to detect that it has passed through an RCU quiescent
+               state.  If the kernel is built with CONFIG_NO_HZ_FULL=y,
+               userspace execution also allows other CPUs to detect that
+               the CPU in question has passed through a quiescent state.
+       c.      To the extent possible, keep the CPU out of the kernel
+               when it is non-idle, for example, by avoiding system
+               calls and by forcing both kernel threads and interrupts
+               to execute elsewhere.
+
+Name: rcuc/%u
+Purpose: Execute RCU callbacks in CONFIG_RCU_BOOST=y kernels.
+To reduce its OS jitter, do at least one of the following:
+1.     Build the kernel with CONFIG_PREEMPT=n.  This prevents these
+       kthreads from being created in the first place, and also obviates
+       the need for RCU priority boosting.  This approach is feasible
+       for workloads that do not require high degrees of responsiveness.
+2.     Build the kernel with CONFIG_RCU_BOOST=n.  This prevents these
+       kthreads from being created in the first place.  This approach
+       is feasible only if your workload never requires RCU priority
+       boosting, for example, if you ensure frequent idle time on all
+       CPUs that might execute within the kernel.
+3.     Build with CONFIG_RCU_NOCB_CPU=y and CONFIG_RCU_NOCB_CPU_ALL=y,
+       which offloads all RCU callbacks to kthreads that can be moved
+       off of CPUs susceptible to OS jitter.  This approach prevents the
+       rcuc/%u kthreads from having any work to do, so that they are
+       never awakened.
+4.     Ensure that the CPU never enters the kernel, and, in particular,
+       avoid initiating any CPU hotplug operations on this CPU.  This is
+       another way of preventing any callbacks from being queued on the
+       CPU, again preventing the rcuc/%u kthreads from having any work
+       to do.
+
+Name: rcuob/%d, rcuop/%d, and rcuos/%d
+Purpose: Offload RCU callbacks from the corresponding CPU.
+To reduce its OS jitter, do at least one of the following:
+1.     Use affinity, cgroups, or other mechanism to force these kthreads
+       to execute on some other CPU.
+2.     Build with CONFIG_RCU_NOCB_CPUS=n, which will prevent these
+       kthreads from being created in the first place.  However, please
+       note that this will not eliminate OS jitter, but will instead
+       shift it to RCU_SOFTIRQ.
+
+Name: watchdog/%u
+Purpose: Detect software lockups on each CPU.
+To reduce its OS jitter, do at least one of the following:
+1.     Build with CONFIG_LOCKUP_DETECTOR=n, which will prevent these
+       kthreads from being created in the first place.
+2.     Echo a zero to /proc/sys/kernel/watchdog to disable the
+       watchdog timer.
+3.     Echo a large number of /proc/sys/kernel/watchdog_thresh in
+       order to reduce the frequency of OS jitter due to the watchdog
+       timer down to a level that is acceptable for your workload.
index 504dfe4d52eba3541cfa6330d52595d37265a0b7..a66c9821b5cefa5056f2fb202a9acb00a207f8af 100644 (file)
@@ -268,7 +268,7 @@ situations.
 System Power Management Phases
 ------------------------------
 Suspending or resuming the system is done in several phases.  Different phases
-are used for standby or memory sleep states ("suspend-to-RAM") and the
+are used for freeze, standby, and memory sleep states ("suspend-to-RAM") and the
 hibernation state ("suspend-to-disk").  Each phase involves executing callbacks
 for every device before the next phase begins.  Not all busses or classes
 support all these callbacks and not all drivers use all the callbacks.  The
@@ -309,7 +309,8 @@ execute the corresponding method from dev->driver->pm instead if there is one.
 
 Entering System Suspend
 -----------------------
-When the system goes into the standby or memory sleep state, the phases are:
+When the system goes into the freeze, standby or memory sleep state,
+the phases are:
 
                prepare, suspend, suspend_late, suspend_noirq.
 
@@ -368,7 +369,7 @@ the devices that were suspended.
 
 Leaving System Suspend
 ----------------------
-When resuming from standby or memory sleep, the phases are:
+When resuming from freeze, standby or memory sleep, the phases are:
 
                resume_noirq, resume_early, resume, complete.
 
@@ -433,8 +434,8 @@ the system log.
 
 Entering Hibernation
 --------------------
-Hibernating the system is more complicated than putting it into the standby or
-memory sleep state, because it involves creating and saving a system image.
+Hibernating the system is more complicated than putting it into the other
+sleep states, because it involves creating and saving a system image.
 Therefore there are more phases for hibernation, with a different set of
 callbacks.  These phases always run after tasks have been frozen and memory has
 been freed.
@@ -485,8 +486,8 @@ image forms an atomic snapshot of the system state.
 
 At this point the system image is saved, and the devices then need to be
 prepared for the upcoming system shutdown.  This is much like suspending them
-before putting the system into the standby or memory sleep state, and the phases
-are similar.
+before putting the system into the freeze, standby or memory sleep state,
+and the phases are similar.
 
     9. The prepare phase is discussed above.
 
index c537834af00566e0fee8058a9643803d2c2b3954..f1f0f59a7c47d594a9753207d713d0834a0e99b1 100644 (file)
@@ -7,8 +7,8 @@ running. The interface exists in /sys/power/ directory (assuming sysfs
 is mounted at /sys). 
 
 /sys/power/state controls system power state. Reading from this file
-returns what states are supported, which is hard-coded to 'standby'
-(Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'
+returns what states are supported, which is hard-coded to 'freeze',
+'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'
 (Suspend-to-Disk). 
 
 Writing to this file one of those strings causes the system to
index c2a4a346c0d98597d3375c5a9f160c012fded709..a81fa254303de0c57ef6e7741dd76ffb0bcfdf02 100644 (file)
@@ -15,8 +15,10 @@ A suspend/hibernation notifier may be used for this purpose.
 The subsystems or drivers having such needs can register suspend notifiers that
 will be called upon the following events by the PM core:
 
-PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will
-                       be frozen immediately.
+PM_HIBERNATION_PREPARE The system is going to hibernate, tasks will be frozen
+                       immediately. This is different from PM_SUSPEND_PREPARE
+                       below because here we do additional work between notifiers
+                       and drivers freezing.
 
 PM_POST_HIBERNATION    The system memory state has been restored from a
                        hibernation image or an error occurred during
index 4416b28630df8d62cbba43e2fedb0cee42d6b3b1..442d43df9b251111df2d677b5e8cc3ef4488c831 100644 (file)
@@ -2,12 +2,26 @@
 System Power Management States
 
 
-The kernel supports three power management states generically, though
-each is dependent on platform support code to implement the low-level
-details for each state. This file describes each state, what they are
+The kernel supports four power management states generically, though
+one is generic and the other three are dependent on platform support
+code to implement the low-level details for each state.
+This file describes each state, what they are
 commonly called, what ACPI state they map to, and what string to write
 to /sys/power/state to enter that state
 
+state:         Freeze / Low-Power Idle
+ACPI state:    S0
+String:                "freeze"
+
+This state is a generic, pure software, light-weight, low-power state.
+It allows more energy to be saved relative to idle by freezing user
+space and putting all I/O devices into low-power states (possibly
+lower-power than available at run time), such that the processors can
+spend more time in their idle states.
+This state can be used for platforms without Standby/Suspend-to-RAM
+support, or it can be used in addition to Suspend-to-RAM (memory sleep)
+to provide reduced resume latency.
+
 
 State:         Standby / Power-On Suspend
 ACPI State:    S1
@@ -22,9 +36,6 @@ We try to put devices in a low-power state equivalent to D1, which
 also offers low power savings, but low resume latency. Not all devices
 support D1, and those that don't are left on. 
 
-A transition from Standby to the On state should take about 1-2
-seconds. 
-
 
 State:         Suspend-to-RAM
 ACPI State:    S3
@@ -42,9 +53,6 @@ transition back to the On state.
 For at least ACPI, STR requires some minimal boot-strapping code to
 resume the system from STR. This may be true on other platforms. 
 
-A transition from Suspend-to-RAM to the On state should take about
-3-5 seconds. 
-
 
 State:         Suspend-to-disk
 ACPI State:    S4
@@ -74,7 +82,3 @@ low-power state (like ACPI S4), or it may simply power down. Powering
 down offers greater savings, and allows this mechanism to work on any
 system. However, entering a real low-power state allows the user to
 trigger wake up events (e.g. pressing a key or opening a laptop lid).
-
-A transition from Suspend-to-Disk to the On state should take about 30
-seconds, though it's typically a bit more with the current
-implementation. 
index 3d7782b9f90d80d171c97e1d15371a9e2ec51ddc..94b5a60b19c5335904f150970d1d566d798a0f93 100644 (file)
@@ -3865,9 +3865,16 @@ M:       K. Y. Srinivasan <kys@microsoft.com>
 M:     Haiyang Zhang <haiyangz@microsoft.com>
 L:     devel@linuxdriverproject.org
 S:     Maintained
-F:     drivers/hv/
+F:     arch/x86/include/asm/mshyperv.h
+F:     arch/x86/include/uapi/asm/hyperv.h
+F:     arch/x86/kernel/cpu/mshyperv.c
 F:     drivers/hid/hid-hyperv.c
+F:     drivers/hv/
 F:     drivers/net/hyperv/
+F:     drivers/scsi/storvsc_drv.c
+F:     drivers/video/hyperv_fb.c
+F:     include/linux/hyperv.h
+F:     tools/hv/
 
 I2C OVER PARALLEL PORT
 M:     Jean Delvare <khali@linux-fr.org>
@@ -4641,12 +4648,13 @@ F:      include/linux/sunrpc/
 F:     include/uapi/linux/sunrpc/
 
 KERNEL VIRTUAL MACHINE (KVM)
-M:     Marcelo Tosatti <mtosatti@redhat.com>
 M:     Gleb Natapov <gleb@redhat.com>
+M:     Paolo Bonzini <pbonzini@redhat.com>
 L:     kvm@vger.kernel.org
-W:     http://kvm.qumranet.com
+W:     http://linux-kvm.org
 S:     Supported
-F:     Documentation/*/kvm.txt
+F:     Documentation/*/kvm*.txt
+F:     Documentation/virtual/kvm/
 F:     arch/*/kvm/
 F:     arch/*/include/asm/kvm*
 F:     include/linux/kvm*
@@ -4976,6 +4984,13 @@ S:       Maintained
 F:     Documentation/hwmon/lm90
 F:     drivers/hwmon/lm90.c
 
+LM95234 HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/lm95234
+F:     drivers/hwmon/lm95234.c
+
 LME2510 MEDIA DRIVER
 M:     Malcolm Priestley <tvboxspy@gmail.com>
 L:     linux-media@vger.kernel.org
@@ -7854,7 +7869,7 @@ L:        linux-scsi@vger.kernel.org
 L:     target-devel@vger.kernel.org
 L:     http://groups.google.com/group/linux-iscsi-target-dev
 W:     http://www.linux-iscsi.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core.git master
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
 S:     Supported
 F:     drivers/target/
 F:     include/target/
@@ -8182,6 +8197,13 @@ F:       drivers/mmc/host/sh_mobile_sdhi.c
 F:     include/linux/mmc/tmio.h
 F:     include/linux/mmc/sh_mobile_sdhi.h
 
+TMP401 HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/tmp401
+F:     drivers/hwmon/tmp401.c
+
 TMPFS (SHMEM FILESYSTEM)
 M:     Hugh Dickins <hughd@google.com>
 L:     linux-mm@kvack.org
index cd11e88576044e127cb73f49bd41c7d4fb5d3e9f..93875f5122a32510d82555bbef001a18ea58308e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 10
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index dd0e8eb8042f746cc7072c0bf67d1fac8c0d4a7e..a4429bcd609ec8a3761e064d200d0646c3cae5f1 100644 (file)
@@ -213,6 +213,9 @@ config USE_GENERIC_SMP_HELPERS
 config GENERIC_SMP_IDLE_THREAD
        bool
 
+config GENERIC_IDLE_POLL_SETUP
+       bool
+
 # Select if arch init_task initializer is different to init/init_task.c
 config ARCH_INIT_TASK
        bool
index d423d58f938dc40fb5b3c01445b9184572631b10..49d993cee51232874a81814fe39ca99e09b88bad 100644 (file)
@@ -38,6 +38,7 @@ config ARM
        select HAVE_GENERIC_HARDIRQS
        select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
        select HAVE_IDE if PCI || ISA || PCMCIA
+       select HAVE_IRQ_TIME_ACCOUNTING
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_LZO
@@ -488,7 +489,7 @@ config ARCH_IXP4XX
 config ARCH_DOVE
        bool "Marvell Dove"
        select ARCH_REQUIRE_GPIOLIB
-       select CPU_V7
+       select CPU_PJ4
        select GENERIC_CLOCKEVENTS
        select MIGHT_HAVE_PCI
        select PINCTRL
index 47374085befdf6d4ad1cc49c0714e52453ec510f..1ba358ba16b871aec3b366cab9b4e4066048e69c 100644 (file)
@@ -309,7 +309,7 @@ define archhelp
   echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
   echo  '* xipImage      - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'
   echo  '  uImage        - U-Boot wrapped zImage'
-  echo  '  bootpImage    - Combined zImage and initial RAM disk' 
+  echo  '  bootpImage    - Combined zImage and initial RAM disk'
   echo  '                  (supply initrd image via make variable INITRD=<path>)'
   echo  '* dtbs          - Build device tree blobs for enabled boards'
   echo  '  install       - Install uncompressed kernel'
index 52b88d81b7bbaf435d7a9d7d4c85a9e5fe59f07b..3caed0db698614f45652476595ed54b42de54ffc 100644 (file)
@@ -15,8 +15,6 @@
 #include <linux/smp.h>
 #include <linux/spinlock.h>
 
-#include <linux/irqchip/arm-gic.h>
-
 #include <asm/mcpm.h>
 #include <asm/smp.h>
 #include <asm/smp_plat.h>
@@ -49,7 +47,6 @@ static int __cpuinit mcpm_boot_secondary(unsigned int cpu, struct task_struct *i
 static void __cpuinit mcpm_secondary_init(unsigned int cpu)
 {
        mcpm_cpu_powered_up();
-       gic_secondary_init(0);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index 7e0ebb64a7f9dafe5c73b9201c39e344c309ef93..9940f7b4e438c258d125cc6567ac1b7a9b2fc429 100644 (file)
@@ -199,7 +199,6 @@ CONFIG_USB_PHY=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_STORAGE=y
index c1ef64bc5abd65781da53de52d4cfd3e392e29cc..435d69b83e32ccf0d0faaa6bc9a90ca5b5d95046 100644 (file)
@@ -204,7 +204,6 @@ CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=y
 CONFIG_USB_WDM=y
 CONFIG_USB_STORAGE=y
index 7eb18c1d8d6cbce723b9f62c77746dad81aa11ec..4f009c10540dff2a2e7efd08b0671c2369547b90 100644 (file)
@@ -233,15 +233,15 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
        ((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr),       \
                                                atomic64_t,             \
                                                counter),               \
-                                             (unsigned long)(o),       \
-                                             (unsigned long)(n)))
+                                             (unsigned long long)(o),  \
+                                             (unsigned long long)(n)))
 
 #define cmpxchg64_local(ptr, o, n)                                     \
        ((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr),        \
                                                local64_t,              \
                                                a),                     \
-                                            (unsigned long)(o),        \
-                                            (unsigned long)(n)))
+                                            (unsigned long long)(o),   \
+                                            (unsigned long long)(n)))
 
 #endif /* __LINUX_ARM_ARCH__ >= 6 */
 
index 47ab90563bf48b3febdef5fd4085cd2071d551f9..550d63cef68e4be6ada87a3c7942ccd767061c6d 100644 (file)
@@ -251,7 +251,7 @@ void __ref cpu_die(void)
         * this returns, power and/or clocks can be removed at any point
         * from this CPU and its cache by platform_cpu_kill().
         */
-       RCU_NONIDLE(complete(&cpu_died));
+       complete(&cpu_died);
 
        /*
         * Ensure that the cache lines associated with that completion are
index 9e8bdfa2b36915e4db7a8352753626e7f41b682e..31e69a019bdd999bd53338d669a090697122922b 100644 (file)
@@ -307,11 +307,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "missing register base\n");
-               return -ENOMEM;
-       }
-
        emc_regbase = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(emc_regbase))
                return PTR_ERR(emc_regbase);
index ca07cb1b155a702ce5e3c0cc0de74cfc5a5fe3a4..79690f2f6d3f8a5164495c7758b392cc43bae268 100644 (file)
@@ -381,11 +381,6 @@ static int s3c_adc_probe(struct platform_device *pdev)
        }
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!regs) {
-               dev_err(dev, "failed to find registers\n");
-               return -ENXIO;
-       }
-
        adc->regs = devm_ioremap_resource(dev, regs);
        if (IS_ERR(adc->regs))
                return PTR_ERR(adc->regs);
index d30042e39974f949e6ab3cc81f88f7c6dfc51c4d..13609e01f4b786293219f2c9e865837c9262f76e 100644 (file)
@@ -152,11 +152,12 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
 
-static int __init xen_secondary_init(unsigned int cpu)
+static void __init xen_percpu_init(void *unused)
 {
        struct vcpu_register_vcpu_info info;
        struct vcpu_info *vcpup;
        int err;
+       int cpu = get_cpu();
 
        pr_info("Xen: initializing cpu%d\n", cpu);
        vcpup = per_cpu_ptr(xen_vcpu_info, cpu);
@@ -165,14 +166,10 @@ static int __init xen_secondary_init(unsigned int cpu)
        info.offset = offset_in_page(vcpup);
 
        err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
-       if (err) {
-               pr_debug("register_vcpu_info failed: err=%d\n", err);
-       } else {
-               /* This cpu is using the registered vcpu info, even if
-                  later ones fail to. */
-               per_cpu(xen_vcpu, cpu) = vcpup;
-       }
-       return 0;
+       BUG_ON(err);
+       per_cpu(xen_vcpu, cpu) = vcpup;
+
+       enable_percpu_irq(xen_events_irq, 0);
 }
 
 static void xen_restart(char str, const char *cmd)
@@ -208,7 +205,6 @@ static int __init xen_guest_init(void)
        const char *version = NULL;
        const char *xen_prefix = "xen,xen-";
        struct resource res;
-       int i;
 
        node = of_find_compatible_node(NULL, NULL, "xen,xen");
        if (!node) {
@@ -265,19 +261,23 @@ static int __init xen_guest_init(void)
                                               sizeof(struct vcpu_info));
        if (xen_vcpu_info == NULL)
                return -ENOMEM;
-       for_each_online_cpu(i)
-               xen_secondary_init(i);
 
        gnttab_init();
        if (!xen_initial_domain())
                xenbus_probe(NULL);
 
+       return 0;
+}
+core_initcall(xen_guest_init);
+
+static int __init xen_pm_init(void)
+{
        pm_power_off = xen_power_off;
        arm_pm_restart = xen_restart;
 
        return 0;
 }
-core_initcall(xen_guest_init);
+subsys_initcall(xen_pm_init);
 
 static irqreturn_t xen_arm_callback(int irq, void *arg)
 {
@@ -285,11 +285,6 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
-static __init void xen_percpu_enable_events(void *unused)
-{
-       enable_percpu_irq(xen_events_irq, 0);
-}
-
 static int __init xen_init_events(void)
 {
        if (!xen_domain() || xen_events_irq < 0)
@@ -303,7 +298,7 @@ static int __init xen_init_events(void)
                return -EINVAL;
        }
 
-       on_each_cpu(xen_percpu_enable_events, NULL, 0);
+       on_each_cpu(xen_percpu_init, NULL, 0);
 
        return 0;
 }
index 48347dcf056681641936a8cedcfeb88272fc8f7e..56b3f6d447ae10b8d53f9cfb767826fe90a97c11 100644 (file)
@@ -122,8 +122,6 @@ endmenu
 
 menu "Kernel Features"
 
-source "kernel/time/Kconfig"
-
 config ARM64_64K_PAGES
        bool "Enable 64KB pages support"
        help
index c8eedc6049844dbb0d2142fa9aca90478e163025..5aceb83b3f5c3c5dd9dc1168a157bb0e41f1c8e9 100644 (file)
@@ -82,7 +82,7 @@
 
        .macro  enable_dbg_if_not_stepping, tmp
        mrs     \tmp, mdscr_el1
-       tbnz    \tmp, #1, 9990f
+       tbnz    \tmp, #0, 9990f
        enable_dbg
 9990:
        .endm
index 0c3ba9f51376d33656607c67f18e135895357079..f4726dc054b3bbcdd7c7a5d98d3733b6a893ea3e 100644 (file)
@@ -136,8 +136,6 @@ void disable_debug_monitors(enum debug_el el)
  */
 static void clear_os_lock(void *unused)
 {
-       asm volatile("msr mdscr_el1, %0" : : "r" (0));
-       isb();
        asm volatile("msr oslar_el1, %0" : : "r" (0));
        isb();
 }
index ac974f48a7a25145cd8024a7c8cb77a21cdccad2..fbb6e18436598142cf0e4ea7429b63965f2ada4b 100644 (file)
@@ -95,7 +95,7 @@ static void early_write(struct console *con, const char *s, unsigned n)
        }
 }
 
-static struct console early_console = {
+static struct console early_console_dev = {
        .name =         "earlycon",
        .write =        early_write,
        .flags =        CON_PRINTBUFFER | CON_BOOT,
@@ -145,7 +145,8 @@ static int __init setup_early_printk(char *buf)
                early_base = early_io_map(paddr, EARLYCON_IOBASE);
 
        printch = match->printch;
-       register_console(&early_console);
+       early_console = &early_console_dev;
+       register_console(&early_console_dev);
 
        return 0;
 }
index 6a9a5329259065a99ceea12c3fe391f5996c448b..add6ea616843139ff81a65f26c344ed9e69fd66d 100644 (file)
@@ -282,12 +282,13 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
-static int __init arm64_of_clk_init(void)
+static int __init arm64_device_init(void)
 {
        of_clk_init(NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
        return 0;
 }
-arch_initcall(arm64_of_clk_init);
+arch_initcall(arm64_device_init);
 
 static DEFINE_PER_CPU(struct cpu, cpu_data);
 
@@ -305,13 +306,6 @@ static int __init topology_init(void)
 }
 subsys_initcall(topology_init);
 
-static int __init arm64_device_probe(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-       return 0;
-}
-device_initcall(arm64_device_probe);
-
 static const char *hwcap_str[] = {
        "fp",
        "asimd",
index abe69b80cf7f674d9eb25b884a33e78a223aeb65..48a386094fa3cf98a7e8af3ae8d3b9ba5cce6c21 100644 (file)
@@ -52,7 +52,7 @@ loop1:
        add     x2, x2, #4                      // add 4 (line length offset)
        mov     x4, #0x3ff
        and     x4, x4, x1, lsr #3              // find maximum number on the way size
-       clz     x5, x4                          // find bit position of way size increment
+       clz     w5, w4                          // find bit position of way size increment
        mov     x7, #0x7fff
        and     x7, x7, x1, lsr #13             // extract max number of the index size
 loop2:
index f1d8b9bbfdadc5a64a63d781051e6675aa39e322..a82ae8868077f9f32749ccfcc490d166d6fddd1c 100644 (file)
@@ -119,8 +119,7 @@ ENTRY(__cpu_setup)
 
        mov     x0, #3 << 20
        msr     cpacr_el1, x0                   // Enable FP/ASIMD
-       mov     x0, #1
-       msr     oslar_el1, x0                   // Set the debug OS lock
+       msr     mdscr_el1, xzr                  // Reset mdscr_el1
        tlbi    vmalle1is                       // invalidate I + D TLBs
        /*
         * Memory region attributes for LPAE:
index bdc35589277f721805eed5675fe0bfabd8dc0aec..549903cfc2cbe6f223025ff1b04017939f7dd336 100644 (file)
@@ -205,6 +205,11 @@ config ARCH_DISCONTIGMEM_ENABLE
 config ARCH_SPARSEMEM_ENABLE
        def_bool n
 
+config NODES_SHIFT
+       int
+       default "2"
+       depends on NEED_MULTIPLE_NODES
+
 source "mm/Kconfig"
 
 config OWNERSHIP_TRACE
index 4dd4f78d3dcc80a0799a96ab7fc629fe09b728ac..d22af851f3f638b09fdc4394a05e2cebf8a10201 100644 (file)
@@ -2,3 +2,4 @@
 generic-y      += clkdev.h
 generic-y      += exec.h
 generic-y      += trace_clock.h
+generic-y      += param.h
diff --git a/arch/avr32/include/asm/numnodes.h b/arch/avr32/include/asm/numnodes.h
deleted file mode 100644 (file)
index 0b864d7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_AVR32_NUMNODES_H
-#define __ASM_AVR32_NUMNODES_H
-
-/* Max 4 nodes */
-#define NODES_SHIFT    2
-
-#endif /* __ASM_AVR32_NUMNODES_H */
diff --git a/arch/avr32/include/asm/param.h b/arch/avr32/include/asm/param.h
deleted file mode 100644 (file)
index 009a167..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __ASM_AVR32_PARAM_H
-#define __ASM_AVR32_PARAM_H
-
-#include <uapi/asm/param.h>
-
-# define HZ            CONFIG_HZ
-# define USER_HZ       100             /* User interfaces are in "ticks" */
-# define CLOCKS_PER_SEC        (USER_HZ)       /* frequency at which times() counts */
-#endif /* __ASM_AVR32_PARAM_H */
index df53e7a467740a34846a4852c93122f3ef82a18e..3b85eaddf525f2be65d5772be3f28051afac7b43 100644 (file)
@@ -33,3 +33,4 @@ header-y += termbits.h
 header-y += termios.h
 header-y += types.h
 header-y += unistd.h
+generic-y += param.h
diff --git a/arch/avr32/include/uapi/asm/param.h b/arch/avr32/include/uapi/asm/param.h
deleted file mode 100644 (file)
index d28aa5e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _UAPI__ASM_AVR32_PARAM_H
-#define _UAPI__ASM_AVR32_PARAM_H
-
-
-#ifndef HZ
-# define HZ            100
-#endif
-
-/* TODO: Should be configurable */
-#define EXEC_PAGESIZE  4096
-
-#ifndef NOGROUP
-# define NOGROUP       (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64
-
-#endif /* _UAPI__ASM_AVR32_PARAM_H */
index 596f7305d93f017c43af7fc5f965ea4d0b988246..2c9412908024d4ce88d8945cf953b0d24437dcaf 100644 (file)
@@ -264,7 +264,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
                        break;
                case R_AVR32_GOT18SW:
                        if ((relocation & 0xfffe0003) != 0
-                           && (relocation & 0xfffc0003) != 0xffff0000)
+                           && (relocation & 0xfffc0000) != 0xfffc0000)
                                return reloc_overflow(module, "R_AVR32_GOT18SW",
                                                     relocation);
                        relocation >>= 2;
index cb0f6afb73894ef16019b7a53861330a49d72d27..9edc35ff8cf1420e9576f195f92658e71517c073 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <asm/bootinfo.h>
+#include <asm/idle.h>
 #include <asm/reboot.h>
 #include <asm/mach-au1x00/au1000.h>
 #include <prom.h>
index 38afb11ba2c4605e5c370f979eba3bc86a97621b..93fa586d52e2d480d6157cc0fcffdf962cad6534 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 
+#include <asm/idle.h>
 #include <asm/processor.h>
 #include <asm/time.h>
 #include <asm/mach-au1x00/au1000.h>
index a0233a2c198812980405dc05e117de444413552e..8be4e856b8b8942e903c286c2004fb46c4d0df9d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 
 #include <asm/bootinfo.h>
+#include <asm/idle.h>
 #include <asm/time.h>          /* for mips_hpt_frequency */
 #include <asm/reboot.h>                /* for _machine_{restart,halt} */
 #include <asm/mips_machine.h>
index 516b4428df4ecd3ac5b45a6397f8ffe4a2e070c1..4eedd481dd007bba3b25bfd733fca34cbe895730 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/leds.h>
 
+#include <asm/idle.h>
 #include <asm/processor.h>
 
 #include <cobalt.h>
index face9d26e6d5a1558c93cd149e60eb742fad8619..bac26b971c5e86342dc751bf946434a6ceead08f 100644 (file)
@@ -228,7 +228,6 @@ CONFIG_HIDRAW=y
 CONFIG_USB_HID=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_EHCI_TT_NEWSCHED=y
index 14752dde754018170930faa0aabfbd049b2a4312..e2b4ad55462f3477f6c4b5e63d54057064b92fde 100644 (file)
@@ -344,7 +344,6 @@ CONFIG_UHID=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB=y
 CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
index b6acd2f256b682f4c3ab37774eb3ba70bcee7595..343bebc4b63b981724a17b770dc71b895d4dc225 100644 (file)
@@ -300,7 +300,6 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_OTG_WHITELIST=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
index c9456e7a7283dfa15b507f021bb3f8f6696a45ca..778e32d817bc7da48056167edb4e137547ca9ef4 100644 (file)
@@ -6,8 +6,6 @@
 #include <linux/seq_file.h>
 #include <linux/clk.h>
 
-extern void (*cpu_wait) (void);
-
 struct clk;
 
 struct clk_ops {
diff --git a/arch/mips/include/asm/idle.h b/arch/mips/include/asm/idle.h
new file mode 100644 (file)
index 0000000..d192158
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __ASM_IDLE_H
+#define __ASM_IDLE_H
+
+#include <linux/linkage.h>
+
+extern void (*cpu_wait)(void);
+extern void r4k_wait(void);
+extern asmlinkage void __r4k_wait(void);
+extern void r4k_wait_irqoff(void);
+extern void __pastwait(void);
+
+static inline int using_rollback_handler(void)
+{
+       return cpu_wait == r4k_wait;
+}
+
+static inline int address_is_in_r4k_wait_irqoff(unsigned long addr)
+{
+       return addr >= (unsigned long)r4k_wait_irqoff &&
+              addr < (unsigned long)__pastwait;
+}
+
+#endif /* __ASM_IDLE_H  */
index 1be13727323f7f2baf0395ee3360de5a78fcfaae..b7e59853fd33b05df930c3fb795aa03a9a6de23e 100644 (file)
@@ -118,7 +118,7 @@ static inline void set_io_port_base(unsigned long base)
  */
 static inline unsigned long virt_to_phys(volatile const void *address)
 {
-       return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+       return __pa(address);
 }
 
 /*
diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/asm/kvm.h
deleted file mode 100644 (file)
index 85789ea..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-* 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.
-*
-* Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
-* Authors: Sanjay Lal <sanjayl@kymasys.com>
-*/
-
-#ifndef __LINUX_KVM_MIPS_H
-#define __LINUX_KVM_MIPS_H
-
-#include <linux/types.h>
-
-#define __KVM_MIPS
-
-#define N_MIPS_COPROC_REGS      32
-#define N_MIPS_COPROC_SEL      8
-
-/* for KVM_GET_REGS and KVM_SET_REGS */
-struct kvm_regs {
-       __u32 gprs[32];
-       __u32 hi;
-       __u32 lo;
-       __u32 pc;
-
-       __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];
-};
-
-/* for KVM_GET_SREGS and KVM_SET_SREGS */
-struct kvm_sregs {
-};
-
-/* for KVM_GET_FPU and KVM_SET_FPU */
-struct kvm_fpu {
-};
-
-struct kvm_debug_exit_arch {
-};
-
-/* for KVM_SET_GUEST_DEBUG */
-struct kvm_guest_debug_arch {
-};
-
-struct kvm_mips_interrupt {
-       /* in */
-       __u32 cpu;
-       __u32 irq;
-};
-
-/* definition of registers in kvm_run */
-struct kvm_sync_regs {
-};
-
-#endif /* __LINUX_KVM_MIPS_H */
index e68781e183873b8ef40ae98157a4e6b260dd3cf9..143875c6c95add1730f000ba326c7b2237f593a8 100644 (file)
@@ -336,7 +336,7 @@ enum emulation_result {
 #define VPN2_MASK           0xffffe000
 #define TLB_IS_GLOBAL(x)    (((x).tlb_lo0 & MIPS3_PG_G) && ((x).tlb_lo1 & MIPS3_PG_G))
 #define TLB_VPN2(x)         ((x).tlb_hi & VPN2_MASK)
-#define TLB_ASID(x)         (ASID_MASK((x).tlb_hi))
+#define TLB_ASID(x)         ((x).tlb_hi & ASID_MASK)
 #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) ? ((x).tlb_lo1 & MIPS3_PG_V) : ((x).tlb_lo0 & MIPS3_PG_V))
 
 struct kvm_mips_tlb {
index 1554721e4808e7ffc67d61bc87646cbdd5a325be..820116067c101070c6a4c35727d1e4cfb24563ee 100644 (file)
@@ -67,68 +67,45 @@ extern unsigned long pgd_current[];
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
-#define ASID_INC(asid)                                         \
-({                                                             \
-       unsigned long __asid = asid;                            \
-       __asm__("1:\taddiu\t%0,1\t\t\t\t# patched\n\t"          \
-       ".section\t__asid_inc,\"a\"\n\t"                        \
-       ".word\t1b\n\t"                                         \
-       ".previous"                                             \
-       :"=r" (__asid)                                          \
-       :"0" (__asid));                                         \
-       __asid;                                                 \
-})
-#define ASID_MASK(asid)                                                \
-({                                                             \
-       unsigned long __asid = asid;                            \
-       __asm__("1:\tandi\t%0,%1,0xfc0\t\t\t# patched\n\t"      \
-       ".section\t__asid_mask,\"a\"\n\t"                       \
-       ".word\t1b\n\t"                                         \
-       ".previous"                                             \
-       :"=r" (__asid)                                          \
-       :"r" (__asid));                                         \
-       __asid;                                                 \
-})
-#define ASID_VERSION_MASK                                      \
-({                                                             \
-       unsigned long __asid;                                   \
-       __asm__("1:\taddiu\t%0,$0,0xff00\t\t\t\t# patched\n\t"  \
-       ".section\t__asid_version_mask,\"a\"\n\t"               \
-       ".word\t1b\n\t"                                         \
-       ".previous"                                             \
-       :"=r" (__asid));                                        \
-       __asid;                                                 \
-})
-#define ASID_FIRST_VERSION                                     \
-({                                                             \
-       unsigned long __asid = asid;                            \
-       __asm__("1:\tli\t%0,0x100\t\t\t\t# patched\n\t"         \
-       ".section\t__asid_first_version,\"a\"\n\t"              \
-       ".word\t1b\n\t"                                         \
-       ".previous"                                             \
-       :"=r" (__asid));                                        \
-       __asid;                                                 \
-})
-
-#define ASID_FIRST_VERSION_R3000       0x1000
-#define ASID_FIRST_VERSION_R4000       0x100
-#define ASID_FIRST_VERSION_R8000       0x1000
-#define ASID_FIRST_VERSION_RM9000      0x1000
+#define ASID_INC       0x40
+#define ASID_MASK      0xfc0
+
+#elif defined(CONFIG_CPU_R8000)
+
+#define ASID_INC       0x10
+#define ASID_MASK      0xff0
+
+#elif defined(CONFIG_MIPS_MT_SMTC)
+
+#define ASID_INC       0x1
+extern unsigned long smtc_asid_mask;
+#define ASID_MASK      (smtc_asid_mask)
+#define HW_ASID_MASK   0xff
+/* End SMTC/34K debug hack */
+#else /* FIXME: not correct for R6000 */
+
+#define ASID_INC       0x1
+#define ASID_MASK      0xff
 
-#ifdef CONFIG_MIPS_MT_SMTC
-#define SMTC_HW_ASID_MASK              0xff
-extern unsigned int smtc_asid_mask;
 #endif
 
 #define cpu_context(cpu, mm)   ((mm)->context.asid[cpu])
-#define cpu_asid(cpu, mm)      ASID_MASK(cpu_context((cpu), (mm)))
+#define cpu_asid(cpu, mm)      (cpu_context((cpu), (mm)) & ASID_MASK)
 #define asid_cache(cpu)                (cpu_data[cpu].asid_cache)
 
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
 }
 
+/*
+ *  All unused by hardware upper bits will be considered
+ *  as a software asid extension.
+ */
+#define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
+#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
+
 #ifndef CONFIG_MIPS_MT_SMTC
 /* Normal, classic MIPS get_new_mmu_context */
 static inline void
@@ -137,7 +114,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
        extern void kvm_local_flush_tlb_all(void);
        unsigned long asid = asid_cache(cpu);
 
-       if (!ASID_MASK((asid = ASID_INC(asid)))) {
+       if (! ((asid += ASID_INC) & ASID_MASK) ) {
                if (cpu_has_vtag_icache)
                        flush_icache_all();
 #ifdef CONFIG_VIRTUALIZATION
@@ -200,7 +177,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         * free up the ASID value for use and flush any old
         * instances of it from the TLB.
         */
-       oldasid = ASID_MASK(read_c0_entryhi());
+       oldasid = (read_c0_entryhi() & ASID_MASK);
        if(smtc_live_asid[mytlb][oldasid]) {
                smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
                if(smtc_live_asid[mytlb][oldasid] == 0)
@@ -211,7 +188,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         * having ASID_MASK smaller than the hardware maximum,
         * make sure no "soft" bits become "hard"...
         */
-       write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) |
+       write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
                         cpu_asid(cpu, next));
        ehb(); /* Make sure it propagates to TCStatus */
        evpe(mtflags);
@@ -264,15 +241,15 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
 #ifdef CONFIG_MIPS_MT_SMTC
        /* See comments for similar code above */
        mtflags = dvpe();
-       oldasid = ASID_MASK(read_c0_entryhi());
+       oldasid = read_c0_entryhi() & ASID_MASK;
        if(smtc_live_asid[mytlb][oldasid]) {
                smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
                if(smtc_live_asid[mytlb][oldasid] == 0)
                         smtc_flush_tlb_asid(oldasid);
        }
        /* See comments for similar code above */
-       write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) |
-                        cpu_asid(cpu, next));
+       write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
+                        cpu_asid(cpu, next));
        ehb(); /* Make sure it propagates to TCStatus */
        evpe(mtflags);
 #else
@@ -309,14 +286,14 @@ drop_mmu_context(struct mm_struct *mm, unsigned cpu)
 #ifdef CONFIG_MIPS_MT_SMTC
                /* See comments for similar code above */
                prevvpe = dvpe();
-               oldasid = ASID_MASK(read_c0_entryhi());
+               oldasid = (read_c0_entryhi() & ASID_MASK);
                if (smtc_live_asid[mytlb][oldasid]) {
                        smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
                        if(smtc_live_asid[mytlb][oldasid] == 0)
                                smtc_flush_tlb_asid(oldasid);
                }
                /* See comments for similar code above */
-               write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK)
+               write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK)
                                | cpu_asid(cpu, mm));
                ehb(); /* Make sure it propagates to TCStatus */
                evpe(prevvpe);
index eab99e536b5c9137e5cd1f117fa57ca1318c6c54..f59552fae9173264ab58ffd3fbe95e080ec5db93 100644 (file)
@@ -46,7 +46,6 @@
 #endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
 
 #include <linux/pfn.h>
-#include <asm/io.h>
 
 extern void build_clear_page(void);
 extern void build_copy_page(void);
@@ -151,6 +150,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
     ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
 #endif
 #define __va(x)                ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
+#include <asm/io.h>
 
 /*
  * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad
@@ -171,14 +171,13 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 
 #ifdef CONFIG_FLATMEM
 
-#define pfn_valid(pfn)                                                 \
-({                                                                     \
-       unsigned long __pfn = (pfn);                                    \
-       /* avoid <linux/bootmem.h> include hell */                      \
-       extern unsigned long min_low_pfn;                               \
-                                                                       \
-       __pfn >= min_low_pfn && __pfn < max_mapnr;                      \
-})
+static inline int pfn_valid(unsigned long pfn)
+{
+       /* avoid <linux/mm.h> include hell */
+       extern unsigned long max_mapnr;
+
+       return pfn >= ARCH_PFN_OFFSET && pfn < max_mapnr;
+}
 
 #elif defined(CONFIG_SPARSEMEM)
 
index 71686c897deaa2651bbb5808ae4192f57ea1f54f..1470b7b68b0e98996d271b25b86584fb6f3261a5 100644 (file)
@@ -28,7 +28,6 @@
 /*
  * System setup and hardware flags..
  */
-extern void (*cpu_wait)(void);
 
 extern unsigned int vced_count, vcei_count;
 
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h
new file mode 100644 (file)
index 0000000..85789ea
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+* 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.
+*
+* Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
+* Authors: Sanjay Lal <sanjayl@kymasys.com>
+*/
+
+#ifndef __LINUX_KVM_MIPS_H
+#define __LINUX_KVM_MIPS_H
+
+#include <linux/types.h>
+
+#define __KVM_MIPS
+
+#define N_MIPS_COPROC_REGS      32
+#define N_MIPS_COPROC_SEL      8
+
+/* for KVM_GET_REGS and KVM_SET_REGS */
+struct kvm_regs {
+       __u32 gprs[32];
+       __u32 hi;
+       __u32 lo;
+       __u32 pc;
+
+       __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];
+};
+
+/* for KVM_GET_SREGS and KVM_SET_SREGS */
+struct kvm_sregs {
+};
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_mips_interrupt {
+       /* in */
+       __u32 cpu;
+       __u32 irq;
+};
+
+/* definition of registers in kvm_run */
+struct kvm_sync_regs {
+};
+
+#endif /* __LINUX_KVM_MIPS_H */
index 16338b84fa79d337c9d0f32c64f37de9a23a43e3..1dee279f96659c6ae2d2ac6d42af77483454076d 100644 (file)
 #define __NR_process_vm_writev         (__NR_Linux + 305)
 #define __NR_kcmp                      (__NR_Linux + 306)
 #define __NR_finit_module              (__NR_Linux + 307)
+#define __NR_getdents64                        (__NR_Linux + 308)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            307
+#define __NR_Linux_syscalls            308
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         307
+#define __NR_64_Linux_syscalls         308
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
index 6ad9e04bdf6210a8b722e92aca5e49161cb4deca..423d871a946ba15ae5b5ea70338530949fa8d166 100644 (file)
@@ -4,7 +4,7 @@
 
 extra-y                := head.o vmlinux.lds
 
-obj-y          += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
+obj-y          += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \
                   prom.o ptrace.o reset.o setup.o signal.o syscall.o \
                   time.o topology.o traps.o unaligned.o watch.o vdso.o
 
index 4bbffdb9024ffb9cf437adb4fd5243e75e68a88c..c6568bf4b1b05559b43bc18f65e33c84a85963ba 100644 (file)
 #include <asm/spram.h>
 #include <asm/uaccess.h>
 
-/*
- * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
- * the implementation of the "wait" feature differs between CPU families. This
- * points to the function that implements CPU specific wait.
- * The wait instruction stops the pipeline and reduces the power consumption of
- * the CPU very much.
- */
-void (*cpu_wait)(void);
-EXPORT_SYMBOL(cpu_wait);
-
-static void r3081_wait(void)
-{
-       unsigned long cfg = read_c0_conf();
-       write_c0_conf(cfg | R30XX_CONF_HALT);
-}
-
-static void r39xx_wait(void)
-{
-       local_irq_disable();
-       if (!need_resched())
-               write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
-       local_irq_enable();
-}
-
-extern void r4k_wait(void);
-
-/*
- * This variant is preferable as it allows testing need_resched and going to
- * sleep depending on the outcome atomically.  Unfortunately the "It is
- * implementation-dependent whether the pipeline restarts when a non-enabled
- * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
- * using this version a gamble.
- */
-void r4k_wait_irqoff(void)
-{
-       local_irq_disable();
-       if (!need_resched())
-               __asm__("       .set    push            \n"
-                       "       .set    mips3           \n"
-                       "       wait                    \n"
-                       "       .set    pop             \n");
-       local_irq_enable();
-       __asm__("       .globl __pastwait       \n"
-               "__pastwait:                    \n");
-}
-
-/*
- * The RM7000 variant has to handle erratum 38.         The workaround is to not
- * have any pending stores when the WAIT instruction is executed.
- */
-static void rm7k_wait_irqoff(void)
-{
-       local_irq_disable();
-       if (!need_resched())
-               __asm__(
-               "       .set    push                                    \n"
-               "       .set    mips3                                   \n"
-               "       .set    noat                                    \n"
-               "       mfc0    $1, $12                                 \n"
-               "       sync                                            \n"
-               "       mtc0    $1, $12         # stalls until W stage  \n"
-               "       wait                                            \n"
-               "       mtc0    $1, $12         # stalls until W stage  \n"
-               "       .set    pop                                     \n");
-       local_irq_enable();
-}
-
-/*
- * The Au1xxx wait is available only if using 32khz counter or
- * external timer source, but specifically not CP0 Counter.
- * alchemy/common/time.c may override cpu_wait!
- */
-static void au1k_wait(void)
-{
-       __asm__("       .set    mips3                   \n"
-               "       cache   0x14, 0(%0)             \n"
-               "       cache   0x14, 32(%0)            \n"
-               "       sync                            \n"
-               "       nop                             \n"
-               "       wait                            \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       .set    mips0                   \n"
-               : : "r" (au1k_wait));
-}
-
-static int __initdata nowait;
-
-static int __init wait_disable(char *s)
-{
-       nowait = 1;
-
-       return 1;
-}
-
-__setup("nowait", wait_disable);
-
 static int __cpuinitdata mips_fpu_disabled;
 
 static int __init fpu_disable(char *s)
@@ -150,105 +51,6 @@ static int __init dsp_disable(char *s)
 
 __setup("nodsp", dsp_disable);
 
-void __init check_wait(void)
-{
-       struct cpuinfo_mips *c = &current_cpu_data;
-
-       if (nowait) {
-               printk("Wait instruction disabled.\n");
-               return;
-       }
-
-       switch (c->cputype) {
-       case CPU_R3081:
-       case CPU_R3081E:
-               cpu_wait = r3081_wait;
-               break;
-       case CPU_TX3927:
-               cpu_wait = r39xx_wait;
-               break;
-       case CPU_R4200:
-/*     case CPU_R4300: */
-       case CPU_R4600:
-       case CPU_R4640:
-       case CPU_R4650:
-       case CPU_R4700:
-       case CPU_R5000:
-       case CPU_R5500:
-       case CPU_NEVADA:
-       case CPU_4KC:
-       case CPU_4KEC:
-       case CPU_4KSC:
-       case CPU_5KC:
-       case CPU_25KF:
-       case CPU_PR4450:
-       case CPU_BMIPS3300:
-       case CPU_BMIPS4350:
-       case CPU_BMIPS4380:
-       case CPU_BMIPS5000:
-       case CPU_CAVIUM_OCTEON:
-       case CPU_CAVIUM_OCTEON_PLUS:
-       case CPU_CAVIUM_OCTEON2:
-       case CPU_JZRISC:
-       case CPU_LOONGSON1:
-       case CPU_XLR:
-       case CPU_XLP:
-               cpu_wait = r4k_wait;
-               break;
-
-       case CPU_RM7000:
-               cpu_wait = rm7k_wait_irqoff;
-               break;
-
-       case CPU_M14KC:
-       case CPU_M14KEC:
-       case CPU_24K:
-       case CPU_34K:
-       case CPU_1004K:
-               cpu_wait = r4k_wait;
-               if (read_c0_config7() & MIPS_CONF7_WII)
-                       cpu_wait = r4k_wait_irqoff;
-               break;
-
-       case CPU_74K:
-               cpu_wait = r4k_wait;
-               if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0))
-                       cpu_wait = r4k_wait_irqoff;
-               break;
-
-       case CPU_TX49XX:
-               cpu_wait = r4k_wait_irqoff;
-               break;
-       case CPU_ALCHEMY:
-               cpu_wait = au1k_wait;
-               break;
-       case CPU_20KC:
-               /*
-                * WAIT on Rev1.0 has E1, E2, E3 and E16.
-                * WAIT on Rev2.0 and Rev3.0 has E16.
-                * Rev3.1 WAIT is nop, why bother
-                */
-               if ((c->processor_id & 0xff) <= 0x64)
-                       break;
-
-               /*
-                * Another rev is incremeting c0_count at a reduced clock
-                * rate while in WAIT mode.  So we basically have the choice
-                * between using the cp0 timer as clocksource or avoiding
-                * the WAIT instruction.  Until more details are known,
-                * disable the use of WAIT for 20Kc entirely.
-                  cpu_wait = r4k_wait;
-                */
-               break;
-       case CPU_RM9000:
-               if ((c->processor_id & 0x00ff) >= 0x40)
-                       cpu_wait = r4k_wait;
-               break;
-       default:
-               break;
-       }
-}
-
 static inline void check_errata(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
index 35bed0d2342c9a779ef5d0c12a3a8080938484f7..3be9e7bb30ff05dbfa1c4866d3decba0a69a8715 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/bootmem.h>
 #include <linux/crash_dump.h>
 #include <asm/uaccess.h>
+#include <linux/slab.h>
 
 static int __init parse_savemaxmem(char *p)
 {
index 5c2ba9f08a80d33ed0cdf61ffaf429524c3ffd4f..31fa856829cbf2620521317e5247d42b9e3fb087 100644 (file)
@@ -122,7 +122,7 @@ handle_vcei:
        __FINIT
 
        .align  5       /* 32 byte rollback region */
-LEAF(r4k_wait)
+LEAF(__r4k_wait)
        .set    push
        .set    noreorder
        /* start of rollback region */
@@ -146,14 +146,14 @@ LEAF(r4k_wait)
        jr      ra
        nop
        .set    pop
-       END(r4k_wait)
+       END(__r4k_wait)
 
        .macro  BUILD_ROLLBACK_PROLOGUE handler
        FEXPORT(rollback_\handler)
        .set    push
        .set    noat
        MFC0    k0, CP0_EPC
-       PTR_LA  k1, r4k_wait
+       PTR_LA  k1, __r4k_wait
        ori     k0, 0x1f        /* 32 byte rollback region */
        xori    k0, 0x1f
        bne     k0, k1, 9f
@@ -493,7 +493,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
        .set    noreorder
        /* check if TLB contains a entry for EPC */
        MFC0    k1, CP0_ENTRYHI
-       andi    k1, 0xff        /* ASID_MASK patched at run-time!! */
+       andi    k1, 0xff        /* ASID_MASK */
        MFC0    k0, CP0_EPC
        PTR_SRL k0, _PAGE_SHIFT + 1
        PTR_SLL k0, _PAGE_SHIFT + 1
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
new file mode 100644 (file)
index 0000000..3b09b88
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * MIPS idle loop and WAIT instruction support.
+ *
+ * Copyright (C) xxxx  the Anonymous
+ * Copyright (C) 1994 - 2006 Ralf Baechle
+ * Copyright (C) 2003, 2004  Maciej W. Rozycki
+ * Copyright (C) 2001, 2004, 2011, 2012         MIPS Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/irqflags.h>
+#include <linux/printk.h>
+#include <linux/sched.h>
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
+#include <asm/idle.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait.
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
+ */
+void (*cpu_wait)(void);
+EXPORT_SYMBOL(cpu_wait);
+
+static void r3081_wait(void)
+{
+       unsigned long cfg = read_c0_conf();
+       write_c0_conf(cfg | R30XX_CONF_HALT);
+       local_irq_enable();
+}
+
+static void r39xx_wait(void)
+{
+       if (!need_resched())
+               write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
+       local_irq_enable();
+}
+
+void r4k_wait(void)
+{
+       local_irq_enable();
+       __r4k_wait();
+}
+
+/*
+ * This variant is preferable as it allows testing need_resched and going to
+ * sleep depending on the outcome atomically.  Unfortunately the "It is
+ * implementation-dependent whether the pipeline restarts when a non-enabled
+ * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
+ * using this version a gamble.
+ */
+void r4k_wait_irqoff(void)
+{
+       if (!need_resched())
+               __asm__(
+               "       .set    push            \n"
+               "       .set    mips3           \n"
+               "       wait                    \n"
+               "       .set    pop             \n");
+       local_irq_enable();
+       __asm__(
+       "       .globl __pastwait       \n"
+       "__pastwait:                    \n");
+}
+
+/*
+ * The RM7000 variant has to handle erratum 38.         The workaround is to not
+ * have any pending stores when the WAIT instruction is executed.
+ */
+static void rm7k_wait_irqoff(void)
+{
+       if (!need_resched())
+               __asm__(
+               "       .set    push                                    \n"
+               "       .set    mips3                                   \n"
+               "       .set    noat                                    \n"
+               "       mfc0    $1, $12                                 \n"
+               "       sync                                            \n"
+               "       mtc0    $1, $12         # stalls until W stage  \n"
+               "       wait                                            \n"
+               "       mtc0    $1, $12         # stalls until W stage  \n"
+               "       .set    pop                                     \n");
+       local_irq_enable();
+}
+
+/*
+ * The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter.
+ * alchemy/common/time.c may override cpu_wait!
+ */
+static void au1k_wait(void)
+{
+       __asm__(
+       "       .set    mips3                   \n"
+       "       cache   0x14, 0(%0)             \n"
+       "       cache   0x14, 32(%0)            \n"
+       "       sync                            \n"
+       "       nop                             \n"
+       "       wait                            \n"
+       "       nop                             \n"
+       "       nop                             \n"
+       "       nop                             \n"
+       "       nop                             \n"
+       "       .set    mips0                   \n"
+       : : "r" (au1k_wait));
+       local_irq_enable();
+}
+
+static int __initdata nowait;
+
+static int __init wait_disable(char *s)
+{
+       nowait = 1;
+
+       return 1;
+}
+
+__setup("nowait", wait_disable);
+
+void __init check_wait(void)
+{
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       if (nowait) {
+               printk("Wait instruction disabled.\n");
+               return;
+       }
+
+       switch (c->cputype) {
+       case CPU_R3081:
+       case CPU_R3081E:
+               cpu_wait = r3081_wait;
+               break;
+       case CPU_TX3927:
+               cpu_wait = r39xx_wait;
+               break;
+       case CPU_R4200:
+/*     case CPU_R4300: */
+       case CPU_R4600:
+       case CPU_R4640:
+       case CPU_R4650:
+       case CPU_R4700:
+       case CPU_R5000:
+       case CPU_R5500:
+       case CPU_NEVADA:
+       case CPU_4KC:
+       case CPU_4KEC:
+       case CPU_4KSC:
+       case CPU_5KC:
+       case CPU_25KF:
+       case CPU_PR4450:
+       case CPU_BMIPS3300:
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+       case CPU_BMIPS5000:
+       case CPU_CAVIUM_OCTEON:
+       case CPU_CAVIUM_OCTEON_PLUS:
+       case CPU_CAVIUM_OCTEON2:
+       case CPU_JZRISC:
+       case CPU_LOONGSON1:
+       case CPU_XLR:
+       case CPU_XLP:
+               cpu_wait = r4k_wait;
+               break;
+
+       case CPU_RM7000:
+               cpu_wait = rm7k_wait_irqoff;
+               break;
+
+       case CPU_M14KC:
+       case CPU_M14KEC:
+       case CPU_24K:
+       case CPU_34K:
+       case CPU_1004K:
+               cpu_wait = r4k_wait;
+               if (read_c0_config7() & MIPS_CONF7_WII)
+                       cpu_wait = r4k_wait_irqoff;
+               break;
+
+       case CPU_74K:
+               cpu_wait = r4k_wait;
+               if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0))
+                       cpu_wait = r4k_wait_irqoff;
+               break;
+
+       case CPU_TX49XX:
+               cpu_wait = r4k_wait_irqoff;
+               break;
+       case CPU_ALCHEMY:
+               cpu_wait = au1k_wait;
+               break;
+       case CPU_20KC:
+               /*
+                * WAIT on Rev1.0 has E1, E2, E3 and E16.
+                * WAIT on Rev2.0 and Rev3.0 has E16.
+                * Rev3.1 WAIT is nop, why bother
+                */
+               if ((c->processor_id & 0xff) <= 0x64)
+                       break;
+
+               /*
+                * Another rev is incremeting c0_count at a reduced clock
+                * rate while in WAIT mode.  So we basically have the choice
+                * between using the cp0 timer as clocksource or avoiding
+                * the WAIT instruction.  Until more details are known,
+                * disable the use of WAIT for 20Kc entirely.
+                  cpu_wait = r4k_wait;
+                */
+               break;
+       case CPU_RM9000:
+               if ((c->processor_id & 0x00ff) >= 0x40)
+                       cpu_wait = r4k_wait;
+               break;
+       default:
+               break;
+       }
+}
+
+static void smtc_idle_hook(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+       void smtc_idle_loop_hook(void);
+
+       smtc_idle_loop_hook();
+#endif
+}
+
+void arch_cpu_idle(void)
+{
+       smtc_idle_hook();
+       if (cpu_wait)
+               cpu_wait();
+       else
+               local_irq_enable();
+}
index 12bc4ebdf55b6bf5e087532feafcaddca94b417e..1f8187ab0997be478f69b66eadb8ac4a6bf7e489 100644 (file)
@@ -207,7 +207,10 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
 
 void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
-       free_insn_slot(p->ainsn.insn, 0);
+       if (p->ainsn.insn) {
+               free_insn_slot(p->ainsn.insn, 0);
+               p->ainsn.insn = NULL;
+       }
 }
 
 static void save_previous_kprobe(struct kprobe_ctlblk *kcb)
index a3e461408b7e830758d3b3dfeed661573277131e..acb34373679e21f9940f62f251e64dc1e32e5f17 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
+#include <asm/idle.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 #include <asm/prom.h>
index eb902c1f0cad4c50031836ad73225f620be8d7d5..c6a041d9d05d57fcd71f91a228c86524e00efd08 100644 (file)
@@ -51,19 +51,6 @@ void arch_cpu_idle_dead(void)
 }
 #endif
 
-void arch_cpu_idle(void)
-{
-#ifdef CONFIG_MIPS_MT_SMTC
-       extern void smtc_idle_loop_hook(void);
-
-       smtc_idle_loop_hook();
-#endif
-       if (cpu_wait)
-               (*cpu_wait)();
-       else
-               local_irq_enable();
-}
-
 asmlinkage void ret_from_fork(void);
 asmlinkage void ret_from_kernel_thread(void);
 
@@ -224,6 +211,9 @@ struct mips_frame_info {
        int             pc_offset;
 };
 
+#define J_TARGET(pc,target)    \
+               (((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
+
 static inline int is_ra_save_ins(union mips_instruction *ip)
 {
 #ifdef CONFIG_CPU_MICROMIPS
@@ -264,7 +254,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
 #endif
 }
 
-static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
+static inline int is_jump_ins(union mips_instruction *ip)
 {
 #ifdef CONFIG_CPU_MICROMIPS
        /*
@@ -288,6 +278,8 @@ static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
                return 0;
        return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op);
 #else
+       if (ip->j_format.opcode == j_op)
+               return 1;
        if (ip->j_format.opcode == jal_op)
                return 1;
        if (ip->r_format.opcode != spec_op)
@@ -350,7 +342,7 @@ static int get_frame_info(struct mips_frame_info *info)
 
        for (i = 0; i < max_insns; i++, ip++) {
 
-               if (is_jal_jalr_jr_ins(ip))
+               if (is_jump_ins(ip))
                        break;
                if (!info->frame_size) {
                        if (is_sp_move_ins(ip))
@@ -393,15 +385,42 @@ err:
 
 static struct mips_frame_info schedule_mfi __read_mostly;
 
+#ifdef CONFIG_KALLSYMS
+static unsigned long get___schedule_addr(void)
+{
+       return kallsyms_lookup_name("__schedule");
+}
+#else
+static unsigned long get___schedule_addr(void)
+{
+       union mips_instruction *ip = (void *)schedule;
+       int max_insns = 8;
+       int i;
+
+       for (i = 0; i < max_insns; i++, ip++) {
+               if (ip->j_format.opcode == j_op)
+                       return J_TARGET(ip, ip->j_format.target);
+       }
+       return 0;
+}
+#endif
+
 static int __init frame_info_init(void)
 {
        unsigned long size = 0;
 #ifdef CONFIG_KALLSYMS
        unsigned long ofs;
+#endif
+       unsigned long addr;
+
+       addr = get___schedule_addr();
+       if (!addr)
+               addr = (unsigned long)schedule;
 
-       kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs);
+#ifdef CONFIG_KALLSYMS
+       kallsyms_lookup_size_offset(addr, &size, &ofs);
 #endif
-       schedule_mfi.func = schedule;
+       schedule_mfi.func = (void *)addr;
        schedule_mfi.func_size = size;
 
        get_frame_info(&schedule_mfi);
index 36cfd4060e1f423eed05869a1adc9591f36ab662..97a5909a61cf0c623dfdf8284eaf11bf13e7adf7 100644 (file)
@@ -423,4 +423,5 @@ sys_call_table:
        PTR     sys_process_vm_writev           /* 5305 */
        PTR     sys_kcmp
        PTR     sys_finit_module
+       PTR     sys_getdents64
        .size   sys_call_table,.-sys_call_table
index c17619fe18e32a9f23a5df7e18b0b943b5d0cf2c..6e7862ab46cc4a6fef3c31e1ade85e04b357824f 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/atomic.h>
 #include <asm/cpu.h>
 #include <asm/processor.h>
+#include <asm/idle.h>
 #include <asm/r4k-timer.h>
 #include <asm/mmu_context.h>
 #include <asm/time.h>
index 31d22f3121c98bb8c0b57488c60c58d4c0ca5b4c..75a4fd709841a9df42d4eba3218e053f7bf8c351 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/hardirq.h>
 #include <asm/hazards.h>
 #include <asm/irq.h>
+#include <asm/idle.h>
 #include <asm/mmu_context.h>
 #include <asm/mipsregs.h>
 #include <asm/cacheflush.h>
@@ -111,7 +112,7 @@ static int vpe0limit;
 static int ipibuffers;
 static int nostlb;
 static int asidmask;
-unsigned int smtc_asid_mask = 0xff;
+unsigned long smtc_asid_mask = 0xff;
 
 static int __init vpe0tcs(char *str)
 {
@@ -858,7 +859,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
        unsigned long flags;
        int mtflags;
        unsigned long tcrestart;
-       extern void r4k_wait_irqoff(void), __pastwait(void);
        int set_resched_flag = (type == LINUX_SMP_IPI &&
                                action == SMP_RESCHEDULE_YOURSELF);
 
@@ -914,8 +914,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
                         */
                        if (cpu_wait == r4k_wait_irqoff) {
                                tcrestart = read_tc_c0_tcrestart();
-                               if (tcrestart >= (unsigned long)r4k_wait_irqoff
-                                   && tcrestart < (unsigned long)__pastwait) {
+                               if (address_is_in_r4k_wait_irqoff(tcrestart)) {
                                        write_tc_c0_tcrestart(__pastwait);
                                        tcstatus &= ~TCSTATUS_IXMT;
                                        write_tc_c0_tcstatus(tcstatus);
@@ -1395,7 +1394,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
        asid = asid_cache(cpu);
 
        do {
-               if (!ASID_MASK(ASID_INC(asid))) {
+               if (!((asid += ASID_INC) & ASID_MASK) ) {
                        if (cpu_has_vtag_icache)
                                flush_icache_all();
                        /* Traverse all online CPUs (hack requires contiguous range) */
@@ -1414,7 +1413,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
                                                mips_ihb();
                                        }
                                        tcstat = read_tc_c0_tcstatus();
-                                       smtc_live_asid[tlb][ASID_MASK(tcstat)] |= (asiduse)(0x1 << i);
+                                       smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i);
                                        if (!prevhalt)
                                                write_tc_c0_tchalt(0);
                                }
@@ -1423,7 +1422,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
                                asid = ASID_FIRST_VERSION;
                        local_flush_tlb_all();  /* start new asid cycle */
                }
-       } while (smtc_live_asid[tlb][ASID_MASK(asid)]);
+       } while (smtc_live_asid[tlb][(asid & ASID_MASK)]);
 
        /*
         * SMTC shares the TLB within VPEs and possibly across all VPEs.
@@ -1461,7 +1460,7 @@ void smtc_flush_tlb_asid(unsigned long asid)
                tlb_read();
                ehb();
                ehi = read_c0_entryhi();
-               if (ASID_MASK(ehi) == asid) {
+               if ((ehi & ASID_MASK) == asid) {
                    /*
                     * Invalidate only entries with specified ASID,
                     * makiing sure all entries differ.
index 77cff1f6d050cb92e21475ae52a9ef2f037b5bc5..e3be67012d7882d23d657841d4bc7d436839c648 100644 (file)
@@ -41,6 +41,7 @@
 #include <asm/dsp.h>
 #include <asm/fpu.h>
 #include <asm/fpu_emulator.h>
+#include <asm/idle.h>
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
 #include <asm/module.h>
@@ -57,7 +58,6 @@
 #include <asm/uasm.h>
 
 extern void check_wait(void);
-extern asmlinkage void r4k_wait(void);
 extern asmlinkage void rollback_handle_int(void);
 extern asmlinkage void handle_int(void);
 extern u32 handle_tlbl[];
@@ -1542,7 +1542,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                extern char except_vec_vi, except_vec_vi_lui;
                extern char except_vec_vi_ori, except_vec_vi_end;
                extern char rollback_except_vec_vi;
-               char *vec_start = (cpu_wait == r4k_wait) ?
+               char *vec_start = using_rollback_handler() ?
                        &rollback_except_vec_vi : &except_vec_vi;
 #ifdef CONFIG_MIPS_MT_SMTC
                /*
@@ -1656,7 +1656,6 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
        unsigned int cpu = smp_processor_id();
        unsigned int status_set = ST0_CU0;
        unsigned int hwrena = cpu_hwrena_impl_bits;
-       unsigned long asid = 0;
 #ifdef CONFIG_MIPS_MT_SMTC
        int secondaryTC = 0;
        int bootTC = (cpu == 0);
@@ -1740,9 +1739,8 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
        }
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-       asid = ASID_FIRST_VERSION;
-       cpu_data[cpu].asid_cache = asid;
-       TLBMISS_HANDLER_SETUP();
+       if (!cpu_data[cpu].asid_cache)
+               cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
 
        atomic_inc(&init_mm.mm_count);
        current->active_mm = &init_mm;
@@ -1814,10 +1812,8 @@ void __init trap_init(void)
        extern char except_vec4;
        extern char except_vec3_r4000;
        unsigned long i;
-       int rollback;
 
        check_wait();
-       rollback = (cpu_wait == r4k_wait);
 
 #if defined(CONFIG_KGDB)
        if (kgdb_early_setup)
@@ -1894,7 +1890,8 @@ void __init trap_init(void)
        if (board_be_init)
                board_be_init();
 
-       set_except_vector(0, rollback ? rollback_handle_int : handle_int);
+       set_except_vector(0, using_rollback_handler() ? rollback_handle_int
+                                                     : handle_int);
        set_except_vector(1, handle_tlbm);
        set_except_vector(2, handle_tlbl);
        set_except_vector(3, handle_tlbs);
index 2b2bac9a40aa00a762a0efae5310fddd0521fb5c..4b6274b47f3368b289b378703e8e9a17de5f9275 100644 (file)
@@ -525,16 +525,18 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause,
                                printk("MTCz, cop0->reg[EBASE]: %#lx\n",
                                       kvm_read_c0_guest_ebase(cop0));
                        } else if (rd == MIPS_CP0_TLB_HI && sel == 0) {
-                               uint32_t nasid = ASID_MASK(vcpu->arch.gprs[rt]);
+                               uint32_t nasid =
+                                   vcpu->arch.gprs[rt] & ASID_MASK;
                                if ((KSEGX(vcpu->arch.gprs[rt]) != CKSEG0)
                                    &&
-                                   (ASID_MASK(kvm_read_c0_guest_entryhi(cop0))
-                                     != nasid)) {
+                                   ((kvm_read_c0_guest_entryhi(cop0) &
+                                     ASID_MASK) != nasid)) {
 
                                        kvm_debug
                                            ("MTCz, change ASID from %#lx to %#lx\n",
-                                            ASID_MASK(kvm_read_c0_guest_entryhi(cop0)),
-                                            ASID_MASK(vcpu->arch.gprs[rt]));
+                                            kvm_read_c0_guest_entryhi(cop0) &
+                                            ASID_MASK,
+                                            vcpu->arch.gprs[rt] & ASID_MASK);
 
                                        /* Blow away the shadow host TLBs */
                                        kvm_mips_flush_host_tlb(1);
@@ -986,7 +988,8 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause,
                 * resulting handler will do the right thing
                 */
                index = kvm_mips_guest_tlb_lookup(vcpu, (va & VPN2_MASK) |
-                                                 ASID_MASK(kvm_read_c0_guest_entryhi(cop0)));
+                                                 (kvm_read_c0_guest_entryhi
+                                                  (cop0) & ASID_MASK));
 
                if (index < 0) {
                        vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK);
@@ -1151,7 +1154,7 @@ kvm_mips_emulate_tlbmiss_ld(unsigned long cause, uint32_t *opc,
        struct kvm_vcpu_arch *arch = &vcpu->arch;
        enum emulation_result er = EMULATE_DONE;
        unsigned long entryhi = (vcpu->arch.  host_cp0_badvaddr & VPN2_MASK) |
-                               ASID_MASK(kvm_read_c0_guest_entryhi(cop0));
+                               (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK);
 
        if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
                /* save old pc */
@@ -1198,7 +1201,7 @@ kvm_mips_emulate_tlbinv_ld(unsigned long cause, uint32_t *opc,
        enum emulation_result er = EMULATE_DONE;
        unsigned long entryhi =
                (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
-               ASID_MASK(kvm_read_c0_guest_entryhi(cop0));
+               (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK);
 
        if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
                /* save old pc */
@@ -1243,7 +1246,7 @@ kvm_mips_emulate_tlbmiss_st(unsigned long cause, uint32_t *opc,
        struct kvm_vcpu_arch *arch = &vcpu->arch;
        enum emulation_result er = EMULATE_DONE;
        unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
-                               ASID_MASK(kvm_read_c0_guest_entryhi(cop0));
+                               (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK);
 
        if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
                /* save old pc */
@@ -1287,7 +1290,7 @@ kvm_mips_emulate_tlbinv_st(unsigned long cause, uint32_t *opc,
        struct kvm_vcpu_arch *arch = &vcpu->arch;
        enum emulation_result er = EMULATE_DONE;
        unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
-               ASID_MASK(kvm_read_c0_guest_entryhi(cop0));
+               (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK);
 
        if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
                /* save old pc */
@@ -1356,7 +1359,7 @@ kvm_mips_emulate_tlbmod(unsigned long cause, uint32_t *opc,
 {
        struct mips_coproc *cop0 = vcpu->arch.cop0;
        unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
-                               ASID_MASK(kvm_read_c0_guest_entryhi(cop0));
+                               (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK);
        struct kvm_vcpu_arch *arch = &vcpu->arch;
        enum emulation_result er = EMULATE_DONE;
 
@@ -1783,8 +1786,8 @@ kvm_mips_handle_tlbmiss(unsigned long cause, uint32_t *opc,
         */
        index = kvm_mips_guest_tlb_lookup(vcpu,
                                          (va & VPN2_MASK) |
-                                         ASID_MASK(kvm_read_c0_guest_entryhi
-                                          (vcpu->arch.cop0)));
+                                         (kvm_read_c0_guest_entryhi
+                                          (vcpu->arch.cop0) & ASID_MASK));
        if (index < 0) {
                if (exccode == T_TLB_LD_MISS) {
                        er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
index 89511a9258d394f2d540e722fdaaa8f5aa6a82f1..c777dd36d4a8bf88be1000dc993bc2d8774b6a33 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/kvm_host.h>
+#include <linux/srcu.h>
+
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -51,13 +53,13 @@ EXPORT_SYMBOL(kvm_mips_is_error_pfn);
 
 uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu)
 {
-       return ASID_MASK(vcpu->arch.guest_kernel_asid[smp_processor_id()]);
+       return vcpu->arch.guest_kernel_asid[smp_processor_id()] & ASID_MASK;
 }
 
 
 uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu)
 {
-       return ASID_MASK(vcpu->arch.guest_user_asid[smp_processor_id()]);
+       return vcpu->arch.guest_user_asid[smp_processor_id()] & ASID_MASK;
 }
 
 inline uint32_t kvm_mips_get_commpage_asid (struct kvm_vcpu *vcpu)
@@ -84,7 +86,7 @@ void kvm_mips_dump_host_tlbs(void)
        old_pagemask = read_c0_pagemask();
 
        printk("HOST TLBs:\n");
-       printk("ASID: %#lx\n", ASID_MASK(read_c0_entryhi()));
+       printk("ASID: %#lx\n", read_c0_entryhi() & ASID_MASK);
 
        for (i = 0; i < current_cpu_data.tlbsize; i++) {
                write_c0_index(i);
@@ -169,21 +171,27 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu)
        }
 }
 
-static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
+static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
 {
+       int srcu_idx, err = 0;
        pfn_t pfn;
 
        if (kvm->arch.guest_pmap[gfn] != KVM_INVALID_PAGE)
-               return;
+               return 0;
 
+        srcu_idx = srcu_read_lock(&kvm->srcu);
        pfn = kvm_mips_gfn_to_pfn(kvm, gfn);
 
        if (kvm_mips_is_error_pfn(pfn)) {
-               panic("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn);
+               kvm_err("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn);
+               err = -EFAULT;
+               goto out;
        }
 
        kvm->arch.guest_pmap[gfn] = pfn;
-       return;
+out:
+       srcu_read_unlock(&kvm->srcu, srcu_idx);
+       return err;
 }
 
 /* Translate guest KSEG0 addresses to Host PA */
@@ -207,7 +215,10 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu,
                        gva);
                return KVM_INVALID_PAGE;
        }
-       kvm_mips_map_page(vcpu->kvm, gfn);
+
+       if (kvm_mips_map_page(vcpu->kvm, gfn) < 0)
+               return KVM_INVALID_ADDR;
+
        return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
 }
 
@@ -310,8 +321,11 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
        even = !(gfn & 0x1);
        vaddr = badvaddr & (PAGE_MASK << 1);
 
-       kvm_mips_map_page(vcpu->kvm, gfn);
-       kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1);
+       if (kvm_mips_map_page(vcpu->kvm, gfn) < 0)
+               return -1;
+
+       if (kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1) < 0)
+               return -1;
 
        if (even) {
                pfn0 = kvm->arch.guest_pmap[gfn];
@@ -389,8 +403,11 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
                pfn0 = 0;
                pfn1 = 0;
        } else {
-               kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT);
-               kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT);
+               if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT) < 0)
+                       return -1;
+
+               if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT) < 0)
+                       return -1;
 
                pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT];
                pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT];
@@ -428,7 +445,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
 
        for (i = 0; i < KVM_MIPS_GUEST_TLB_SIZE; i++) {
                if (((TLB_VPN2(tlb[i]) & ~tlb[i].tlb_mask) == ((entryhi & VPN2_MASK) & ~tlb[i].tlb_mask)) &&
-                       (TLB_IS_GLOBAL(tlb[i]) || (TLB_ASID(tlb[i]) == ASID_MASK(entryhi)))) {
+                       (TLB_IS_GLOBAL(tlb[i]) || (TLB_ASID(tlb[i]) == (entryhi & ASID_MASK)))) {
                        index = i;
                        break;
                }
@@ -626,7 +643,7 @@ kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
 {
        unsigned long asid = asid_cache(cpu);
 
-       if (!(ASID_MASK(ASID_INC(asid)))) {
+       if (!((asid += ASID_INC) & ASID_MASK)) {
                if (cpu_has_vtag_icache) {
                        flush_icache_all();
                }
@@ -804,7 +821,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        if (!newasid) {
                /* If we preempted while the guest was executing, then reload the pre-empted ASID */
                if (current->flags & PF_VCPU) {
-                       write_c0_entryhi(ASID_MASK(vcpu->arch.preempt_entryhi));
+                       write_c0_entryhi(vcpu->arch.
+                                        preempt_entryhi & ASID_MASK);
                        ehb();
                }
        } else {
@@ -816,11 +834,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
                 */
                if (current->flags & PF_VCPU) {
                        if (KVM_GUEST_KERNEL_MODE(vcpu))
-                               write_c0_entryhi(ASID_MASK(vcpu->arch.
-                                                guest_kernel_asid[cpu]));
+                               write_c0_entryhi(vcpu->arch.
+                                                guest_kernel_asid[cpu] &
+                                                ASID_MASK);
                        else
-                               write_c0_entryhi(ASID_MASK(vcpu->arch.
-                                                guest_user_asid[cpu]));
+                               write_c0_entryhi(vcpu->arch.
+                                                guest_user_asid[cpu] &
+                                                ASID_MASK);
                        ehb();
                }
        }
@@ -879,7 +899,8 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
                            kvm_mips_guest_tlb_lookup(vcpu,
                                                      ((unsigned long) opc & VPN2_MASK)
                                                      |
-                                                     ASID_MASK(kvm_read_c0_guest_entryhi(cop0)));
+                                                     (kvm_read_c0_guest_entryhi
+                                                      (cop0) & ASID_MASK));
                        if (index < 0) {
                                kvm_err
                                    ("%s: get_user_failed for %p, vcpu: %p, ASID: %#lx\n",
index 9861c8669fab4047da01ad6af587ef948817d169..850821df924c32d069acbce03607b832c3a0c48b 100644 (file)
@@ -144,10 +144,6 @@ static int gptu_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Failed to get resource\n");
-               return -ENOMEM;
-       }
 
        /* remap gptu register range */
        gptu_membase = devm_ioremap_resource(&pdev->dev, res);
@@ -169,6 +165,8 @@ static int gptu_probe(struct platform_device *pdev)
        if (((gptu_r32(GPTU_ID) >> 8) & 0xff) != GPTU_MAGIC) {
                dev_err(&pdev->dev, "Failed to find magic\n");
                gptu_hwexit();
+               clk_disable(clk);
+               clk_put(clk);
                return -ENAVAIL;
        }
 
index 8a12d00908e024ab3559681955182f7f216c0155..32b9f21bfd8562f37d8e51e1ad23908c320ad3e8 100644 (file)
@@ -11,7 +11,6 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/tlbdebug.h>
-#include <asm/mmu_context.h>
 
 static inline const char *msk2str(unsigned int mask)
 {
@@ -56,7 +55,7 @@ static void dump_tlb(int first, int last)
        s_pagemask = read_c0_pagemask();
        s_entryhi = read_c0_entryhi();
        s_index = read_c0_index();
-       asid = ASID_MASK(s_entryhi);
+       asid = s_entryhi & 0xff;
 
        for (i = first; i <= last; i++) {
                write_c0_index(i);
@@ -86,7 +85,7 @@ static void dump_tlb(int first, int last)
 
                        printk("va=%0*lx asid=%02lx\n",
                               width, (entryhi & ~0x1fffUL),
-                              ASID_MASK(entryhi));
+                              entryhi & 0xff);
                        printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
                               width,
                               (entrylo0 << 6) & PAGE_MASK, c0,
index 8327698b99377e0e78c74a7bf0bef19e657fbd53..91615c2ef0cf969baeff215ca3d8a627e3851d2f 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/mm.h>
 
 #include <asm/mipsregs.h>
-#include <asm/mmu_context.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/tlbdebug.h>
@@ -22,7 +21,7 @@ static void dump_tlb(int first, int last)
        unsigned int asid;
        unsigned long entryhi, entrylo0;
 
-       asid = ASID_MASK(read_c0_entryhi());
+       asid = read_c0_entryhi() & 0xfc0;
 
        for (i = first; i <= last; i++) {
                write_c0_index(i<<8);
@@ -36,7 +35,7 @@ static void dump_tlb(int first, int last)
 
                /* Unused entries have a virtual address of KSEG0.  */
                if ((entryhi & 0xffffe000) != 0x80000000
-                   && (ASID_MASK(entryhi) == asid)) {
+                   && (entryhi & 0xfc0) == asid) {
                        /*
                         * Only print entries in use
                         */
@@ -45,7 +44,7 @@ static void dump_tlb(int first, int last)
                        printk("va=%08lx asid=%08lx"
                               "  [pa=%06lx n=%d d=%d v=%d g=%d]",
                               (entryhi & 0xffffe000),
-                              ASID_MASK(entryhi),
+                              entryhi & 0xfc0,
                               entrylo0 & PAGE_MASK,
                               (entrylo0 & (1 << 11)) ? 1 : 0,
                               (entrylo0 & (1 << 10)) ? 1 : 0,
index 35c8c64684941603f29c072478fd42b7401a7be8..65bfbb5d06f442efbd6601600097f94124cc171c 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 
+#include <asm/idle.h>
 #include <asm/reboot.h>
 
 #include <loongson.h>
index d4f610f9604a27296a685ea1455bbd18717b48be..547f34b69e4c06a471032ab588b8391e62f0cc39 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/io.h>
 #include <linux/pm.h>
+#include <asm/idle.h>
 #include <asm/reboot.h>
 
 #include <loongson1.h>
index 4a13c150f31b18d3317c9e0e7e12ffa39bb561e4..a63d1ed0827fefe36520b2d21877b5bd6a6767f4 100644 (file)
@@ -51,7 +51,7 @@ void local_flush_tlb_all(void)
 #endif
 
        local_irq_save(flags);
-       old_ctx = ASID_MASK(read_c0_entryhi());
+       old_ctx = read_c0_entryhi() & ASID_MASK;
        write_c0_entrylo0(0);
        entry = r3k_have_wired_reg ? read_c0_wired() : 8;
        for (; entry < current_cpu_data.tlbsize; entry++) {
@@ -87,13 +87,13 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 
 #ifdef DEBUG_TLB
                printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
-                       ASID_MASK(cpu_context(cpu, mm)), start, end);
+                       cpu_context(cpu, mm) & ASID_MASK, start, end);
 #endif
                local_irq_save(flags);
                size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
                if (size <= current_cpu_data.tlbsize) {
-                       int oldpid = ASID_MASK(read_c0_entryhi());
-                       int newpid = ASID_MASK(cpu_context(cpu, mm));
+                       int oldpid = read_c0_entryhi() & ASID_MASK;
+                       int newpid = cpu_context(cpu, mm) & ASID_MASK;
 
                        start &= PAGE_MASK;
                        end += PAGE_SIZE - 1;
@@ -166,10 +166,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 #ifdef DEBUG_TLB
                printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page);
 #endif
-               newpid = ASID_MASK(cpu_context(cpu, vma->vm_mm));
+               newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK;
                page &= PAGE_MASK;
                local_irq_save(flags);
-               oldpid = ASID_MASK(read_c0_entryhi());
+               oldpid = read_c0_entryhi() & ASID_MASK;
                write_c0_entryhi(page | newpid);
                BARRIER;
                tlb_probe();
@@ -197,10 +197,10 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
        if (current->active_mm != vma->vm_mm)
                return;
 
-       pid = ASID_MASK(read_c0_entryhi());
+       pid = read_c0_entryhi() & ASID_MASK;
 
 #ifdef DEBUG_TLB
-       if ((pid != ASID_MASK(cpu_context(cpu, vma->vm_mm))) || (cpu_context(cpu, vma->vm_mm) == 0)) {
+       if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) {
                printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
                       (cpu_context(cpu, vma->vm_mm)), pid);
        }
@@ -241,7 +241,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 
                local_irq_save(flags);
                /* Save old context and create impossible VPN2 value */
-               old_ctx = ASID_MASK(read_c0_entryhi());
+               old_ctx = read_c0_entryhi() & ASID_MASK;
                old_pagemask = read_c0_pagemask();
                w = read_c0_wired();
                write_c0_wired(w + 1);
@@ -264,7 +264,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 #endif
 
                local_irq_save(flags);
-               old_ctx = ASID_MASK(read_c0_entryhi());
+               old_ctx = read_c0_entryhi() & ASID_MASK;
                write_c0_entrylo0(entrylo0);
                write_c0_entryhi(entryhi);
                write_c0_index(wired);
index 09653b290d53356517607ac51388a09412e3d033..c643de4c473a8d67115c7f0d304ebe1dc1e8c4ce 100644 (file)
@@ -287,7 +287,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
 
        ENTER_CRITICAL(flags);
 
-       pid = ASID_MASK(read_c0_entryhi());
+       pid = read_c0_entryhi() & ASID_MASK;
        address &= (PAGE_MASK << 1);
        write_c0_entryhi(address | pid);
        pgdp = pgd_offset(vma->vm_mm, address);
index 122f9207f49e7f58871cda1bb681f73370fd1286..91c2499f806a25809259a0b9682667ce2d7f31d5 100644 (file)
@@ -195,7 +195,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
        if (current->active_mm != vma->vm_mm)
                return;
 
-       pid = ASID_MASK(read_c0_entryhi());
+       pid = read_c0_entryhi() & ASID_MASK;
 
        local_irq_save(flags);
        address &= PAGE_MASK;
index 4d46d37875765a3d3024bdee0d043fae9b7a23f7..ce9818eef7d392b569ea531a6064fea790458e3d 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/init.h>
 #include <linux/cache.h>
 
-#include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 #include <asm/war.h>
@@ -306,78 +305,6 @@ static struct uasm_reloc relocs[128] __cpuinitdata;
 static int check_for_high_segbits __cpuinitdata;
 #endif
 
-static void __cpuinit insn_fixup(unsigned int **start, unsigned int **stop,
-                                       unsigned int i_const)
-{
-       unsigned int **p;
-
-       for (p = start; p < stop; p++) {
-#ifndef CONFIG_CPU_MICROMIPS
-               unsigned int *ip;
-
-               ip = *p;
-               *ip = (*ip & 0xffff0000) | i_const;
-#else
-               unsigned short *ip;
-
-               ip = ((unsigned short *)((unsigned int)*p - 1));
-               if ((*ip & 0xf000) == 0x4000) {
-                       *ip &= 0xfff1;
-                       *ip |= (i_const << 1);
-               } else if ((*ip & 0xf000) == 0x6000) {
-                       *ip &= 0xfff1;
-                       *ip |= ((i_const >> 2) << 1);
-               } else {
-                       ip++;
-                       *ip = i_const;
-               }
-#endif
-               local_flush_icache_range((unsigned long)ip,
-                                        (unsigned long)ip + sizeof(*ip));
-       }
-}
-
-#define asid_insn_fixup(section, const)                                        \
-do {                                                                   \
-       extern unsigned int *__start_ ## section;                       \
-       extern unsigned int *__stop_ ## section;                        \
-       insn_fixup(&__start_ ## section, &__stop_ ## section, const);   \
-} while(0)
-
-/*
- * Caller is assumed to flush the caches before the first context switch.
- */
-static void __cpuinit setup_asid(unsigned int inc, unsigned int mask,
-                                unsigned int version_mask,
-                                unsigned int first_version)
-{
-       extern asmlinkage void handle_ri_rdhwr_vivt(void);
-       unsigned long *vivt_exc;
-
-#ifdef CONFIG_CPU_MICROMIPS
-       /*
-        * Worst case optimised microMIPS addiu instructions support
-        * only a 3-bit immediate value.
-        */
-       if(inc > 7)
-               panic("Invalid ASID increment value!");
-#endif
-       asid_insn_fixup(__asid_inc, inc);
-       asid_insn_fixup(__asid_mask, mask);
-       asid_insn_fixup(__asid_version_mask, version_mask);
-       asid_insn_fixup(__asid_first_version, first_version);
-
-       /* Patch up the 'handle_ri_rdhwr_vivt' handler. */
-       vivt_exc = (unsigned long *) &handle_ri_rdhwr_vivt;
-#ifdef CONFIG_CPU_MICROMIPS
-       vivt_exc = (unsigned long *)((unsigned long) vivt_exc - 1);
-#endif
-       vivt_exc++;
-       *vivt_exc = (*vivt_exc & ~mask) | mask;
-
-       current_cpu_data.asid_cache = first_version;
-}
-
 static int check_for_high_segbits __cpuinitdata;
 
 static unsigned int kscratch_used_mask __cpuinitdata;
@@ -2256,7 +2183,6 @@ void __cpuinit build_tlb_refill_handler(void)
        case CPU_TX3922:
        case CPU_TX3927:
 #ifndef CONFIG_MIPS_PGD_C0_CONTEXT
-               setup_asid(0x40, 0xfc0, 0xf000, ASID_FIRST_VERSION_R3000);
                if (cpu_has_local_ebase)
                        build_r3000_tlb_refill_handler();
                if (!run_once) {
@@ -2282,11 +2208,6 @@ void __cpuinit build_tlb_refill_handler(void)
                break;
 
        default:
-#ifndef CONFIG_MIPS_MT_SMTC
-               setup_asid(0x1, 0xff, 0xff00, ASID_FIRST_VERSION_R4000);
-#else
-               setup_asid(0x1, smtc_asid_mask, 0xff00, ASID_FIRST_VERSION_R4000);
-#endif
                if (!run_once) {
                        scratch_reg = allocate_kscratch();
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
index af319143b59187a4918805f737e2dcdb480845e7..eaa99d28cb8eddbf1fe0311740f22054bb4e15ad 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/pm.h>
 #include <linux/bootmem.h>
 
+#include <asm/idle.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/bootinfo.h>
index e3e094100e3e51f2ea879431f85a9512d84e22a4..89c8c1066632b5f2800c1a4f2ecaef212ac890cf 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/serial_8250.h>
 #include <linux/pm.h>
 
+#include <asm/idle.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/bootinfo.h>
index 0edb89a6351610480833ee81d5e996b45ee3ea45..1c98975316604aa27517afec87cb450bf459d6bd 100644 (file)
@@ -83,7 +83,7 @@ static inline unsigned char str2hexnum(unsigned char c)
        return 0; /* foo */
 }
 
-static inline int str2eaddr(unsigned char *ea, unsigned char *str)
+int str2eaddr(unsigned char *ea, unsigned char *str)
 {
        int index = 0;
        unsigned char num = 0;
index 1651cfdbfe7b1303c03b629171190e8df013ad16..396b2967ad856bb974da6ff8055d27037cd9b654 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cacheflush.h>
+#include <asm/idle.h>
 #include <asm/r4kcache.h>
 #include <asm/reboot.h>
 #include <asm/smp-ops.h>
index ef7da1e227e61309c990548fa6ed93b259fe0040..e3203d414fee331eecce025924b0a8e7c4cee362 100644 (file)
                        reg-shift = <2>;
                };
        };
+
+       usb@101c0000 {
+               compatible = "ralink,rt3050-usb", "snps,dwc2";
+               reg = <0x101c0000 40000>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <18>;
+
+               status = "disabled";
+       };
 };
index c18c9a84f4c4ee5794088f133332d3a391b834b7..0ac73ea281984909df89403d17fb82fd4e9f3ae4 100644 (file)
@@ -43,4 +43,8 @@
                        reg = <0x50000 0x7b0000>;
                };
        };
+
+       usb@101c0000 {
+               status = "ok";
+       };
 };
index 5364aabc21027951532bc5d0e7d97898344f701a..681e7f86c08000f29884ce369efafab86afe1b29 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <asm/bootinfo.h>
+#include <asm/idle.h>
 #include <asm/time.h>
 #include <asm/reboot.h>
 #include <asm/r4kcache.h>
index 70a3f90131d82af9d67bac9ff2d8d206812dde6b..d7f755833c3f43431b48f38b296da4df34d993e6 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpu.h>
+#include <asm/idle.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/reboot.h>
index cc5474b24f0657f6b51091d6f2779427a03d3e78..80beb188ed476ebb2775db8a89673bd1de95f631 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 
 #include <asm/cacheflush.h>
+#include <asm/idle.h>
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 
index cad060f288cf51e089bfb9cf7b6e879064bc0989..6507dabdd5ddc1a758e68f7476eb197fac9ec7b3 100644 (file)
@@ -245,7 +245,7 @@ config SMP
 
 config IRQSTACKS
        bool "Use separate kernel stacks when processing interrupts"
-       default n
+       default y
        help
          If you say Y here the kernel will use separate kernel stacks
          for handling hard and soft interrupts.  This can help avoid
index 2f967cc6649e0cab325136624a614af4f0784281..197690068f88fb1087c0e6d77074a9fd81f37602 100644 (file)
@@ -23,24 +23,21 @@ NM          = sh $(srctree)/arch/parisc/nm
 CHECKFLAGS     += -D__hppa__=1
 LIBGCC         = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
-MACHINE                := $(shell uname -m)
-NATIVE         := $(if $(filter parisc%,$(MACHINE)),1,0)
-
 ifdef CONFIG_64BIT
 UTS_MACHINE    := parisc64
 CHECKFLAGS     += -D__LP64__=1 -m64
-WIDTH          := 64
+CC_ARCHES      = hppa64
 else # 32-bit
-WIDTH          :=
+CC_ARCHES      = hppa hppa2.0 hppa1.1
 endif
 
-# attempt to help out folks who are cross-compiling
-ifeq ($(NATIVE),1)
-CROSS_COMPILE  := hppa$(WIDTH)-linux-
-else
- ifeq ($(CROSS_COMPILE),)
- CROSS_COMPILE := hppa$(WIDTH)-linux-gnu-
- endif
+ifneq ($(SUBARCH),$(UTS_MACHINE))
+       ifeq ($(CROSS_COMPILE),)
+               CC_SUFFIXES = linux linux-gnu unknown-linux-gnu
+               CROSS_COMPILE := $(call cc-cross-prefix, \
+                       $(foreach a,$(CC_ARCHES), \
+                       $(foreach s,$(CC_SUFFIXES),$(a)-$(s)-)))
      endif
 endif
 
 OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
index 12373c4dababec920c0ec42f120064011567d4b6..c19f7138ba48b91dfffe1046da708782057cc779 100644 (file)
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+#ifdef CONFIG_IRQSTACKS
+#define __ARCH_HAS_DO_SOFTIRQ
+#endif
+
 typedef struct {
        unsigned int __softirq_pending;
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        unsigned int kernel_stack_usage;
+#ifdef CONFIG_IRQSTACKS
+       unsigned int irq_stack_usage;
+       unsigned int irq_stack_counter;
+#endif
 #endif
 #ifdef CONFIG_SMP
        unsigned int irq_resched_count;
@@ -28,6 +36,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 #define __ARCH_IRQ_STAT
 #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
 #define inc_irq_stat(member)   this_cpu_inc(irq_stat.member)
+#define __inc_irq_stat(member) __this_cpu_inc(irq_stat.member)
 #define local_softirq_pending()        this_cpu_read(irq_stat.__softirq_pending)
 
 #define __ARCH_SET_SOFTIRQ_PENDING
index 064015547d1e32be0a968ba946bc54f8db362895..cfbc43929cf6d20e2e53df0be823b8166ff576c0 100644 (file)
  */
 #ifdef __KERNEL__
 
+#include <linux/spinlock_types.h>
+
 #define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
 
 union irq_stack_union {
        unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
+       raw_spinlock_t lock;
 };
 
 DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
index 4bb96ad9b0b14ddd1cb066bc21b304d861059f38..ae27cb6ce19ab012e45c8eeadc77dec77846c526 100644 (file)
        L2_ptep         \pgd,\pte,\index,\va,\fault
        .endm
 
+       /* Acquire pa_dbit_lock lock. */
+       .macro          dbit_lock       spc,tmp,tmp1
+#ifdef CONFIG_SMP
+       cmpib,COND(=),n 0,\spc,2f
+       load32          PA(pa_dbit_lock),\tmp
+1:     LDCW            0(\tmp),\tmp1
+       cmpib,COND(=)   0,\tmp1,1b
+       nop
+2:
+#endif
+       .endm
+
+       /* Release pa_dbit_lock lock without reloading lock address. */
+       .macro          dbit_unlock0    spc,tmp
+#ifdef CONFIG_SMP
+       or,COND(=)      %r0,\spc,%r0
+       stw             \spc,0(\tmp)
+#endif
+       .endm
+
+       /* Release pa_dbit_lock lock. */
+       .macro          dbit_unlock1    spc,tmp
+#ifdef CONFIG_SMP
+       load32          PA(pa_dbit_lock),\tmp
+       dbit_unlock0    \spc,\tmp
+#endif
+       .endm
+
        /* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
         * don't needlessly dirty the cache line if it was already set */
-       .macro          update_ptep     ptep,pte,tmp,tmp1
+       .macro          update_ptep     spc,ptep,pte,tmp,tmp1
+#ifdef CONFIG_SMP
+       or,COND(=)      %r0,\spc,%r0
+       LDREG           0(\ptep),\pte
+#endif
        ldi             _PAGE_ACCESSED,\tmp1
        or              \tmp1,\pte,\tmp
        and,COND(<>)    \tmp1,\pte,%r0
 
        /* Set the dirty bit (and accessed bit).  No need to be
         * clever, this is only used from the dirty fault */
-       .macro          update_dirty    ptep,pte,tmp
+       .macro          update_dirty    spc,ptep,pte,tmp
+#ifdef CONFIG_SMP
+       or,COND(=)      %r0,\spc,%r0
+       LDREG           0(\ptep),\pte
+#endif
        ldi             _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
        or              \tmp,\pte,\pte
        STREG           \pte,0(\ptep)
@@ -1111,11 +1147,13 @@ dtlb_miss_20w:
 
        L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
        
        idtlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1135,11 +1173,13 @@ nadtlb_miss_20w:
 
        L3_ptep         ptp,pte,t0,va,nadtlb_check_alias_20w
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
 
        idtlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1161,7 +1201,8 @@ dtlb_miss_11:
 
        L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb_11      spc,pte,prot
 
@@ -1172,6 +1213,7 @@ dtlb_miss_11:
        idtlbp          prot,(%sr1,va)
 
        mtsp            t0, %sr1        /* Restore sr1 */
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1192,7 +1234,8 @@ nadtlb_miss_11:
 
        L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_11
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb_11      spc,pte,prot
 
@@ -1204,6 +1247,7 @@ nadtlb_miss_11:
        idtlbp          prot,(%sr1,va)
 
        mtsp            t0, %sr1        /* Restore sr1 */
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1224,13 +1268,15 @@ dtlb_miss_20:
 
        L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
 
        f_extend        pte,t0
 
        idtlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1250,13 +1296,15 @@ nadtlb_miss_20:
 
        L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_20
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
 
        f_extend        pte,t0
        
         idtlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1357,11 +1405,13 @@ itlb_miss_20w:
 
        L3_ptep         ptp,pte,t0,va,itlb_fault
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
        
        iitlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1379,11 +1429,13 @@ naitlb_miss_20w:
 
        L3_ptep         ptp,pte,t0,va,naitlb_check_alias_20w
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
 
        iitlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1405,7 +1457,8 @@ itlb_miss_11:
 
        L2_ptep         ptp,pte,t0,va,itlb_fault
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb_11      spc,pte,prot
 
@@ -1416,6 +1469,7 @@ itlb_miss_11:
        iitlbp          prot,(%sr1,va)
 
        mtsp            t0, %sr1        /* Restore sr1 */
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1427,7 +1481,8 @@ naitlb_miss_11:
 
        L2_ptep         ptp,pte,t0,va,naitlb_check_alias_11
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb_11      spc,pte,prot
 
@@ -1438,6 +1493,7 @@ naitlb_miss_11:
        iitlbp          prot,(%sr1,va)
 
        mtsp            t0, %sr1        /* Restore sr1 */
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1459,13 +1515,15 @@ itlb_miss_20:
 
        L2_ptep         ptp,pte,t0,va,itlb_fault
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
 
        f_extend        pte,t0  
 
        iitlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1477,13 +1535,15 @@ naitlb_miss_20:
 
        L2_ptep         ptp,pte,t0,va,naitlb_check_alias_20
 
-       update_ptep     ptp,pte,t0,t1
+       dbit_lock       spc,t0,t1
+       update_ptep     spc,ptp,pte,t0,t1
 
        make_insert_tlb spc,pte,prot
 
        f_extend        pte,t0
 
        iitlbt          pte,prot
+       dbit_unlock1    spc,t0
 
        rfir
        nop
@@ -1507,29 +1567,13 @@ dbit_trap_20w:
 
        L3_ptep         ptp,pte,t0,va,dbit_fault
 
-#ifdef CONFIG_SMP
-       cmpib,COND(=),n        0,spc,dbit_nolock_20w
-       load32          PA(pa_dbit_lock),t0
-
-dbit_spin_20w:
-       LDCW            0(t0),t1
-       cmpib,COND(=)         0,t1,dbit_spin_20w
-       nop
-
-dbit_nolock_20w:
-#endif
-       update_dirty    ptp,pte,t1
+       dbit_lock       spc,t0,t1
+       update_dirty    spc,ptp,pte,t1
 
        make_insert_tlb spc,pte,prot
                
        idtlbt          pte,prot
-#ifdef CONFIG_SMP
-       cmpib,COND(=),n        0,spc,dbit_nounlock_20w
-       ldi             1,t1
-       stw             t1,0(t0)
-
-dbit_nounlock_20w:
-#endif
+       dbit_unlock0    spc,t0
 
        rfir
        nop
@@ -1543,18 +1587,8 @@ dbit_trap_11:
 
        L2_ptep         ptp,pte,t0,va,dbit_fault
 
-#ifdef CONFIG_SMP
-       cmpib,COND(=),n        0,spc,dbit_nolock_11
-       load32          PA(pa_dbit_lock),t0
-
-dbit_spin_11:
-       LDCW            0(t0),t1
-       cmpib,=         0,t1,dbit_spin_11
-       nop
-
-dbit_nolock_11:
-#endif
-       update_dirty    ptp,pte,t1
+       dbit_lock       spc,t0,t1
+       update_dirty    spc,ptp,pte,t1
 
        make_insert_tlb_11      spc,pte,prot
 
@@ -1565,13 +1599,7 @@ dbit_nolock_11:
        idtlbp          prot,(%sr1,va)
 
        mtsp            t1, %sr1     /* Restore sr1 */
-#ifdef CONFIG_SMP
-       cmpib,COND(=),n        0,spc,dbit_nounlock_11
-       ldi             1,t1
-       stw             t1,0(t0)
-
-dbit_nounlock_11:
-#endif
+       dbit_unlock0    spc,t0
 
        rfir
        nop
@@ -1583,32 +1611,15 @@ dbit_trap_20:
 
        L2_ptep         ptp,pte,t0,va,dbit_fault
 
-#ifdef CONFIG_SMP
-       cmpib,COND(=),n        0,spc,dbit_nolock_20
-       load32          PA(pa_dbit_lock),t0
-
-dbit_spin_20:
-       LDCW            0(t0),t1
-       cmpib,=         0,t1,dbit_spin_20
-       nop
-
-dbit_nolock_20:
-#endif
-       update_dirty    ptp,pte,t1
+       dbit_lock       spc,t0,t1
+       update_dirty    spc,ptp,pte,t1
 
        make_insert_tlb spc,pte,prot
 
        f_extend        pte,t1
        
         idtlbt          pte,prot
-
-#ifdef CONFIG_SMP
-       cmpib,COND(=),n        0,spc,dbit_nounlock_20
-       ldi             1,t1
-       stw             t1,0(t0)
-
-dbit_nounlock_20:
-#endif
+       dbit_unlock0    spc,t0
 
        rfir
        nop
index e255db0bb7619cf92e8581cae017f01f20c4718d..55237a70e19773940f67e8e62ac7d43c60f36608 100644 (file)
@@ -166,22 +166,32 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        seq_printf(p, "%*s: ", prec, "STK");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage);
-       seq_printf(p, "  Kernel stack usage\n");
+       seq_puts(p, "  Kernel stack usage\n");
+# ifdef CONFIG_IRQSTACKS
+       seq_printf(p, "%*s: ", prec, "IST");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage);
+       seq_puts(p, "  Interrupt stack usage\n");
+       seq_printf(p, "%*s: ", prec, "ISC");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter);
+       seq_puts(p, "  Interrupt stack usage counter\n");
+# endif
 #endif
 #ifdef CONFIG_SMP
        seq_printf(p, "%*s: ", prec, "RES");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
-       seq_printf(p, "  Rescheduling interrupts\n");
+       seq_puts(p, "  Rescheduling interrupts\n");
        seq_printf(p, "%*s: ", prec, "CAL");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
-       seq_printf(p, "  Function call interrupts\n");
+       seq_puts(p, "  Function call interrupts\n");
 #endif
        seq_printf(p, "%*s: ", prec, "TLB");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
-       seq_printf(p, "  TLB shootdowns\n");
+       seq_puts(p, "  TLB shootdowns\n");
        return 0;
 }
 
@@ -378,6 +388,7 @@ static inline void stack_overflow_check(struct pt_regs *regs)
        unsigned long sp = regs->gr[30];
        unsigned long stack_usage;
        unsigned int *last_usage;
+       int cpu = smp_processor_id();
 
        /* if sr7 != 0, we interrupted a userspace process which we do not want
         * to check for stack overflow. We will only check the kernel stack. */
@@ -386,7 +397,31 @@ static inline void stack_overflow_check(struct pt_regs *regs)
 
        /* calculate kernel stack usage */
        stack_usage = sp - stack_start;
-       last_usage = &per_cpu(irq_stat.kernel_stack_usage, smp_processor_id());
+#ifdef CONFIG_IRQSTACKS
+       if (likely(stack_usage <= THREAD_SIZE))
+               goto check_kernel_stack; /* found kernel stack */
+
+       /* check irq stack usage */
+       stack_start = (unsigned long) &per_cpu(irq_stack_union, cpu).stack;
+       stack_usage = sp - stack_start;
+
+       last_usage = &per_cpu(irq_stat.irq_stack_usage, cpu);
+       if (unlikely(stack_usage > *last_usage))
+               *last_usage = stack_usage;
+
+       if (likely(stack_usage < (IRQ_STACK_SIZE - STACK_MARGIN)))
+               return;
+
+       pr_emerg("stackcheck: %s will most likely overflow irq stack "
+                "(sp:%lx, stk bottom-top:%lx-%lx)\n",
+               current->comm, sp, stack_start, stack_start + IRQ_STACK_SIZE);
+       goto panic_check;
+
+check_kernel_stack:
+#endif
+
+       /* check kernel stack usage */
+       last_usage = &per_cpu(irq_stat.kernel_stack_usage, cpu);
 
        if (unlikely(stack_usage > *last_usage))
                *last_usage = stack_usage;
@@ -398,31 +433,69 @@ static inline void stack_overflow_check(struct pt_regs *regs)
                 "(sp:%lx, stk bottom-top:%lx-%lx)\n",
                current->comm, sp, stack_start, stack_start + THREAD_SIZE);
 
+#ifdef CONFIG_IRQSTACKS
+panic_check:
+#endif
        if (sysctl_panic_on_stackoverflow)
                panic("low stack detected by irq handler - check messages\n");
 #endif
 }
 
 #ifdef CONFIG_IRQSTACKS
-DEFINE_PER_CPU(union irq_stack_union, irq_stack_union);
+DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
+               .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock)
+       };
 
 static void execute_on_irq_stack(void *func, unsigned long param1)
 {
-       unsigned long *irq_stack_start;
+       union irq_stack_union *union_ptr;
        unsigned long irq_stack;
-       int cpu = smp_processor_id();
+       raw_spinlock_t *irq_stack_in_use;
 
-       irq_stack_start = &per_cpu(irq_stack_union, cpu).stack[0];
-       irq_stack = (unsigned long) irq_stack_start;
-       irq_stack = ALIGN(irq_stack, 16); /* align for stack frame usage */
+       union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
+       irq_stack = (unsigned long) &union_ptr->stack;
+       irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock),
+                        64); /* align for stack frame usage */
 
-       BUG_ON(*irq_stack_start); /* report bug if we were called recursive. */
-       *irq_stack_start = 1;
+       /* We may be called recursive. If we are already using the irq stack,
+        * just continue to use it. Use spinlocks to serialize
+        * the irq stack usage.
+        */
+       irq_stack_in_use = &union_ptr->lock;
+       if (!raw_spin_trylock(irq_stack_in_use)) {
+               void (*direct_call)(unsigned long p1) = func;
+
+               /* We are using the IRQ stack already.
+                * Do direct call on current stack. */
+               direct_call(param1);
+               return;
+       }
 
        /* This is where we switch to the IRQ stack. */
        call_on_stack(param1, func, irq_stack);
 
-       *irq_stack_start = 0;
+       __inc_irq_stat(irq_stack_counter);
+
+       /* free up irq stack usage. */
+       do_raw_spin_unlock(irq_stack_in_use);
+}
+
+asmlinkage void do_softirq(void)
+{
+       __u32 pending;
+       unsigned long flags;
+
+       if (in_interrupt())
+               return;
+
+       local_irq_save(flags);
+
+       pending = local_softirq_pending();
+
+       if (pending)
+               execute_on_irq_stack(__do_softirq, 0);
+
+       local_irq_restore(flags);
 }
 #endif /* CONFIG_IRQSTACKS */
 
index ce939ac8622b84b7278f9e979e68a56354267adf..1c965642068b48d6b7102a5b6adb365f321f73e6 100644 (file)
@@ -1069,7 +1069,7 @@ void flush_tlb_all(void)
 {
        int do_recycle;
 
-       inc_irq_stat(irq_tlb_count);
+       __inc_irq_stat(irq_tlb_count);
        do_recycle = 0;
        spin_lock(&sid_lock);
        if (dirty_space_ids > RECYCLE_THRESHOLD) {
@@ -1090,7 +1090,7 @@ void flush_tlb_all(void)
 #else
 void flush_tlb_all(void)
 {
-       inc_irq_stat(irq_tlb_count);
+       __inc_irq_stat(irq_tlb_count);
        spin_lock(&sid_lock);
        flush_tlb_all_local(NULL);
        recycle_sids();
index 5416e28a753871ec02c75503e9583e8ff5abfbe9..863d877e0b5f7444f31239a2412bdec68165abea 100644 (file)
@@ -262,8 +262,31 @@ config PPC_EARLY_DEBUG_OPAL_HVSI
          Select this to enable early debugging for the PowerNV platform
          using an "hvsi" console
 
+config PPC_EARLY_DEBUG_MEMCONS
+       bool "In memory console"
+       help
+         Select this to enable early debugging using an in memory console.
+         This console provides input and output buffers stored within the
+         kernel BSS and should be safe to select on any system. A debugger
+         can then be used to read kernel output or send input to the console.
 endchoice
 
+config PPC_MEMCONS_OUTPUT_SIZE
+       int "In memory console output buffer size"
+       depends on PPC_EARLY_DEBUG_MEMCONS
+       default 4096
+       help
+         Selects the size of the output buffer (in bytes) of the in memory
+         console.
+
+config PPC_MEMCONS_INPUT_SIZE
+       int "In memory console input buffer size"
+       depends on PPC_EARLY_DEBUG_MEMCONS
+       default 128
+       help
+         Selects the size of the input buffer (in bytes) of the in memory
+         console.
+
 config PPC_EARLY_DEBUG_OPAL
        def_bool y
        depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
index f79196232917140f0afef3085f53d63e32f5e5d7..139a8308070c8fee09665b81d168ef092e584d3e 100644 (file)
@@ -136,7 +136,6 @@ CONFIG_HID_SMARTJOYPLUS=m
 CONFIG_USB_HIDDEV=y
 CONFIG_USB=m
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=m
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
diff --git a/arch/powerpc/include/asm/context_tracking.h b/arch/powerpc/include/asm/context_tracking.h
new file mode 100644 (file)
index 0000000..b6f5a33
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _ASM_POWERPC_CONTEXT_TRACKING_H
+#define _ASM_POWERPC_CONTEXT_TRACKING_H
+
+#ifdef CONFIG_CONTEXT_TRACKING
+#define SCHEDULE_USER bl       .schedule_user
+#else
+#define SCHEDULE_USER bl       .schedule
+#endif
+
+#endif
index 0df54646f9689d867ff86d3b8f515af2dfa1bfe6..681bc0314b6bb999070d59a3f86955d2bf42dd15 100644 (file)
@@ -52,6 +52,7 @@
 #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000)
 #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000)
 #define FW_FEATURE_PRRN                ASM_CONST(0x0000000200000000)
+#define FW_FEATURE_OPALv3      ASM_CONST(0x0000000400000000)
 
 #ifndef __ASSEMBLY__
 
@@ -69,7 +70,8 @@ enum {
                FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
                FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN,
        FW_FEATURE_PSERIES_ALWAYS = 0,
-       FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2,
+       FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2 |
+               FW_FEATURE_OPALv3,
        FW_FEATURE_POWERNV_ALWAYS = 0,
        FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
        FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
index d615b28dda82ff7e9afed97ddf51815f5d170cca..ba713f166fa57fb2f9b08002a8a5cf8c0162d196 100644 (file)
@@ -96,11 +96,12 @@ static inline bool arch_irqs_disabled(void)
 #endif
 
 #define hard_irq_disable()     do {                    \
+       u8 _was_enabled = get_paca()->soft_enabled;     \
        __hard_irq_disable();                           \
-       if (local_paca->soft_enabled)                   \
-               trace_hardirqs_off();                   \
        get_paca()->soft_enabled = 0;                   \
        get_paca()->irq_happened |= PACA_IRQ_HARD_DIS;  \
+       if (_was_enabled)                               \
+               trace_hardirqs_off();                   \
 } while(0)
 
 static inline bool lazy_irq_pending(void)
index b6c8b58b1d764c5d1d8255fbc62df86b6b88c83e..cbb9305ab15affb2035f723be351e3a7431e2955 100644 (file)
@@ -243,7 +243,8 @@ enum OpalMCE_TlbErrorType {
 
 enum OpalThreadStatus {
        OPAL_THREAD_INACTIVE = 0x0,
-       OPAL_THREAD_STARTED = 0x1
+       OPAL_THREAD_STARTED = 0x1,
+       OPAL_THREAD_UNAVAILABLE = 0x2 /* opal-v3 */
 };
 
 enum OpalPciBusCompare {
@@ -563,6 +564,8 @@ extern void opal_nvram_init(void);
 
 extern int opal_machine_check(struct pt_regs *regs);
 
+extern void opal_shutdown(void);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_H */
index 91acb12bac9280a2a8068cc9cd46176f5cbd1243..b66ae722a8e9c2d9aacb9ef7eb49e553d9ad9dde 100644 (file)
@@ -186,7 +186,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
 
 static inline pgtable_t pmd_pgtable(pmd_t pmd)
 {
-       return (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE);
+       return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS);
 }
 
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
index 3e13e23e4fdf8a4e3fc84e07ef091cffdfc0492f..d836d945068d032cb072013cf027f7a43e36b88a 100644 (file)
@@ -47,7 +47,7 @@
  * generic accessors and iterators here
  */
 #define __real_pte(e,p)        ((real_pte_t) { \
-                       (e), ((e) & _PAGE_COMBO) ? \
+                       (e), (pte_val(e) & _PAGE_COMBO) ? \
                                (pte_val(*((p) + PTRS_PER_PTE))) : 0 })
 #define __rpte_to_hidx(r,index)        ((pte_val((r).pte) & _PAGE_COMBO) ? \
         (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf))
index a8bc2bb4adc97147b8a4d95b07ea54bef1016567..34fd70488d83f09ebb947680763ddbcf4ce62fad 100644 (file)
@@ -264,6 +264,8 @@ extern void rtas_progress(char *s, unsigned short hex);
 extern void rtas_initialize(void);
 extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
 extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
+extern int rtas_online_cpus_mask(cpumask_var_t cpus);
+extern int rtas_offline_cpus_mask(cpumask_var_t cpus);
 extern int rtas_ibm_suspend_me(struct rtas_args *);
 
 struct rtc_time;
index 8ceea14d6fe44a20d0d807e28a4ca63477f18863..ba7b1973866e1933486f47ed59e3aa0efe799f34 100644 (file)
@@ -97,7 +97,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_PERFMON_CTXSW      6       /* perfmon needs ctxsw calls */
 #define TIF_SYSCALL_AUDIT      7       /* syscall auditing active */
 #define TIF_SINGLESTEP         8       /* singlestepping active */
-#define TIF_MEMDIE             9       /* is terminating due to OOM killer */
+#define TIF_NOHZ               9       /* in adaptive nohz mode */
 #define TIF_SECCOMP            10      /* secure computing */
 #define TIF_RESTOREALL         11      /* Restore all regs (implies NOERROR) */
 #define TIF_NOERROR            12      /* Force successful syscall return */
@@ -106,6 +106,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SYSCALL_TRACEPOINT 15      /* syscall tracepoint instrumentation */
 #define TIF_EMULATE_STACK_STORE        16      /* Is an instruction emulation
                                                for stack store? */
+#define TIF_MEMDIE             17      /* is terminating due to OOM killer */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -124,8 +125,10 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_UPROBE            (1<<TIF_UPROBE)
 #define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 #define _TIF_EMULATE_STACK_STORE       (1<<TIF_EMULATE_STACK_STORE)
+#define _TIF_NOHZ              (1<<TIF_NOHZ)
 #define _TIF_SYSCALL_T_OR_A    (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
-                                _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
+                                _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \
+                                _TIF_NOHZ)
 
 #define _TIF_USER_WORK_MASK    (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
                                 _TIF_NOTIFY_RESUME | _TIF_UPROBE)
index 5a7510e9d09d3865619b7a874efa7584074b5f7a..dc590919f8eb370d1568d54f7c002d58f63b2dad 100644 (file)
@@ -52,6 +52,7 @@ extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
 extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_memcons(void);
 extern void __init udbg_init_ehv_bc(void);
 extern void __init udbg_init_ps3gelic(void);
 extern void __init udbg_init_debug_opal_raw(void);
index e514de57a125333a4ce174cb399070b6cc62e3b4..d22e73e4618b7924879517f1f59cb99dcd63b43e 100644 (file)
@@ -439,8 +439,6 @@ ret_from_fork:
 ret_from_kernel_thread:
        REST_NVGPRS(r1)
        bl      schedule_tail
-       li      r3,0
-       stw     r3,0(r1)
        mtlr    r14
        mr      r3,r15
        PPC440EP_ERR42
index 915fbb4fc2fe4e7534dbf78eb39317013b03b014..51cfb8fc301f1299299bcc49edb12c7f9bc57eab 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/irqflags.h>
 #include <asm/ftrace.h>
 #include <asm/hw_irq.h>
+#include <asm/context_tracking.h>
 
 /*
  * System calls.
@@ -376,8 +377,6 @@ _GLOBAL(ret_from_fork)
 _GLOBAL(ret_from_kernel_thread)
        bl      .schedule_tail
        REST_NVGPRS(r1)
-       li      r3,0
-       std     r3,0(r1)
        ld      r14, 0(r14)
        mtlr    r14
        mr      r3,r15
@@ -634,7 +633,7 @@ _GLOBAL(ret_from_except_lite)
        andi.   r0,r4,_TIF_NEED_RESCHED
        beq     1f
        bl      .restore_interrupts
-       bl      .schedule
+       SCHEDULE_USER
        b       .ret_from_except_lite
 
 1:     bl      .save_nvgprs
index 42a756eec9ff7ea6a240bbef197e6519b1abd008..645170a07ada1da7abf4fddc814fcbaad9c071c9 100644 (file)
@@ -489,7 +489,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
         */
 
        mfspr   r14,SPRN_DBSR           /* check single-step/branch taken */
-       andis.  r15,r14,DBSR_IC@h
+       andis.  r15,r14,(DBSR_IC|DBSR_BT)@h
        beq+    1f
 
        LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
@@ -500,7 +500,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        bge+    cr1,1f
 
        /* here it looks like we got an inappropriate debug exception. */
-       lis     r14,DBSR_IC@h           /* clear the IC event */
+       lis     r14,(DBSR_IC|DBSR_BT)@h         /* clear the event */
        rlwinm  r11,r11,0,~MSR_DE       /* clear DE in the CSRR1 value */
        mtspr   SPRN_DBSR,r14
        mtspr   SPRN_CSRR1,r11
@@ -555,7 +555,7 @@ kernel_dbg_exc:
         */
 
        mfspr   r14,SPRN_DBSR           /* check single-step/branch taken */
-       andis.  r15,r14,DBSR_IC@h
+       andis.  r15,r14,(DBSR_IC|DBSR_BT)@h
        beq+    1f
 
        LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
@@ -566,7 +566,7 @@ kernel_dbg_exc:
        bge+    cr1,1f
 
        /* here it looks like we got an inappropriate debug exception. */
-       lis     r14,DBSR_IC@h           /* clear the IC event */
+       lis     r14,(DBSR_IC|DBSR_BT)@h         /* clear the event */
        rlwinm  r11,r11,0,~MSR_DE       /* clear DE in the DSRR1 value */
        mtspr   SPRN_DBSR,r14
        mtspr   SPRN_DSRR1,r11
index 466a2908bb634506e034cf63ab1da77b2036d95c..611acdf30096643a1d94bc3111b685e28d290453 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/cpu.h>
+#include <linux/hardirq.h>
 
 #include <asm/page.h>
 #include <asm/current.h>
@@ -335,10 +336,13 @@ void default_machine_kexec(struct kimage *image)
        pr_debug("kexec: Starting switchover sequence.\n");
 
        /* switch to a staticly allocated stack.  Based on irq stack code.
+        * We setup preempt_count to avoid using VMX in memcpy.
         * XXX: the task struct will likely be invalid once we do the copy!
         */
        kexec_stack.thread_info.task = current_thread_info()->task;
        kexec_stack.thread_info.flags = 0;
+       kexec_stack.thread_info.preempt_count = HARDIRQ_OFFSET;
+       kexec_stack.thread_info.cpu = current_thread_info()->cpu;
 
        /* We need a static PACA, too; copy this CPU's PACA over and switch to
         * it.  Also poison per_cpu_offset to catch anyone using non-static
index 19e096bd0e73d8b9a530159a4b9b440efc25403f..e469f30e6eeb88b4668e11a86d287e99b67aeae2 100644 (file)
@@ -657,6 +657,17 @@ _GLOBAL(__ucmpdi2)
        li      r3,2
        blr
 
+_GLOBAL(__bswapdi2)
+       rotlwi  r9,r4,8
+       rotlwi  r10,r3,8
+       rlwimi  r9,r4,24,0,7
+       rlwimi  r10,r3,24,0,7
+       rlwimi  r9,r4,24,16,23
+       rlwimi  r10,r3,24,16,23
+       mr      r3,r9
+       mr      r4,r10
+       blr
+
 _GLOBAL(abs)
        srawi   r4,r3,31
        xor     r3,r3,r4
index 5cfa8008693b83aaae96dd4f5d91a7e8190d234b..6820e45f557b73b848fda82c512332752b760dc2 100644 (file)
@@ -234,6 +234,17 @@ _GLOBAL(__flush_dcache_icache)
        isync
        blr
 
+_GLOBAL(__bswapdi2)
+       srdi    r8,r3,32
+       rlwinm  r7,r3,8,0xffffffff
+       rlwimi  r7,r3,24,0,7
+       rlwinm  r9,r8,8,0xffffffff
+       rlwimi  r7,r3,24,16,23
+       rlwimi  r9,r8,24,0,7
+       rlwimi  r9,r8,24,16,23
+       sldi    r7,r7,32
+       or      r3,r7,r9
+       blr
 
 #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
 /*
index f5c5c90799a763eb2a188316ea95e5d761ffe232..6053f037ef0af4368551d1e866769c39f6ea6143 100644 (file)
@@ -359,7 +359,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
                                      enum pci_mmap_state mmap_state,
                                      int write_combine)
 {
-       unsigned long prot = pgprot_val(protection);
 
        /* Write combine is always 0 on non-memory space mappings. On
         * memory space, if the user didn't pass 1, we check for a
@@ -376,9 +375,9 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
 
        /* XXX would be nice to have a way to ask for write-through */
        if (write_combine)
-               return pgprot_noncached_wc(prot);
+               return pgprot_noncached_wc(protection);
        else
-               return pgprot_noncached(prot);
+               return pgprot_noncached(protection);
 }
 
 /*
index 78b8766fd79e4605f96a103c6562ff62caa37c5e..c29666586998f27dd0f4d5aa8db721320a82cc2d 100644 (file)
@@ -143,7 +143,8 @@ EXPORT_SYMBOL(__lshrdi3);
 int __ucmpdi2(unsigned long long, unsigned long long);
 EXPORT_SYMBOL(__ucmpdi2);
 #endif
-
+long long __bswapdi2(long long);
+EXPORT_SYMBOL(__bswapdi2);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memmove);
index ceb4e7b62cf441ed6237499d11ef15cc6e2e4d50..a902723fdc69b0857d3d8658e32790614983c626 100644 (file)
@@ -339,6 +339,13 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
 
 static void prime_debug_regs(struct thread_struct *thread)
 {
+       /*
+        * We could have inherited MSR_DE from userspace, since
+        * it doesn't get cleared on exception entry.  Make sure
+        * MSR_DE is clear before we enable any debug events.
+        */
+       mtmsr(mfmsr() & ~MSR_DE);
+
        mtspr(SPRN_IAC1, thread->iac1);
        mtspr(SPRN_IAC2, thread->iac2);
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
@@ -971,6 +978,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
         * do some house keeping and then return from the fork or clone
         * system call, using the stack frame created above.
         */
+       ((unsigned long *)sp)[0] = 0;
        sp -= sizeof(struct pt_regs);
        kregs = (struct pt_regs *) sp;
        sp -= STACK_FRAME_OVERHEAD;
index 3b14d320e69f81737b447b59bcef4046edde0b5a..98c2fc198712aabe3f90055e24d653df604be78e 100644 (file)
@@ -32,6 +32,7 @@
 #include <trace/syscall.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/perf_event.h>
+#include <linux/context_tracking.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -1788,6 +1789,8 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 {
        long ret = 0;
 
+       user_exit();
+
        secure_computing_strict(regs->gpr[0]);
 
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
@@ -1832,4 +1835,6 @@ void do_syscall_trace_leave(struct pt_regs *regs)
        step = test_thread_flag(TIF_SINGLESTEP);
        if (step || test_thread_flag(TIF_SYSCALL_TRACE))
                tracehook_report_syscall_exit(regs, step);
+
+       user_enter();
 }
index 1fd6e7b2f390b41dac642f58e781baf735c04be4..52add6f3e201e1c196ea493f40a8fccc2cc922bc 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/delay.h>
+#include <linux/cpu.h>
 #include <linux/smp.h>
 #include <linux/completion.h>
 #include <linux/cpumask.h>
@@ -807,6 +808,95 @@ static void rtas_percpu_suspend_me(void *info)
        __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
 }
 
+enum rtas_cpu_state {
+       DOWN,
+       UP,
+};
+
+#ifndef CONFIG_SMP
+static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
+                               cpumask_var_t cpus)
+{
+       if (!cpumask_empty(cpus)) {
+               cpumask_clear(cpus);
+               return -EINVAL;
+       } else
+               return 0;
+}
+#else
+/* On return cpumask will be altered to indicate CPUs changed.
+ * CPUs with states changed will be set in the mask,
+ * CPUs with status unchanged will be unset in the mask. */
+static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
+                               cpumask_var_t cpus)
+{
+       int cpu;
+       int cpuret = 0;
+       int ret = 0;
+
+       if (cpumask_empty(cpus))
+               return 0;
+
+       for_each_cpu(cpu, cpus) {
+               switch (state) {
+               case DOWN:
+                       cpuret = cpu_down(cpu);
+                       break;
+               case UP:
+                       cpuret = cpu_up(cpu);
+                       break;
+               }
+               if (cpuret) {
+                       pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
+                                       __func__,
+                                       ((state == UP) ? "up" : "down"),
+                                       cpu, cpuret);
+                       if (!ret)
+                               ret = cpuret;
+                       if (state == UP) {
+                               /* clear bits for unchanged cpus, return */
+                               cpumask_shift_right(cpus, cpus, cpu);
+                               cpumask_shift_left(cpus, cpus, cpu);
+                               break;
+                       } else {
+                               /* clear bit for unchanged cpu, continue */
+                               cpumask_clear_cpu(cpu, cpus);
+                       }
+               }
+       }
+
+       return ret;
+}
+#endif
+
+int rtas_online_cpus_mask(cpumask_var_t cpus)
+{
+       int ret;
+
+       ret = rtas_cpu_state_change_mask(UP, cpus);
+
+       if (ret) {
+               cpumask_var_t tmp_mask;
+
+               if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY))
+                       return ret;
+
+               /* Use tmp_mask to preserve cpus mask from first failure */
+               cpumask_copy(tmp_mask, cpus);
+               rtas_offline_cpus_mask(tmp_mask);
+               free_cpumask_var(tmp_mask);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(rtas_online_cpus_mask);
+
+int rtas_offline_cpus_mask(cpumask_var_t cpus)
+{
+       return rtas_cpu_state_change_mask(DOWN, cpus);
+}
+EXPORT_SYMBOL(rtas_offline_cpus_mask);
+
 int rtas_ibm_suspend_me(struct rtas_args *args)
 {
        long state;
@@ -814,6 +904,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
        struct rtas_suspend_me_data data;
        DECLARE_COMPLETION_ONSTACK(done);
+       cpumask_var_t offline_mask;
+       int cpuret;
 
        if (!rtas_service_present("ibm,suspend-me"))
                return -ENOSYS;
@@ -837,11 +929,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
                return 0;
        }
 
+       if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
+               return -ENOMEM;
+
        atomic_set(&data.working, 0);
        atomic_set(&data.done, 0);
        atomic_set(&data.error, 0);
        data.token = rtas_token("ibm,suspend-me");
        data.complete = &done;
+
+       /* All present CPUs must be online */
+       cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
+       cpuret = rtas_online_cpus_mask(offline_mask);
+       if (cpuret) {
+               pr_err("%s: Could not bring present CPUs online.\n", __func__);
+               atomic_set(&data.error, cpuret);
+               goto out;
+       }
+
        stop_topology_update();
 
        /* Call function on all CPUs.  One of us will make the
@@ -857,6 +962,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
 
        start_topology_update();
 
+       /* Take down CPUs not online prior to suspend */
+       cpuret = rtas_offline_cpus_mask(offline_mask);
+       if (cpuret)
+               pr_warn("%s: Could not restore CPUs to offline state.\n",
+                               __func__);
+
+out:
+       free_cpumask_var(offline_mask);
        return atomic_read(&data.error);
 }
 #else /* CONFIG_PPC_PSERIES */
index 5b3022470126ce1787bb259c89b319d7f7e9770f..2f3cdb01506de3d7791712ecd6ffeaf1fcd36352 100644 (file)
@@ -89,6 +89,7 @@
 
 /* Array sizes */
 #define VALIDATE_BUF_SIZE 4096    
+#define VALIDATE_MSG_LEN  256
 #define RTAS_MSG_MAXLEN   64
 
 /* Quirk - RTAS requires 4k list length and block size */
@@ -466,7 +467,7 @@ static void validate_flash(struct rtas_validate_flash_t *args_buf)
 }
 
 static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, 
-                                  char *msg)
+                                  char *msg, int msglen)
 {
        int n;
 
@@ -474,7 +475,8 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf,
                n = sprintf(msg, "%d\n", args_buf->update_results);
                if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) ||
                    (args_buf->update_results == VALIDATE_TMP_UPDATE))
-                       n += sprintf(msg + n, "%s\n", args_buf->buf);
+                       n += snprintf(msg + n, msglen - n, "%s\n",
+                                       args_buf->buf);
        } else {
                n = sprintf(msg, "%d\n", args_buf->status);
        }
@@ -486,11 +488,11 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf,
 {
        struct rtas_validate_flash_t *const args_buf =
                &rtas_validate_flash_data;
-       char msg[RTAS_MSG_MAXLEN];
+       char msg[VALIDATE_MSG_LEN];
        int msglen;
 
        mutex_lock(&rtas_validate_flash_mutex);
-       msglen = get_validate_flash_msg(args_buf, msg);
+       msglen = get_validate_flash_msg(args_buf, msg, VALIDATE_MSG_LEN);
        mutex_unlock(&rtas_validate_flash_mutex);
 
        return simple_read_from_buffer(buf, count, ppos, msg, msglen);
index cf12eae02de5a694e2ba0e5298bfd8f082b688f9..577a8aa69c6e959dbc6e58d4555990822f23076b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/signal.h>
 #include <linux/uprobes.h>
 #include <linux/key.h>
+#include <linux/context_tracking.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -24,7 +25,7 @@
  * through debug.exception-trace sysctl.
  */
 
-int show_unhandled_signals = 0;
+int show_unhandled_signals = 1;
 
 /*
  * Allocate space for the signal frame
@@ -159,6 +160,8 @@ static int do_signal(struct pt_regs *regs)
 
 void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
 {
+       user_exit();
+
        if (thread_info_flags & _TIF_UPROBE)
                uprobe_notify_resume(regs);
 
@@ -169,4 +172,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
                clear_thread_flag(TIF_NOTIFY_RESUME);
                tracehook_notify_resume(regs);
        }
+
+       user_enter();
 }
index 83efa2f7d9266ced97726aa6b26c1739076a6ec1..a7a648f6b75047a72caa2280fb6f07ef9e5f2a16 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kdebug.h>
 #include <linux/debugfs.h>
 #include <linux/ratelimit.h>
+#include <linux/context_tracking.h>
 
 #include <asm/emulated_ops.h>
 #include <asm/pgtable.h>
@@ -667,6 +668,7 @@ int machine_check_generic(struct pt_regs *regs)
 
 void machine_check_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
        int recover = 0;
 
        __get_cpu_var(irq_stat).mce_exceptions++;
@@ -683,7 +685,7 @@ void machine_check_exception(struct pt_regs *regs)
                recover = cur_cpu_spec->machine_check(regs);
 
        if (recover > 0)
-               return;
+               goto bail;
 
 #if defined(CONFIG_8xx) && defined(CONFIG_PCI)
        /* the qspan pci read routines can cause machine checks -- Cort
@@ -693,20 +695,23 @@ void machine_check_exception(struct pt_regs *regs)
         * -- BenH
         */
        bad_page_fault(regs, regs->dar, SIGBUS);
-       return;
+       goto bail;
 #endif
 
        if (debugger_fault_handler(regs))
-               return;
+               goto bail;
 
        if (check_io_access(regs))
-               return;
+               goto bail;
 
        die("Machine check", regs, SIGBUS);
 
        /* Must die if the interrupt is not recoverable */
        if (!(regs->msr & MSR_RI))
                panic("Unrecoverable Machine check");
+
+bail:
+       exception_exit(prev_state);
 }
 
 void SMIException(struct pt_regs *regs)
@@ -716,20 +721,29 @@ void SMIException(struct pt_regs *regs)
 
 void unknown_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
+
        printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
               regs->nip, regs->msr, regs->trap);
 
        _exception(SIGTRAP, regs, 0, 0);
+
+       exception_exit(prev_state);
 }
 
 void instruction_breakpoint_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
+
        if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
                                        5, SIGTRAP) == NOTIFY_STOP)
-               return;
+               goto bail;
        if (debugger_iabr_match(regs))
-               return;
+               goto bail;
        _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+
+bail:
+       exception_exit(prev_state);
 }
 
 void RunModeException(struct pt_regs *regs)
@@ -739,15 +753,20 @@ void RunModeException(struct pt_regs *regs)
 
 void __kprobes single_step_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
+
        clear_single_step(regs);
 
        if (notify_die(DIE_SSTEP, "single_step", regs, 5,
                                        5, SIGTRAP) == NOTIFY_STOP)
-               return;
+               goto bail;
        if (debugger_sstep(regs))
-               return;
+               goto bail;
 
        _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+
+bail:
+       exception_exit(prev_state);
 }
 
 /*
@@ -1005,6 +1024,7 @@ int is_valid_bugaddr(unsigned long addr)
 
 void __kprobes program_check_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
        unsigned int reason = get_reason(regs);
        extern int do_mathemu(struct pt_regs *regs);
 
@@ -1014,26 +1034,26 @@ void __kprobes program_check_exception(struct pt_regs *regs)
        if (reason & REASON_FP) {
                /* IEEE FP exception */
                parse_fpe(regs);
-               return;
+               goto bail;
        }
        if (reason & REASON_TRAP) {
                /* Debugger is first in line to stop recursive faults in
                 * rcu_lock, notify_die, or atomic_notifier_call_chain */
                if (debugger_bpt(regs))
-                       return;
+                       goto bail;
 
                /* trap exception */
                if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
                                == NOTIFY_STOP)
-                       return;
+                       goto bail;
 
                if (!(regs->msr & MSR_PR) &&  /* not user-mode */
                    report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
                        regs->nip += 4;
-                       return;
+                       goto bail;
                }
                _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-               return;
+               goto bail;
        }
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        if (reason & REASON_TM) {
@@ -1049,7 +1069,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
                if (!user_mode(regs) &&
                    report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
                        regs->nip += 4;
-                       return;
+                       goto bail;
                }
                /* If usermode caused this, it's done something illegal and
                 * gets a SIGILL slap on the wrist.  We call it an illegal
@@ -1059,7 +1079,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
                 */
                if (user_mode(regs)) {
                        _exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
-                       return;
+                       goto bail;
                } else {
                        printk(KERN_EMERG "Unexpected TM Bad Thing exception "
                               "at %lx (msr 0x%x)\n", regs->nip, reason);
@@ -1083,16 +1103,16 @@ void __kprobes program_check_exception(struct pt_regs *regs)
        switch (do_mathemu(regs)) {
        case 0:
                emulate_single_step(regs);
-               return;
+               goto bail;
        case 1: {
                        int code = 0;
                        code = __parse_fpscr(current->thread.fpscr.val);
                        _exception(SIGFPE, regs, code, regs->nip);
-                       return;
+                       goto bail;
                }
        case -EFAULT:
                _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
-               return;
+               goto bail;
        }
        /* fall through on any other errors */
 #endif /* CONFIG_MATH_EMULATION */
@@ -1103,10 +1123,10 @@ void __kprobes program_check_exception(struct pt_regs *regs)
                case 0:
                        regs->nip += 4;
                        emulate_single_step(regs);
-                       return;
+                       goto bail;
                case -EFAULT:
                        _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
-                       return;
+                       goto bail;
                }
        }
 
@@ -1114,10 +1134,14 @@ void __kprobes program_check_exception(struct pt_regs *regs)
                _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
        else
                _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+
+bail:
+       exception_exit(prev_state);
 }
 
 void alignment_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
        int sig, code, fixed = 0;
 
        /* We restore the interrupt state now */
@@ -1131,7 +1155,7 @@ void alignment_exception(struct pt_regs *regs)
        if (fixed == 1) {
                regs->nip += 4; /* skip over emulated instruction */
                emulate_single_step(regs);
-               return;
+               goto bail;
        }
 
        /* Operand address was bad */
@@ -1146,6 +1170,9 @@ void alignment_exception(struct pt_regs *regs)
                _exception(sig, regs, code, regs->dar);
        else
                bad_page_fault(regs, regs->dar, sig);
+
+bail:
+       exception_exit(prev_state);
 }
 
 void StackOverflow(struct pt_regs *regs)
@@ -1174,23 +1201,32 @@ void trace_syscall(struct pt_regs *regs)
 
 void kernel_fp_unavailable_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
+
        printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
                          "%lx at %lx\n", regs->trap, regs->nip);
        die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
+
+       exception_exit(prev_state);
 }
 
 void altivec_unavailable_exception(struct pt_regs *regs)
 {
+       enum ctx_state prev_state = exception_enter();
+
        if (user_mode(regs)) {
                /* A user program has executed an altivec instruction,
                   but this kernel doesn't support altivec. */
                _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-               return;
+               goto bail;
        }
 
        printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
                        "%lx at %lx\n", regs->trap, regs->nip);
        die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
+
+bail:
+       exception_exit(prev_state);
 }
 
 void vsx_unavailable_exception(struct pt_regs *regs)
index 13b867093499be5abccb014677371f8787390c7f..9d3fdcd66290b79c6200cd853a04eea73be1a3d0 100644 (file)
@@ -64,6 +64,9 @@ void __init udbg_early_init(void)
        udbg_init_usbgecko();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
        udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
+       /* In memory console */
+       udbg_init_memcons();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
        udbg_init_ehv_bc();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
index 229951ffc35137beb826657c826813b9733eba9b..8726779e1409b5da36c1e1ea852276cf47d4252c 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/perf_event.h>
 #include <linux/magic.h>
 #include <linux/ratelimit.h>
+#include <linux/context_tracking.h>
 
 #include <asm/firmware.h>
 #include <asm/page.h>
@@ -196,6 +197,7 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)
 int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
                            unsigned long error_code)
 {
+       enum ctx_state prev_state = exception_enter();
        struct vm_area_struct * vma;
        struct mm_struct *mm = current->mm;
        unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
@@ -204,6 +206,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
        int trap = TRAP(regs);
        int is_exec = trap == 0x400;
        int fault;
+       int rc = 0;
 
 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
        /*
@@ -230,28 +233,30 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
         * look at it
         */
        if (error_code & ICSWX_DSI_UCT) {
-               int rc = acop_handle_fault(regs, address, error_code);
+               rc = acop_handle_fault(regs, address, error_code);
                if (rc)
-                       return rc;
+                       goto bail;
        }
 #endif /* CONFIG_PPC_ICSWX */
 
        if (notify_page_fault(regs))
-               return 0;
+               goto bail;
 
        if (unlikely(debugger_fault_handler(regs)))
-               return 0;
+               goto bail;
 
        /* On a kernel SLB miss we can only check for a valid exception entry */
-       if (!user_mode(regs) && (address >= TASK_SIZE))
-               return SIGSEGV;
+       if (!user_mode(regs) && (address >= TASK_SIZE)) {
+               rc = SIGSEGV;
+               goto bail;
+       }
 
 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
                             defined(CONFIG_PPC_BOOK3S_64))
        if (error_code & DSISR_DABRMATCH) {
                /* breakpoint match */
                do_break(regs, address, error_code);
-               return 0;
+               goto bail;
        }
 #endif
 
@@ -260,8 +265,10 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
                local_irq_enable();
 
        if (in_atomic() || mm == NULL) {
-               if (!user_mode(regs))
-                       return SIGSEGV;
+               if (!user_mode(regs)) {
+                       rc = SIGSEGV;
+                       goto bail;
+               }
                /* in_atomic() in user mode is really bad,
                   as is current->mm == NULL. */
                printk(KERN_EMERG "Page fault in user mode with "
@@ -417,9 +424,11 @@ good_area:
         */
        fault = handle_mm_fault(mm, vma, address, flags);
        if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
-               int rc = mm_fault_error(regs, address, fault);
+               rc = mm_fault_error(regs, address, fault);
                if (rc >= MM_FAULT_RETURN)
-                       return rc;
+                       goto bail;
+               else
+                       rc = 0;
        }
 
        /*
@@ -454,7 +463,7 @@ good_area:
        }
 
        up_read(&mm->mmap_sem);
-       return 0;
+       goto bail;
 
 bad_area:
        up_read(&mm->mmap_sem);
@@ -463,7 +472,7 @@ bad_area_nosemaphore:
        /* User mode accesses cause a SIGSEGV */
        if (user_mode(regs)) {
                _exception(SIGSEGV, regs, code, address);
-               return 0;
+               goto bail;
        }
 
        if (is_exec && (error_code & DSISR_PROTFAULT))
@@ -471,7 +480,11 @@ bad_area_nosemaphore:
                                   " page (%lx) - exploit attempt? (uid: %d)\n",
                                   address, from_kuid(&init_user_ns, current_uid()));
 
-       return SIGSEGV;
+       rc = SIGSEGV;
+
+bail:
+       exception_exit(prev_state);
+       return rc;
 
 }
 
index 88ac0eeaadde69bfeceb82d44527754638ed351b..e303a6d74e3a72ca2f1db230073f7ec9896a9895 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/init.h>
 #include <linux/signal.h>
 #include <linux/memblock.h>
+#include <linux/context_tracking.h>
 
 #include <asm/processor.h>
 #include <asm/pgtable.h>
@@ -954,6 +955,7 @@ void hash_failure_debug(unsigned long ea, unsigned long access,
  */
 int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
 {
+       enum ctx_state prev_state = exception_enter();
        pgd_t *pgdir;
        unsigned long vsid;
        struct mm_struct *mm;
@@ -973,7 +975,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
                mm = current->mm;
                if (! mm) {
                        DBG_LOW(" user region with no mm !\n");
-                       return 1;
+                       rc = 1;
+                       goto bail;
                }
                psize = get_slice_psize(mm, ea);
                ssize = user_segment_size(ea);
@@ -992,19 +995,23 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
                /* Not a valid range
                 * Send the problem up to do_page_fault 
                 */
-               return 1;
+               rc = 1;
+               goto bail;
        }
        DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid);
 
        /* Bad address. */
        if (!vsid) {
                DBG_LOW("Bad address!\n");
-               return 1;
+               rc = 1;
+               goto bail;
        }
        /* Get pgdir */
        pgdir = mm->pgd;
-       if (pgdir == NULL)
-               return 1;
+       if (pgdir == NULL) {
+               rc = 1;
+               goto bail;
+       }
 
        /* Check CPU locality */
        tmp = cpumask_of(smp_processor_id());
@@ -1027,7 +1034,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
        ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugeshift);
        if (ptep == NULL || !pte_present(*ptep)) {
                DBG_LOW(" no PTE !\n");
-               return 1;
+               rc = 1;
+               goto bail;
        }
 
        /* Add _PAGE_PRESENT to the required access perm */
@@ -1038,13 +1046,16 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
         */
        if (access & ~pte_val(*ptep)) {
                DBG_LOW(" no access !\n");
-               return 1;
+               rc = 1;
+               goto bail;
        }
 
 #ifdef CONFIG_HUGETLB_PAGE
-       if (hugeshift)
-               return __hash_page_huge(ea, access, vsid, ptep, trap, local,
+       if (hugeshift) {
+               rc = __hash_page_huge(ea, access, vsid, ptep, trap, local,
                                        ssize, hugeshift, psize);
+               goto bail;
+       }
 #endif /* CONFIG_HUGETLB_PAGE */
 
 #ifndef CONFIG_PPC_64K_PAGES
@@ -1124,6 +1135,9 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
                pte_val(*(ptep + PTRS_PER_PTE)));
 #endif
        DBG_LOW(" -> rc=%d\n", rc);
+
+bail:
+       exception_exit(prev_state);
        return rc;
 }
 EXPORT_SYMBOL_GPL(hash_page);
@@ -1259,6 +1273,8 @@ void flush_hash_range(unsigned long number, int local)
  */
 void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc)
 {
+       enum ctx_state prev_state = exception_enter();
+
        if (user_mode(regs)) {
 #ifdef CONFIG_PPC_SUBPAGE_PROT
                if (rc == -2)
@@ -1268,6 +1284,8 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc)
                        _exception(SIGBUS, regs, BUS_ADRERR, address);
        } else
                bad_page_fault(regs, address, SIGBUS);
+
+       exception_exit(prev_state);
 }
 
 long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
index c2787bf779ca0f8730f23b542f54c2657fe77471..a90b9c4589908078f139d953707b6ce13b6860d0 100644 (file)
@@ -215,7 +215,8 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
                                             unsigned long phys)
 {
        int  mapped = htab_bolt_mapping(start, start + page_size, phys,
-                                       PAGE_KERNEL, mmu_vmemmap_psize,
+                                       pgprot_val(PAGE_KERNEL),
+                                       mmu_vmemmap_psize,
                                        mmu_kernel_ssize);
        BUG_ON(mapped < 0);
 }
index c627843c5b2eff6084cfd3d23972e2cbd5735d7d..426180b849780f1f8d082e66488fec4b05d9aeb1 100644 (file)
 #include <linux/perf_event.h>
 #include <linux/percpu.h>
 #include <linux/hardirq.h>
+#include <linux/uaccess.h>
 #include <asm/reg.h>
 #include <asm/pmc.h>
 #include <asm/machdep.h>
 #include <asm/firmware.h>
 #include <asm/ptrace.h>
+#include <asm/code-patching.h>
 
 #define BHRB_MAX_ENTRIES       32
 #define BHRB_TARGET            0x0000000000000002
@@ -100,6 +102,10 @@ static inline int siar_valid(struct pt_regs *regs)
        return 1;
 }
 
+static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
+static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
+void power_pmu_flush_branch_stack(void) {}
+static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
 #endif /* CONFIG_PPC32 */
 
 static bool regs_use_siar(struct pt_regs *regs)
@@ -308,6 +314,159 @@ static inline int siar_valid(struct pt_regs *regs)
        return 1;
 }
 
+
+/* Reset all possible BHRB entries */
+static void power_pmu_bhrb_reset(void)
+{
+       asm volatile(PPC_CLRBHRB);
+}
+
+static void power_pmu_bhrb_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       if (!ppmu->bhrb_nr)
+               return;
+
+       /* Clear BHRB if we changed task context to avoid data leaks */
+       if (event->ctx->task && cpuhw->bhrb_context != event->ctx) {
+               power_pmu_bhrb_reset();
+               cpuhw->bhrb_context = event->ctx;
+       }
+       cpuhw->bhrb_users++;
+}
+
+static void power_pmu_bhrb_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       if (!ppmu->bhrb_nr)
+               return;
+
+       cpuhw->bhrb_users--;
+       WARN_ON_ONCE(cpuhw->bhrb_users < 0);
+
+       if (!cpuhw->disabled && !cpuhw->bhrb_users) {
+               /* BHRB cannot be turned off when other
+                * events are active on the PMU.
+                */
+
+               /* avoid stale pointer */
+               cpuhw->bhrb_context = NULL;
+       }
+}
+
+/* Called from ctxsw to prevent one process's branch entries to
+ * mingle with the other process's entries during context switch.
+ */
+void power_pmu_flush_branch_stack(void)
+{
+       if (ppmu->bhrb_nr)
+               power_pmu_bhrb_reset();
+}
+/* Calculate the to address for a branch */
+static __u64 power_pmu_bhrb_to(u64 addr)
+{
+       unsigned int instr;
+       int ret;
+       __u64 target;
+
+       if (is_kernel_addr(addr))
+               return branch_target((unsigned int *)addr);
+
+       /* Userspace: need copy instruction here then translate it */
+       pagefault_disable();
+       ret = __get_user_inatomic(instr, (unsigned int __user *)addr);
+       if (ret) {
+               pagefault_enable();
+               return 0;
+       }
+       pagefault_enable();
+
+       target = branch_target(&instr);
+       if ((!target) || (instr & BRANCH_ABSOLUTE))
+               return target;
+
+       /* Translate relative branch target from kernel to user address */
+       return target - (unsigned long)&instr + addr;
+}
+
+/* Processing BHRB entries */
+void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
+{
+       u64 val;
+       u64 addr;
+       int r_index, u_index, pred;
+
+       r_index = 0;
+       u_index = 0;
+       while (r_index < ppmu->bhrb_nr) {
+               /* Assembly read function */
+               val = read_bhrb(r_index++);
+               if (!val)
+                       /* Terminal marker: End of valid BHRB entries */
+                       break;
+               else {
+                       addr = val & BHRB_EA;
+                       pred = val & BHRB_PREDICTION;
+
+                       if (!addr)
+                               /* invalid entry */
+                               continue;
+
+                       /* Branches are read most recent first (ie. mfbhrb 0 is
+                        * the most recent branch).
+                        * There are two types of valid entries:
+                        * 1) a target entry which is the to address of a
+                        *    computed goto like a blr,bctr,btar.  The next
+                        *    entry read from the bhrb will be branch
+                        *    corresponding to this target (ie. the actual
+                        *    blr/bctr/btar instruction).
+                        * 2) a from address which is an actual branch.  If a
+                        *    target entry proceeds this, then this is the
+                        *    matching branch for that target.  If this is not
+                        *    following a target entry, then this is a branch
+                        *    where the target is given as an immediate field
+                        *    in the instruction (ie. an i or b form branch).
+                        *    In this case we need to read the instruction from
+                        *    memory to determine the target/to address.
+                        */
+
+                       if (val & BHRB_TARGET) {
+                               /* Target branches use two entries
+                                * (ie. computed gotos/XL form)
+                                */
+                               cpuhw->bhrb_entries[u_index].to = addr;
+                               cpuhw->bhrb_entries[u_index].mispred = pred;
+                               cpuhw->bhrb_entries[u_index].predicted = ~pred;
+
+                               /* Get from address in next entry */
+                               val = read_bhrb(r_index++);
+                               addr = val & BHRB_EA;
+                               if (val & BHRB_TARGET) {
+                                       /* Shouldn't have two targets in a
+                                          row.. Reset index and try again */
+                                       r_index--;
+                                       addr = 0;
+                               }
+                               cpuhw->bhrb_entries[u_index].from = addr;
+                       } else {
+                               /* Branches to immediate field 
+                                  (ie I or B form) */
+                               cpuhw->bhrb_entries[u_index].from = addr;
+                               cpuhw->bhrb_entries[u_index].to =
+                                       power_pmu_bhrb_to(addr);
+                               cpuhw->bhrb_entries[u_index].mispred = pred;
+                               cpuhw->bhrb_entries[u_index].predicted = ~pred;
+                       }
+                       u_index++;
+
+               }
+       }
+       cpuhw->bhrb_stack.nr = u_index;
+       return;
+}
+
 #endif /* CONFIG_PPC64 */
 
 static void perf_event_interrupt(struct pt_regs *regs);
@@ -904,47 +1063,6 @@ static int collect_events(struct perf_event *group, int max_count,
        return n;
 }
 
-/* Reset all possible BHRB entries */
-static void power_pmu_bhrb_reset(void)
-{
-       asm volatile(PPC_CLRBHRB);
-}
-
-void power_pmu_bhrb_enable(struct perf_event *event)
-{
-       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
-
-       if (!ppmu->bhrb_nr)
-               return;
-
-       /* Clear BHRB if we changed task context to avoid data leaks */
-       if (event->ctx->task && cpuhw->bhrb_context != event->ctx) {
-               power_pmu_bhrb_reset();
-               cpuhw->bhrb_context = event->ctx;
-       }
-       cpuhw->bhrb_users++;
-}
-
-void power_pmu_bhrb_disable(struct perf_event *event)
-{
-       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
-
-       if (!ppmu->bhrb_nr)
-               return;
-
-       cpuhw->bhrb_users--;
-       WARN_ON_ONCE(cpuhw->bhrb_users < 0);
-
-       if (!cpuhw->disabled && !cpuhw->bhrb_users) {
-               /* BHRB cannot be turned off when other
-                * events are active on the PMU.
-                */
-
-               /* avoid stale pointer */
-               cpuhw->bhrb_context = NULL;
-       }
-}
-
 /*
  * Add a event to the PMU.
  * If all events are not already frozen, then we disable and
@@ -1180,15 +1298,6 @@ int power_pmu_commit_txn(struct pmu *pmu)
        return 0;
 }
 
-/* Called from ctxsw to prevent one process's branch entries to
- * mingle with the other process's entries during context switch.
- */
-void power_pmu_flush_branch_stack(void)
-{
-       if (ppmu->bhrb_nr)
-               power_pmu_bhrb_reset();
-}
-
 /*
  * Return 1 if we might be able to put event on a limited PMC,
  * or 0 if not.
@@ -1458,77 +1567,6 @@ struct pmu power_pmu = {
        .flush_branch_stack = power_pmu_flush_branch_stack,
 };
 
-/* Processing BHRB entries */
-void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
-{
-       u64 val;
-       u64 addr;
-       int r_index, u_index, target, pred;
-
-       r_index = 0;
-       u_index = 0;
-       while (r_index < ppmu->bhrb_nr) {
-               /* Assembly read function */
-               val = read_bhrb(r_index);
-
-               /* Terminal marker: End of valid BHRB entries */
-               if (val == 0) {
-                       break;
-               } else {
-                       /* BHRB field break up */
-                       addr = val & BHRB_EA;
-                       pred = val & BHRB_PREDICTION;
-                       target = val & BHRB_TARGET;
-
-                       /* Probable Missed entry: Not applicable for POWER8 */
-                       if ((addr == 0) && (target == 0) && (pred == 1)) {
-                               r_index++;
-                               continue;
-                       }
-
-                       /* Real Missed entry: Power8 based missed entry */
-                       if ((addr == 0) && (target == 1) && (pred == 1)) {
-                               r_index++;
-                               continue;
-                       }
-
-                       /* Reserved condition: Not a valid entry  */
-                       if ((addr == 0) && (target == 1) && (pred == 0)) {
-                               r_index++;
-                               continue;
-                       }
-
-                       /* Is a target address */
-                       if (val & BHRB_TARGET) {
-                               /* First address cannot be a target address */
-                               if (r_index == 0) {
-                                       r_index++;
-                                       continue;
-                               }
-
-                               /* Update target address for the previous entry */
-                               cpuhw->bhrb_entries[u_index - 1].to = addr;
-                               cpuhw->bhrb_entries[u_index - 1].mispred = pred;
-                               cpuhw->bhrb_entries[u_index - 1].predicted = ~pred;
-
-                               /* Dont increment u_index */
-                               r_index++;
-                       } else {
-                               /* Update address, flags for current entry */
-                               cpuhw->bhrb_entries[u_index].from = addr;
-                               cpuhw->bhrb_entries[u_index].mispred = pred;
-                               cpuhw->bhrb_entries[u_index].predicted = ~pred;
-
-                               /* Successfully popullated one entry */
-                               u_index++;
-                               r_index++;
-                       }
-               }
-       }
-       cpuhw->bhrb_stack.nr = u_index;
-       return;
-}
-
 /*
  * A counter has overflowed; update its count and record
  * things if requested.  Note that interrupts are hard-disabled
index a881232a3cce1bdafee6f5f2a6536a89afe188ab..b62aab3e22ecd0447caf0db7ff97c2c16bc12644 100644 (file)
@@ -128,7 +128,7 @@ config PPC_RTAS_DAEMON
 
 config RTAS_PROC
        bool "Proc interface to RTAS"
-       depends on PPC_RTAS
+       depends on PPC_RTAS && PROC_FS
        default y
 
 config RTAS_FLASH
index ade4463226c612fd338b5cbaed1cb941d14881a9..628c564ceadbb32b1c96287f3ba5cb43390cc56a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/opal.h>
 #include <asm/firmware.h>
 
@@ -28,6 +29,8 @@ struct opal {
 static struct device_node *opal_node;
 static DEFINE_SPINLOCK(opal_write_lock);
 extern u64 opal_mc_secondary_handler[];
+static unsigned int *opal_irqs;
+static unsigned int opal_irq_count;
 
 int __init early_init_dt_scan_opal(unsigned long node,
                                   const char *uname, int depth, void *data)
@@ -53,7 +56,11 @@ int __init early_init_dt_scan_opal(unsigned long node,
                 opal.entry, entryp, entrysz);
 
        powerpc_firmware_features |= FW_FEATURE_OPAL;
-       if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) {
+       if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
+               powerpc_firmware_features |= FW_FEATURE_OPALv2;
+               powerpc_firmware_features |= FW_FEATURE_OPALv3;
+               printk("OPAL V3 detected !\n");
+       } else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) {
                powerpc_firmware_features |= FW_FEATURE_OPALv2;
                printk("OPAL V2 detected !\n");
        } else {
@@ -144,6 +151,13 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
                                rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) {
                len = total_len;
                rc = opal_console_write(vtermno, &len, data);
+
+               /* Closed or other error drop */
+               if (rc != OPAL_SUCCESS && rc != OPAL_BUSY &&
+                   rc != OPAL_BUSY_EVENT) {
+                       written = total_len;
+                       break;
+               }
                if (rc == OPAL_SUCCESS) {
                        total_len -= len;
                        data += len;
@@ -316,6 +330,8 @@ static int __init opal_init(void)
        irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
        pr_debug("opal: Found %d interrupts reserved for OPAL\n",
                 irqs ? (irqlen / 4) : 0);
+       opal_irq_count = irqlen / 4;
+       opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
        for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
                unsigned int hwirq = be32_to_cpup(irqs);
                unsigned int irq = irq_create_mapping(NULL, hwirq);
@@ -327,7 +343,19 @@ static int __init opal_init(void)
                if (rc)
                        pr_warning("opal: Error %d requesting irq %d"
                                   " (0x%x)\n", rc, irq, hwirq);
+               opal_irqs[i] = irq;
        }
        return 0;
 }
 subsys_initcall(opal_init);
+
+void opal_shutdown(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < opal_irq_count; i++) {
+               if (opal_irqs[i])
+                       free_irq(opal_irqs[i], 0);
+               opal_irqs[i] = 0;
+       }
+}
index 1da578b7c1bfc61d80902df4fdf3e2148fc98d8e..3937aaae5bc491108c2ae7deed7a1f555bdd8609 100644 (file)
@@ -1048,6 +1048,12 @@ static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus,
        return phb->ioda.pe_rmap[(bus->number << 8) | devfn];
 }
 
+static void pnv_pci_ioda_shutdown(struct pnv_phb *phb)
+{
+       opal_pci_reset(phb->opal_id, OPAL_PCI_IODA_TABLE_RESET,
+                      OPAL_ASSERT_RESET);
+}
+
 void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type)
 {
        struct pci_controller *hose;
@@ -1178,6 +1184,9 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type)
        /* Setup TCEs */
        phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
 
+       /* Setup shutdown function for kexec */
+       phb->shutdown = pnv_pci_ioda_shutdown;
+
        /* Setup MSI support */
        pnv_pci_init_ioda_msis(phb);
 
index 55dfca844ddf0f8f38cbb5cb1c6863b71e217110..163bd7422f1ca555d79a7a8bfe1734ca44fc98fb 100644 (file)
@@ -450,6 +450,18 @@ static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
                pnv_pci_dma_fallback_setup(hose, pdev);
 }
 
+void pnv_pci_shutdown(void)
+{
+       struct pci_controller *hose;
+
+       list_for_each_entry(hose, &hose_list, list_node) {
+               struct pnv_phb *phb = hose->private_data;
+
+               if (phb && phb->shutdown)
+                       phb->shutdown(phb);
+       }
+}
+
 /* Fixup wrong class code in p7ioc and p8 root complex */
 static void pnv_p7ioc_rc_quirk(struct pci_dev *dev)
 {
index 48dc4bb856a14932878f29b917b5d7551897de66..25d76c4df50b27711c6bd1bb40481216a7009eb6 100644 (file)
@@ -86,6 +86,7 @@ struct pnv_phb {
        void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
        void (*fixup_phb)(struct pci_controller *hose);
        u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
+       void (*shutdown)(struct pnv_phb *phb);
 
        union {
                struct {
@@ -158,4 +159,5 @@ extern void pnv_pci_init_ioda_hub(struct device_node *np);
 extern void pnv_pci_init_ioda2_phb(struct device_node *np);
 extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
                                        u64 *startp, u64 *endp);
+
 #endif /* __POWERNV_PCI_H */
index 8a9df7f9667ede1a97abb5aee79a14843aa5a6ab..a1c6f83fc3916efab1a092e1c7b102ff4a3c788a 100644 (file)
@@ -9,8 +9,10 @@ static inline void pnv_smp_init(void) { }
 
 #ifdef CONFIG_PCI
 extern void pnv_pci_init(void);
+extern void pnv_pci_shutdown(void);
 #else
 static inline void pnv_pci_init(void) { }
+static inline void pnv_pci_shutdown(void) { }
 #endif
 
 #endif /* _POWERNV_H */
index db1ad1c8f68fd1ed18a91fbc542a55c9e31d60b1..d4459bfc92f76a7bd45c6714395023786f200cc9 100644 (file)
@@ -78,7 +78,9 @@ static void pnv_show_cpuinfo(struct seq_file *m)
        if (root)
                model = of_get_property(root, "model", NULL);
        seq_printf(m, "machine\t\t: PowerNV %s\n", model);
-       if (firmware_has_feature(FW_FEATURE_OPALv2))
+       if (firmware_has_feature(FW_FEATURE_OPALv3))
+               seq_printf(m, "firmware\t: OPAL v3\n");
+       else if (firmware_has_feature(FW_FEATURE_OPALv2))
                seq_printf(m, "firmware\t: OPAL v2\n");
        else if (firmware_has_feature(FW_FEATURE_OPAL))
                seq_printf(m, "firmware\t: OPAL v1\n");
@@ -126,6 +128,17 @@ static void pnv_progress(char *s, unsigned short hex)
 {
 }
 
+static void pnv_shutdown(void)
+{
+       /* Let the PCI code clear up IODA tables */
+       pnv_pci_shutdown();
+
+       /* And unregister all OPAL interrupts so they don't fire
+        * up while we kexec
+        */
+       opal_shutdown();
+}
+
 #ifdef CONFIG_KEXEC
 static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
 {
@@ -187,6 +200,7 @@ define_machine(powernv) {
        .init_IRQ               = pnv_init_IRQ,
        .show_cpuinfo           = pnv_show_cpuinfo,
        .progress               = pnv_progress,
+       .machine_shutdown       = pnv_shutdown,
        .power_save             = power7_idle,
        .calibrate_decr         = generic_calibrate_decr,
 #ifdef CONFIG_KEXEC
index 6a3ecca5b7253e5dafe06f488f393eeb7c439186..88c9459c3e07121a64765e4304bcbb4dd7a1b2a4 100644 (file)
@@ -71,18 +71,68 @@ int pnv_smp_kick_cpu(int nr)
 
        BUG_ON(nr < 0 || nr >= NR_CPUS);
 
-       /* On OPAL v2 the CPU are still spinning inside OPAL itself,
-        * get them back now
+       /*
+        * If we already started or OPALv2 is not supported, we just
+        * kick the CPU via the PACA
         */
-       if (!paca[nr].cpu_start && firmware_has_feature(FW_FEATURE_OPALv2)) {
-               pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu);
-               rc = opal_start_cpu(pcpu, start_here);
+       if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv2))
+               goto kick;
+
+       /*
+        * At this point, the CPU can either be spinning on the way in
+        * from kexec or be inside OPAL waiting to be started for the
+        * first time. OPAL v3 allows us to query OPAL to know if it
+        * has the CPUs, so we do that
+        */
+       if (firmware_has_feature(FW_FEATURE_OPALv3)) {
+               uint8_t status;
+
+               rc = opal_query_cpu_status(pcpu, &status);
                if (rc != OPAL_SUCCESS) {
-                       pr_warn("OPAL Error %ld starting CPU %d\n",
+                       pr_warn("OPAL Error %ld querying CPU %d state\n",
                                rc, nr);
                        return -ENODEV;
                }
+
+               /*
+                * Already started, just kick it, probably coming from
+                * kexec and spinning
+                */
+               if (status == OPAL_THREAD_STARTED)
+                       goto kick;
+
+               /*
+                * Available/inactive, let's kick it
+                */
+               if (status == OPAL_THREAD_INACTIVE) {
+                       pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n",
+                                nr, pcpu);
+                       rc = opal_start_cpu(pcpu, start_here);
+                       if (rc != OPAL_SUCCESS) {
+                               pr_warn("OPAL Error %ld starting CPU %d\n",
+                                       rc, nr);
+                               return -ENODEV;
+                       }
+               } else {
+                       /*
+                        * An unavailable CPU (or any other unknown status)
+                        * shouldn't be started. It should also
+                        * not be in the possible map but currently it can
+                        * happen
+                        */
+                       pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable"
+                                " (status %d)...\n", nr, pcpu, status);
+                       return -ENODEV;
+               }
+       } else {
+               /*
+                * On OPAL v2, we just kick it and hope for the best,
+                * we must not test the error from opal_start_cpu() or
+                * we would fail to get CPUs from kexec.
+                */
+               opal_start_cpu(pcpu, start_here);
        }
+ kick:
        return smp_generic_kick_cpu(nr);
 }
 
index 9a0941bc4d31b30ed78cd2ff0527861ce1570b8a..023b288f895bf7afcbe1fa955b58637edb78d19e 100644 (file)
@@ -18,6 +18,7 @@ config PPC_PSERIES
        select PPC_PCI_CHOICE if EXPERT
        select ZLIB_DEFLATE
        select PPC_DOORBELL
+       select HAVE_CONTEXT_TRACKING
        default y
 
 config PPC_SPLPAR
index 47226e04126d10e930a7a4a1bf42aa1c9abedb7a..5f997e79d570f8fb704cf9ec79ef49cb538b3b28 100644 (file)
@@ -16,6 +16,7 @@
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   */
 
+#include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/suspend.h>
 #include <linux/stat.h>
@@ -126,11 +127,15 @@ static ssize_t store_hibernate(struct device *dev,
                               struct device_attribute *attr,
                               const char *buf, size_t count)
 {
+       cpumask_var_t offline_mask;
        int rc;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
+       if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY))
+               return -ENOMEM;
+
        stream_id = simple_strtoul(buf, NULL, 16);
 
        do {
@@ -140,15 +145,32 @@ static ssize_t store_hibernate(struct device *dev,
        } while (rc == -EAGAIN);
 
        if (!rc) {
+               /* All present CPUs must be online */
+               cpumask_andnot(offline_mask, cpu_present_mask,
+                               cpu_online_mask);
+               rc = rtas_online_cpus_mask(offline_mask);
+               if (rc) {
+                       pr_err("%s: Could not bring present CPUs online.\n",
+                                       __func__);
+                       goto out;
+               }
+
                stop_topology_update();
                rc = pm_suspend(PM_SUSPEND_MEM);
                start_topology_update();
+
+               /* Take down CPUs not online prior to suspend */
+               if (!rtas_offline_cpus_mask(offline_mask))
+                       pr_warn("%s: Could not restore CPUs to offline "
+                                       "state.\n", __func__);
        }
 
        stream_id = 0;
 
        if (!rc)
                rc = count;
+out:
+       free_cpumask_var(offline_mask);
        return rc;
 }
 
index 97fe82ee863334664eb2864f18f0b2a7fbd1dc56..2d3b1dd9571da71aec4b11ab97ef5a0cc106be4f 100644 (file)
@@ -361,7 +361,7 @@ static int wsp_chip_set_affinity(struct irq_data *d,
        xive = xive_set_server(xive, get_irq_server(ics, hw_irq));
        wsp_ics_set_xive(ics, hw_irq, xive);
 
-       return 0;
+       return IRQ_SET_MASK_OK;
 }
 
 static struct irq_chip wsp_irq_chip = {
index b0a518e9759978a7255a334388d53c79a387ba61..99464a7bdb3b1b0da09493dd4601d6b02951e13e 100644 (file)
@@ -64,6 +64,8 @@ endif
 
 obj-$(CONFIG_PPC_SCOM)         += scom.o
 
+obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS)  += udbg_memcons.o
+
 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
 obj-$(CONFIG_PPC_XICS)         += xics/
index 6e0e1005227f934930982fd4d4827b464d05180d..9cd0e60716fef0f37b068d14f2ad38222595221e 100644 (file)
@@ -81,7 +81,7 @@ int ehv_pic_set_affinity(struct irq_data *d, const struct cpumask *dest,
        ev_int_set_config(src, config, prio, cpuid);
        spin_unlock_irqrestore(&ehv_pic_lock, flags);
 
-       return 0;
+       return IRQ_SET_MASK_OK;
 }
 
 static unsigned int ehv_pic_type_to_vecpri(unsigned int type)
index ee21b5e71aecd6379d7e93a4e5b299cb8901cce6..0a13ecb270c7d0c30ac3ea2613bf7a4f76552f69 100644 (file)
@@ -836,7 +836,7 @@ int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
                               mpic_physmask(mask));
        }
 
-       return 0;
+       return IRQ_SET_MASK_OK;
 }
 
 static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
diff --git a/arch/powerpc/sysdev/udbg_memcons.c b/arch/powerpc/sysdev/udbg_memcons.c
new file mode 100644 (file)
index 0000000..ce5a7b4
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * A udbg backend which logs messages and reads input from in memory
+ * buffers.
+ *
+ * The console output can be read from memcons_output which is a
+ * circular buffer whose next write position is stored in memcons.output_pos.
+ *
+ * Input may be passed by writing into the memcons_input buffer when it is
+ * empty. The input buffer is empty when both input_pos == input_start and
+ * *input_start == '\0'.
+ *
+ * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
+ * Copyright (C) 2013 Alistair Popple, IBM Corp
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/barrier.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/udbg.h>
+
+struct memcons {
+       char *output_start;
+       char *output_pos;
+       char *output_end;
+       char *input_start;
+       char *input_pos;
+       char *input_end;
+};
+
+static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
+static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];
+
+struct memcons memcons = {
+       .output_start = memcons_output,
+       .output_pos = memcons_output,
+       .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
+       .input_start = memcons_input,
+       .input_pos = memcons_input,
+       .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
+};
+
+void memcons_putc(char c)
+{
+       char *new_output_pos;
+
+       *memcons.output_pos = c;
+       wmb();
+       new_output_pos = memcons.output_pos + 1;
+       if (new_output_pos >= memcons.output_end)
+               new_output_pos = memcons.output_start;
+
+       memcons.output_pos = new_output_pos;
+}
+
+int memcons_getc_poll(void)
+{
+       char c;
+       char *new_input_pos;
+
+       if (*memcons.input_pos) {
+               c = *memcons.input_pos;
+
+               new_input_pos = memcons.input_pos + 1;
+               if (new_input_pos >= memcons.input_end)
+                       new_input_pos = memcons.input_start;
+               else if (*new_input_pos == '\0')
+                       new_input_pos = memcons.input_start;
+
+               *memcons.input_pos = '\0';
+               wmb();
+               memcons.input_pos = new_input_pos;
+               return c;
+       }
+
+       return -1;
+}
+
+int memcons_getc(void)
+{
+       int c;
+
+       while (1) {
+               c = memcons_getc_poll();
+               if (c == -1)
+                       cpu_relax();
+               else
+                       break;
+       }
+
+       return c;
+}
+
+void udbg_init_memcons(void)
+{
+       udbg_putc = memcons_putc;
+       udbg_getc = memcons_getc;
+       udbg_getc_poll = memcons_getc_poll;
+}
index f7e8609df0d5d059ea9230f22c9c9cccf7d3a801..39d72212655e3706ef5ca09dacd689156bc34399 100644 (file)
@@ -148,7 +148,7 @@ static int ics_opal_set_affinity(struct irq_data *d,
                       __func__, d->irq, hw_irq, server, rc);
                return -1;
        }
-       return 0;
+       return IRQ_SET_MASK_OK;
 }
 
 static struct irq_chip ics_opal_irq_chip = {
index 2c9789da0e249ffae45e5714ea505d13822efd2f..da183c5a103ce1df1da3617bbde788011f0351d3 100644 (file)
@@ -98,7 +98,6 @@ config S390
        select CLONE_BACKWARDS2
        select GENERIC_CLOCKEVENTS
        select GENERIC_CPU_DEVICES if !SMP
-       select GENERIC_KERNEL_THREAD
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL_OLD
        select HAVE_ALIGNED_STRUCT_PAGE if SLUB
index b7931faaef6d76add44dd3bcb5c461cec5237a94..bf246dae1367333c109f7f28a60789c2f97deb84 100644 (file)
@@ -9,11 +9,6 @@ struct dyn_arch_ftrace { };
 
 #define MCOUNT_ADDR ((long)_mcount)
 
-#ifdef CONFIG_64BIT
-#define MCOUNT_INSN_SIZE  12
-#else
-#define MCOUNT_INSN_SIZE  20
-#endif
 
 static inline unsigned long ftrace_call_adjust(unsigned long addr)
 {
@@ -21,4 +16,11 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
 }
 
 #endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_64BIT
+#define MCOUNT_INSN_SIZE  12
+#else
+#define MCOUNT_INSN_SIZE  22
+#endif
+
 #endif /* _ASM_S390_FTRACE_H */
index 75ce9b065f9f321f6b0ef3eb3c010c10e58802e6..5d64fb7619ccfc41047c3b1bb6ad45ade2704d1d 100644 (file)
@@ -32,7 +32,7 @@
 
 void storage_key_init_range(unsigned long start, unsigned long end);
 
-static unsigned long pfmf(unsigned long function, unsigned long address)
+static inline unsigned long pfmf(unsigned long function, unsigned long address)
 {
        asm volatile(
                "       .insn   rre,0xb9af0000,%[function],%[address]"
@@ -44,17 +44,13 @@ static unsigned long pfmf(unsigned long function, unsigned long address)
 
 static inline void clear_page(void *page)
 {
-       if (MACHINE_HAS_PFMF) {
-               pfmf(0x10000, (unsigned long)page);
-       } else {
-               register unsigned long reg1 asm ("1") = 0;
-               register void *reg2 asm ("2") = page;
-               register unsigned long reg3 asm ("3") = 4096;
-               asm volatile(
-                       "       mvcl    2,0"
-                       : "+d" (reg2), "+d" (reg3) : "d" (reg1)
-                       : "memory", "cc");
-       }
+       register unsigned long reg1 asm ("1") = 0;
+       register void *reg2 asm ("2") = page;
+       register unsigned long reg3 asm ("3") = 4096;
+       asm volatile(
+               "       mvcl    2,0"
+               : "+d" (reg2), "+d" (reg3) : "d" (reg1)
+               : "memory", "cc");
 }
 
 static inline void copy_page(void *to, void *from)
index 4105b8221fddfd3c180caf78ef65eb9350c93193..0f0de30e3e3fccbf2259e59176ecffab97a6e1e2 100644 (file)
@@ -306,7 +306,7 @@ extern unsigned long MODULES_END;
 #define RCP_HC_BIT     0x00200000UL
 #define RCP_GR_BIT     0x00040000UL
 #define RCP_GC_BIT     0x00020000UL
-#define RCP_IN_BIT     0x00008000UL    /* IPTE notify bit */
+#define RCP_IN_BIT     0x00002000UL    /* IPTE notify bit */
 
 /* User dirty / referenced bit for KVM's migration feature */
 #define KVM_UR_BIT     0x00008000UL
@@ -374,7 +374,7 @@ extern unsigned long MODULES_END;
 #define RCP_HC_BIT     0x0020000000000000UL
 #define RCP_GR_BIT     0x0004000000000000UL
 #define RCP_GC_BIT     0x0002000000000000UL
-#define RCP_IN_BIT     0x0000800000000000UL    /* IPTE notify bit */
+#define RCP_IN_BIT     0x0000200000000000UL    /* IPTE notify bit */
 
 /* User dirty / referenced bit for KVM's migration feature */
 #define KVM_UR_BIT     0x0000800000000000UL
index 7f4a4a8c847c7a3807fd6d913f0ca93fe5b874b8..be87d3e05a5be69265a6100f87afe2fa60d51137 100644 (file)
@@ -1862,6 +1862,8 @@ void print_fn_code(unsigned char *code, unsigned long len)
        while (len) {
                ptr = buffer;
                opsize = insn_length(*code);
+               if (opsize > len)
+                       break;
                ptr += sprintf(ptr, "%p: ", code);
                for (i = 0; i < opsize; i++)
                        ptr += sprintf(ptr, "%02x", code[i]);
index 78bdf0e5dff77999c72b2aae1a7df71347e35053..e3043aef87a96d17d62defc3c14a828625668507 100644 (file)
 #include <trace/syscall.h>
 #include <asm/asm-offsets.h>
 
-#ifdef CONFIG_64BIT
-#define MCOUNT_OFFSET_RET 12
-#else
-#define MCOUNT_OFFSET_RET 22
-#endif
-
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 void ftrace_disable_code(void);
@@ -155,9 +149,10 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent,
 
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                goto out;
+       ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE;
        if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
                goto out;
-       trace.func = (ip & PSW_ADDR_INSN) - MCOUNT_OFFSET_RET;
+       trace.func = ip;
        /* Only trace if the calling function expects to. */
        if (!ftrace_graph_entry(&trace)) {
                current->curr_ret_stack--;
index 4567ce20d900c128a23d27a6b8668b72d921149f..08dcf21cb8dfc040e627b23c1ee279b8822110df 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
+#include <asm/ftrace.h>
 
        .section .kprobes.text, "ax"
 
@@ -33,6 +34,7 @@ ENTRY(ftrace_caller)
        la      %r2,0(%r14)
        st      %r0,__SF_BACKCHAIN(%r15)
        la      %r3,0(%r3)
+       ahi     %r2,-MCOUNT_INSN_SIZE
        l       %r14,0b-0b(%r1)
        l       %r14,0(%r14)
        basr    %r14,%r14
index 11332193db30552a7d028de8debf6af8e019531b..1c52eae3396a0845f3176ba8305607ef049f2608 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
+#include <asm/ftrace.h>
 
        .section .kprobes.text, "ax"
 
@@ -29,6 +30,7 @@ ENTRY(ftrace_caller)
        stg     %r1,__SF_BACKCHAIN(%r15)
        lgr     %r2,%r14
        lg      %r3,168(%r15)
+       aghi    %r2,-MCOUNT_INSN_SIZE
        larl    %r14,ftrace_trace_function
        lg      %r14,0(%r14)
        basr    %r14,%r14
index 8074cb4b7cbf9ea7988160131cf2481241a5115b..05674b6690019012f3acdbb86ea5325616df9f76 100644 (file)
@@ -645,7 +645,7 @@ static int __cpuinit __smp_rescan_cpus(struct sclp_cpu_info *info,
                        continue;
                pcpu = pcpu_devices + cpu;
                pcpu->address = info->cpu[i].address;
-               pcpu->state = (cpu >= info->configured) ?
+               pcpu->state = (i >= info->configured) ?
                        CPU_STATE_STANDBY : CPU_STATE_CONFIGURED;
                smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
                set_cpu_present(cpu, true);
index 7805ddca833d7092149958e8ed56522598b2db07..18dc417aaf79dfc99bd17c48f427bda08ccb6fc5 100644 (file)
@@ -677,8 +677,7 @@ int gmap_ipte_notify(struct gmap *gmap, unsigned long start, unsigned long len)
                        break;
                }
                /* Get the page mapped */
-               if (get_user_pages(current, gmap->mm, addr, 1, 1, 0,
-                                  NULL, NULL) != 1) {
+               if (fixup_user_fault(current, gmap->mm, addr, FAULT_FLAG_WRITE)) {
                        rc = -EFAULT;
                        break;
                }
index 6a154a91c7e746342f35cf6aa13bdae24f544a88..685692c94f051a8a7ad582442efcc3fa11173332 100644 (file)
@@ -108,7 +108,6 @@ config X86
        select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
        select GENERIC_TIME_VSYSCALL if X86_64
        select KTIME_SCALAR if X86_32
-       select ALWAYS_USE_PERSISTENT_CLOCK
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
        select HAVE_CONTEXT_TRACKING if X86_64
index dab95a85f7f8590d240790e981830ea91f729cdd..55b67614ed942fad37e13fe5a48e4fab19f4feea 100644 (file)
@@ -34,7 +34,7 @@
 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern pmd_t early_dynamic_pgts[EARLY_DYNAMIC_PAGE_TABLES][PTRS_PER_PMD];
 static unsigned int __initdata next_early_pgt = 2;
-pmdval_t __initdata early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX);
+pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX);
 
 /* Wipe all early page tables except for the kernel symbol map */
 static void __init reset_early_page_tables(void)
index d893e8ed8ac96559b2175b00c3d68d71658a4105..2e9e12871c2b51a9fe48068369f8dd4346a4db51 100644 (file)
@@ -487,6 +487,7 @@ static inline void show_saved_mc(void)
 #endif
 
 #if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
+static DEFINE_MUTEX(x86_cpu_microcode_mutex);
 /*
  * Save this mc into mc_saved_data. So it will be loaded early when a CPU is
  * hot added or resumes.
@@ -507,7 +508,7 @@ int save_mc_for_early(u8 *mc)
         * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
         * hotplug.
         */
-       cpu_hotplug_driver_lock();
+       mutex_lock(&x86_cpu_microcode_mutex);
 
        mc_saved_count_init = mc_saved_data.mc_saved_count;
        mc_saved_count = mc_saved_data.mc_saved_count;
@@ -544,7 +545,7 @@ int save_mc_for_early(u8 *mc)
        }
 
 out:
-       cpu_hotplug_driver_unlock();
+       mutex_unlock(&x86_cpu_microcode_mutex);
 
        return ret;
 }
index 607af0d4d5ef5f34afc0d5e7caad375dafff6663..4e7a37ff03ab9f6aba634be08f7650e1ef5f2f7c 100644 (file)
@@ -312,6 +312,8 @@ void arch_cpu_idle(void)
 {
        if (cpuidle_idle_call())
                x86_idle();
+       else
+               local_irq_enable();
 }
 
 /*
@@ -368,9 +370,6 @@ void amd_e400_remove_cpu(int cpu)
  */
 static void amd_e400_idle(void)
 {
-       if (need_resched())
-               return;
-
        if (!amd_e400_c1e_detected) {
                u32 lo, hi;
 
index fdc5dca14fb35de5537765acca869ccfb447262d..eaac1743def7ea70cccda0926e53fc2e343f7f06 100644 (file)
@@ -359,7 +359,17 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
 }
 
 /*
- * would have hole in the middle or ends, and only ram parts will be mapped.
+ * We need to iterate through the E820 memory map and create direct mappings
+ * for only E820_RAM and E820_KERN_RESERVED regions. We cannot simply
+ * create direct mappings for all pfns from [0 to max_low_pfn) and
+ * [4GB to max_pfn) because of possible memory holes in high addresses
+ * that cannot be marked as UC by fixed/variable range MTRRs.
+ * Depending on the alignment of E820 ranges, this may possibly result
+ * in using smaller size (i.e. 4K instead of 2M or 1G) page tables.
+ *
+ * init_mem_mapping() calls init_range_memory_mapping() with big range.
+ * That range would have hole in the middle or ends, and only ram parts
+ * will be mapped in init_range_memory_mapping().
  */
 static unsigned long __init init_range_memory_mapping(
                                           unsigned long r_start,
@@ -419,6 +429,13 @@ void __init init_mem_mapping(void)
        max_pfn_mapped = 0; /* will get exact value next */
        min_pfn_mapped = real_end >> PAGE_SHIFT;
        last_start = start = real_end;
+
+       /*
+        * We start from the top (end of memory) and go to the bottom.
+        * The memblock_find_in_range() gets us a block of RAM from the
+        * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages
+        * for page table.
+        */
        while (last_start > ISA_END_ADDRESS) {
                if (last_start > step_size) {
                        start = round_down(last_start - 1, step_size);
index 00d2efd674df5b7a2ecca39ac2e161cfcf14b719..4f4e741d34b2c9616808177c31e7b488ee00ed8e 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/dmi.h>
+#include <linux/delay.h>
 #ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -74,6 +76,8 @@ static int acpi_ac_resume(struct device *dev);
 #endif
 static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
 
+static int ac_sleep_before_get_state_ms;
+
 static struct acpi_driver acpi_ac_driver = {
        .name = "ac",
        .class = ACPI_AC_CLASS,
@@ -252,6 +256,16 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
        case ACPI_AC_NOTIFY_STATUS:
        case ACPI_NOTIFY_BUS_CHECK:
        case ACPI_NOTIFY_DEVICE_CHECK:
+               /*
+                * A buggy BIOS may notify AC first and then sleep for
+                * a specific time before doing actual operations in the
+                * EC event handler (_Qxx). This will cause the AC state
+                * reported by the ACPI event to be incorrect, so wait for a
+                * specific time for the EC event handler to make progress.
+                */
+               if (ac_sleep_before_get_state_ms > 0)
+                       msleep(ac_sleep_before_get_state_ms);
+
                acpi_ac_get_state(ac);
                acpi_bus_generate_proc_event(device, event, (u32) ac->state);
                acpi_bus_generate_netlink_event(device->pnp.device_class,
@@ -264,6 +278,24 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
        return;
 }
 
+static int thinkpad_e530_quirk(const struct dmi_system_id *d)
+{
+       ac_sleep_before_get_state_ms = 1000;
+       return 0;
+}
+
+static struct dmi_system_id ac_dmi_table[] = {
+       {
+       .callback = thinkpad_e530_quirk,
+       .ident = "thinkpad e530",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
+               },
+       },
+       {},
+};
+
 static int acpi_ac_add(struct acpi_device *device)
 {
        int result = 0;
@@ -312,6 +344,7 @@ static int acpi_ac_add(struct acpi_device *device)
                kfree(ac);
        }
 
+       dmi_check_system(ac_dmi_table);
        return result;
 }
 
index d45b2871d33b12fa2453f4f91da1a1d55bf19edc..edc00818c80321086ff3938f5df3cf2afae04d61 100644 (file)
@@ -223,7 +223,7 @@ static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
 static int ec_poll(struct acpi_ec *ec)
 {
        unsigned long flags;
-       int repeat = 2; /* number of command restarts */
+       int repeat = 5; /* number of command restarts */
        while (repeat--) {
                unsigned long delay = jiffies +
                        msecs_to_jiffies(ec_delay);
@@ -241,8 +241,6 @@ static int ec_poll(struct acpi_ec *ec)
                        }
                        advance_transaction(ec, acpi_ec_read_status(ec));
                } while (time_before(jiffies, delay));
-               if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
-                       break;
                pr_debug(PREFIX "controller reset, restart transaction\n");
                spin_lock_irqsave(&ec->lock, flags);
                start_transaction(ec);
index bec717ffd25f5ff7c016f57365a380dc8e91b7fb..c266cdc117840bcdfc7909c2605840501b2c87c2 100644 (file)
@@ -95,9 +95,6 @@ static const struct acpi_device_id processor_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, processor_device_ids);
 
-static SIMPLE_DEV_PM_OPS(acpi_processor_pm,
-                        acpi_processor_suspend, acpi_processor_resume);
-
 static struct acpi_driver acpi_processor_driver = {
        .name = "processor",
        .class = ACPI_PROCESSOR_CLASS,
@@ -107,7 +104,6 @@ static struct acpi_driver acpi_processor_driver = {
                .remove = acpi_processor_remove,
                .notify = acpi_processor_notify,
                },
-       .drv.pm = &acpi_processor_pm,
 };
 
 #define INSTALL_NOTIFY_HANDLER         1
@@ -934,6 +930,8 @@ static int __init acpi_processor_init(void)
        if (result < 0)
                return result;
 
+       acpi_processor_syscore_init();
+
        acpi_processor_install_hotplug_notify();
 
        acpi_thermal_cpufreq_init();
@@ -956,6 +954,8 @@ static void __exit acpi_processor_exit(void)
 
        acpi_processor_uninstall_hotplug_notify();
 
+       acpi_processor_syscore_exit();
+
        acpi_bus_unregister_driver(&acpi_processor_driver);
 
        return;
index f0df2c9434d2ee14809db94e9150b48de0878a7d..eb133c77aadb5f38a7d60824958fa02457c4c67b 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/sched.h>       /* need_resched() */
 #include <linux/clockchips.h>
 #include <linux/cpuidle.h>
+#include <linux/syscore_ops.h>
 
 /*
  * Include the apic definitions for x86 to have the APIC timer related defines
@@ -210,33 +211,41 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
 
 #endif
 
+#ifdef CONFIG_PM_SLEEP
 static u32 saved_bm_rld;
 
-static void acpi_idle_bm_rld_save(void)
+int acpi_processor_suspend(void)
 {
        acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
+       return 0;
 }
-static void acpi_idle_bm_rld_restore(void)
+
+void acpi_processor_resume(void)
 {
        u32 resumed_bm_rld;
 
        acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
+       if (resumed_bm_rld == saved_bm_rld)
+               return;
 
-       if (resumed_bm_rld != saved_bm_rld)
-               acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
+       acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
 }
 
-int acpi_processor_suspend(struct device *dev)
+static struct syscore_ops acpi_processor_syscore_ops = {
+       .suspend = acpi_processor_suspend,
+       .resume = acpi_processor_resume,
+};
+
+void acpi_processor_syscore_init(void)
 {
-       acpi_idle_bm_rld_save();
-       return 0;
+       register_syscore_ops(&acpi_processor_syscore_ops);
 }
 
-int acpi_processor_resume(struct device *dev)
+void acpi_processor_syscore_exit(void)
 {
-       acpi_idle_bm_rld_restore();
-       return 0;
+       unregister_syscore_ops(&acpi_processor_syscore_ops);
 }
+#endif /* CONFIG_PM_SLEEP */
 
 #if defined(CONFIG_X86)
 static void tsc_check_state(int state)
index fe158fd4f1df401d74c04c612cca591f4a7d8eaf..c1bc608339a6007b9d1ecbbd0f2669626d4a538f 100644 (file)
@@ -1785,7 +1785,7 @@ static void acpi_scan_init_hotplug(acpi_handle handle, int type)
        acpi_set_pnp_ids(handle, &pnp, type);
 
        if (!pnp.type.hardware_id)
-               return;
+               goto out;
 
        /*
         * This relies on the fact that acpi_install_notify_handler() will not
@@ -1800,6 +1800,7 @@ static void acpi_scan_init_hotplug(acpi_handle handle, int type)
                }
        }
 
+out:
        acpi_free_pnp_ids(&pnp);
 }
 
index c3932d0876e0059c4a7c7aee7342b7123388e27c..5b32e15a65ceee63861992d51f7731a140946e3c 100644 (file)
@@ -456,6 +456,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
                DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"),
                },
        },
+       {
+        .callback = video_ignore_initial_backlight,
+        .ident = "HP 1000 Notebook PC",
+        .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"),
+               },
+       },
        {}
 };
 
index c1bfaf43d109119e5f47d709365f91c5c170c656..980b88e109fcf5109e164d155dfca86de735c2c2 100644 (file)
@@ -933,11 +933,6 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
        }
 
        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem_res) {
-               err = -ENXIO;
-               goto err_rel_gpio;
-       }
-
        ide_base = devm_ioremap_resource(&pdev->dev, mem_res);
        if (IS_ERR(ide_base)) {
                err = PTR_ERR(ide_base);
index 1a68f947ded86c45e546c837005704a1ed45f293..d414331b480e72afc9ac8ac505dee449f1c795d9 100644 (file)
@@ -1295,6 +1295,7 @@ int subsys_virtual_register(struct bus_type *subsys,
 
        return subsys_register(subsys, groups, virtual_dir);
 }
+EXPORT_SYMBOL_GPL(subsys_virtual_register);
 
 int __init buses_init(void)
 {
index 016312437577ca3378706560a77068dcda67de81..2499cefdcdf2429d9503506d5514a4943f9ec4e1 100644 (file)
@@ -572,9 +572,11 @@ int device_create_file(struct device *dev,
 
        if (dev) {
                WARN(((attr->attr.mode & S_IWUGO) && !attr->store),
-                               "Write permission without 'store'\n");
+                       "Attribute %s: write permission without 'store'\n",
+                       attr->attr.name);
                WARN(((attr->attr.mode & S_IRUGO) && !attr->show),
-                               "Read permission without 'show'\n");
+                       "Attribute %s: read permission without 'show'\n",
+                       attr->attr.name);
                error = sysfs_create_file(&dev->kobj, &attr->attr);
        }
 
index 39c32529b83374c36eda18188c393930732ad99f..5da914041305907d30f26289f12643b5c581be07 100644 (file)
@@ -61,24 +61,24 @@ EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data);
 int dev_pm_put_subsys_data(struct device *dev)
 {
        struct pm_subsys_data *psd;
-       int ret = 0;
+       int ret = 1;
 
        spin_lock_irq(&dev->power.lock);
 
        psd = dev_to_psd(dev);
-       if (!psd) {
-               ret = -EINVAL;
+       if (!psd)
                goto out;
-       }
 
        if (--psd->refcount == 0) {
                dev->power.subsys_data = NULL;
-               kfree(psd);
-               ret = 1;
+       } else {
+               psd = NULL;
+               ret = 0;
        }
 
  out:
        spin_unlock_irq(&dev->power.lock);
+       kfree(psd);
 
        return ret;
 }
index ca63104136e0db46d0248aa290c355483989ec2e..d6d314027b5d45a95ee762ef3c55dcb0769e15a8 100644 (file)
 #define        SECTOR_SHIFT    9
 #define        SECTOR_SIZE     (1ULL << SECTOR_SHIFT)
 
+/*
+ * Increment the given counter and return its updated value.
+ * If the counter is already 0 it will not be incremented.
+ * If the counter is already at its maximum value returns
+ * -EINVAL without updating it.
+ */
+static int atomic_inc_return_safe(atomic_t *v)
+{
+       unsigned int counter;
+
+       counter = (unsigned int)__atomic_add_unless(v, 1, 0);
+       if (counter <= (unsigned int)INT_MAX)
+               return (int)counter;
+
+       atomic_dec(v);
+
+       return -EINVAL;
+}
+
+/* Decrement the counter.  Return the resulting value, or -EINVAL */
+static int atomic_dec_return_safe(atomic_t *v)
+{
+       int counter;
+
+       counter = atomic_dec_return(v);
+       if (counter >= 0)
+               return counter;
+
+       atomic_inc(v);
+
+       return -EINVAL;
+}
+
 #define RBD_DRV_NAME "rbd"
 #define RBD_DRV_NAME_LONG "rbd (rados block device)"
 
  * block device image metadata (in-memory version)
  */
 struct rbd_image_header {
-       /* These four fields never change for a given rbd image */
+       /* These six fields never change for a given rbd image */
        char *object_prefix;
-       u64 features;
        __u8 obj_order;
        __u8 crypt_type;
        __u8 comp_type;
+       u64 stripe_unit;
+       u64 stripe_count;
+       u64 features;           /* Might be changeable someday? */
 
        /* The remaining fields need to be updated occasionally */
        u64 image_size;
        struct ceph_snap_context *snapc;
-       char *snap_names;
-       u64 *snap_sizes;
-
-       u64 stripe_unit;
-       u64 stripe_count;
+       char *snap_names;       /* format 1 only */
+       u64 *snap_sizes;        /* format 1 only */
 };
 
 /*
@@ -225,6 +257,7 @@ struct rbd_obj_request {
                };
        };
        struct page             **copyup_pages;
+       u32                     copyup_page_count;
 
        struct ceph_osd_request *osd_req;
 
@@ -257,6 +290,7 @@ struct rbd_img_request {
                struct rbd_obj_request  *obj_request;   /* obj req initiator */
        };
        struct page             **copyup_pages;
+       u32                     copyup_page_count;
        spinlock_t              completion_lock;/* protects next_completion */
        u32                     next_completion;
        rbd_img_callback_t      callback;
@@ -311,6 +345,7 @@ struct rbd_device {
 
        struct rbd_spec         *parent_spec;
        u64                     parent_overlap;
+       atomic_t                parent_ref;
        struct rbd_device       *parent;
 
        /* protects updating the header */
@@ -359,7 +394,8 @@ static ssize_t rbd_add(struct bus_type *bus, const char *buf,
                       size_t count);
 static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
                          size_t count);
-static int rbd_dev_image_probe(struct rbd_device *rbd_dev);
+static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping);
+static void rbd_spec_put(struct rbd_spec *spec);
 
 static struct bus_attribute rbd_bus_attrs[] = {
        __ATTR(add, S_IWUSR, NULL, rbd_add),
@@ -426,7 +462,8 @@ static void rbd_img_parent_read(struct rbd_obj_request *obj_request);
 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
 
 static int rbd_dev_refresh(struct rbd_device *rbd_dev);
-static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev);
+static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev);
+static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev);
 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
                                        u64 snap_id);
 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
@@ -726,88 +763,123 @@ static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk)
 }
 
 /*
- * Create a new header structure, translate header format from the on-disk
- * header.
+ * Fill an rbd image header with information from the given format 1
+ * on-disk header.
  */
-static int rbd_header_from_disk(struct rbd_image_header *header,
+static int rbd_header_from_disk(struct rbd_device *rbd_dev,
                                 struct rbd_image_header_ondisk *ondisk)
 {
+       struct rbd_image_header *header = &rbd_dev->header;
+       bool first_time = header->object_prefix == NULL;
+       struct ceph_snap_context *snapc;
+       char *object_prefix = NULL;
+       char *snap_names = NULL;
+       u64 *snap_sizes = NULL;
        u32 snap_count;
-       size_t len;
        size_t size;
+       int ret = -ENOMEM;
        u32 i;
 
-       memset(header, 0, sizeof (*header));
+       /* Allocate this now to avoid having to handle failure below */
 
-       snap_count = le32_to_cpu(ondisk->snap_count);
+       if (first_time) {
+               size_t len;
 
-       len = strnlen(ondisk->object_prefix, sizeof (ondisk->object_prefix));
-       header->object_prefix = kmalloc(len + 1, GFP_KERNEL);
-       if (!header->object_prefix)
-               return -ENOMEM;
-       memcpy(header->object_prefix, ondisk->object_prefix, len);
-       header->object_prefix[len] = '\0';
+               len = strnlen(ondisk->object_prefix,
+                               sizeof (ondisk->object_prefix));
+               object_prefix = kmalloc(len + 1, GFP_KERNEL);
+               if (!object_prefix)
+                       return -ENOMEM;
+               memcpy(object_prefix, ondisk->object_prefix, len);
+               object_prefix[len] = '\0';
+       }
 
+       /* Allocate the snapshot context and fill it in */
+
+       snap_count = le32_to_cpu(ondisk->snap_count);
+       snapc = ceph_create_snap_context(snap_count, GFP_KERNEL);
+       if (!snapc)
+               goto out_err;
+       snapc->seq = le64_to_cpu(ondisk->snap_seq);
        if (snap_count) {
+               struct rbd_image_snap_ondisk *snaps;
                u64 snap_names_len = le64_to_cpu(ondisk->snap_names_len);
 
-               /* Save a copy of the snapshot names */
+               /* We'll keep a copy of the snapshot names... */
 
-               if (snap_names_len > (u64) SIZE_MAX)
-                       return -EIO;
-               header->snap_names = kmalloc(snap_names_len, GFP_KERNEL);
-               if (!header->snap_names)
+               if (snap_names_len > (u64)SIZE_MAX)
+                       goto out_2big;
+               snap_names = kmalloc(snap_names_len, GFP_KERNEL);
+               if (!snap_names)
                        goto out_err;
+
+               /* ...as well as the array of their sizes. */
+
+               size = snap_count * sizeof (*header->snap_sizes);
+               snap_sizes = kmalloc(size, GFP_KERNEL);
+               if (!snap_sizes)
+                       goto out_err;
+
                /*
-                * Note that rbd_dev_v1_header_read() guarantees
-                * the ondisk buffer we're working with has
+                * Copy the names, and fill in each snapshot's id
+                * and size.
+                *
+                * Note that rbd_dev_v1_header_info() guarantees the
+                * ondisk buffer we're working with has
                 * snap_names_len bytes beyond the end of the
                 * snapshot id array, this memcpy() is safe.
                 */
-               memcpy(header->snap_names, &ondisk->snaps[snap_count],
-                       snap_names_len);
+               memcpy(snap_names, &ondisk->snaps[snap_count], snap_names_len);
+               snaps = ondisk->snaps;
+               for (i = 0; i < snap_count; i++) {
+                       snapc->snaps[i] = le64_to_cpu(snaps[i].id);
+                       snap_sizes[i] = le64_to_cpu(snaps[i].image_size);
+               }
+       }
 
-               /* Record each snapshot's size */
+       /* We won't fail any more, fill in the header */
 
-               size = snap_count * sizeof (*header->snap_sizes);
-               header->snap_sizes = kmalloc(size, GFP_KERNEL);
-               if (!header->snap_sizes)
-                       goto out_err;
-               for (i = 0; i < snap_count; i++)
-                       header->snap_sizes[i] =
-                               le64_to_cpu(ondisk->snaps[i].image_size);
+       down_write(&rbd_dev->header_rwsem);
+       if (first_time) {
+               header->object_prefix = object_prefix;
+               header->obj_order = ondisk->options.order;
+               header->crypt_type = ondisk->options.crypt_type;
+               header->comp_type = ondisk->options.comp_type;
+               /* The rest aren't used for format 1 images */
+               header->stripe_unit = 0;
+               header->stripe_count = 0;
+               header->features = 0;
        } else {
-               header->snap_names = NULL;
-               header->snap_sizes = NULL;
+               ceph_put_snap_context(header->snapc);
+               kfree(header->snap_names);
+               kfree(header->snap_sizes);
        }
 
-       header->features = 0;   /* No features support in v1 images */
-       header->obj_order = ondisk->options.order;
-       header->crypt_type = ondisk->options.crypt_type;
-       header->comp_type = ondisk->options.comp_type;
-
-       /* Allocate and fill in the snapshot context */
+       /* The remaining fields always get updated (when we refresh) */
 
        header->image_size = le64_to_cpu(ondisk->image_size);
+       header->snapc = snapc;
+       header->snap_names = snap_names;
+       header->snap_sizes = snap_sizes;
 
-       header->snapc = ceph_create_snap_context(snap_count, GFP_KERNEL);
-       if (!header->snapc)
-               goto out_err;
-       header->snapc->seq = le64_to_cpu(ondisk->snap_seq);
-       for (i = 0; i < snap_count; i++)
-               header->snapc->snaps[i] = le64_to_cpu(ondisk->snaps[i].id);
+       /* Make sure mapping size is consistent with header info */
 
-       return 0;
+       if (rbd_dev->spec->snap_id == CEPH_NOSNAP || first_time)
+               if (rbd_dev->mapping.size != header->image_size)
+                       rbd_dev->mapping.size = header->image_size;
+
+       up_write(&rbd_dev->header_rwsem);
 
+       return 0;
+out_2big:
+       ret = -EIO;
 out_err:
-       kfree(header->snap_sizes);
-       header->snap_sizes = NULL;
-       kfree(header->snap_names);
-       header->snap_names = NULL;
-       kfree(header->object_prefix);
-       header->object_prefix = NULL;
+       kfree(snap_sizes);
+       kfree(snap_names);
+       ceph_put_snap_context(snapc);
+       kfree(object_prefix);
 
-       return -ENOMEM;
+       return ret;
 }
 
 static const char *_rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u32 which)
@@ -934,20 +1006,11 @@ static int rbd_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
 
 static int rbd_dev_mapping_set(struct rbd_device *rbd_dev)
 {
-       const char *snap_name = rbd_dev->spec->snap_name;
-       u64 snap_id;
+       u64 snap_id = rbd_dev->spec->snap_id;
        u64 size = 0;
        u64 features = 0;
        int ret;
 
-       if (strcmp(snap_name, RBD_SNAP_HEAD_NAME)) {
-               snap_id = rbd_snap_id_by_name(rbd_dev, snap_name);
-               if (snap_id == CEPH_NOSNAP)
-                       return -ENOENT;
-       } else {
-               snap_id = CEPH_NOSNAP;
-       }
-
        ret = rbd_snap_size(rbd_dev, snap_id, &size);
        if (ret)
                return ret;
@@ -958,11 +1021,6 @@ static int rbd_dev_mapping_set(struct rbd_device *rbd_dev)
        rbd_dev->mapping.size = size;
        rbd_dev->mapping.features = features;
 
-       /* If we are mapping a snapshot it must be marked read-only */
-
-       if (snap_id != CEPH_NOSNAP)
-               rbd_dev->mapping.read_only = true;
-
        return 0;
 }
 
@@ -970,14 +1028,6 @@ static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev)
 {
        rbd_dev->mapping.size = 0;
        rbd_dev->mapping.features = 0;
-       rbd_dev->mapping.read_only = true;
-}
-
-static void rbd_dev_clear_mapping(struct rbd_device *rbd_dev)
-{
-       rbd_dev->mapping.size = 0;
-       rbd_dev->mapping.features = 0;
-       rbd_dev->mapping.read_only = true;
 }
 
 static const char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset)
@@ -1342,20 +1392,18 @@ static void rbd_obj_request_put(struct rbd_obj_request *obj_request)
        kref_put(&obj_request->kref, rbd_obj_request_destroy);
 }
 
-static void rbd_img_request_get(struct rbd_img_request *img_request)
-{
-       dout("%s: img %p (was %d)\n", __func__, img_request,
-               atomic_read(&img_request->kref.refcount));
-       kref_get(&img_request->kref);
-}
-
+static bool img_request_child_test(struct rbd_img_request *img_request);
+static void rbd_parent_request_destroy(struct kref *kref);
 static void rbd_img_request_destroy(struct kref *kref);
 static void rbd_img_request_put(struct rbd_img_request *img_request)
 {
        rbd_assert(img_request != NULL);
        dout("%s: img %p (was %d)\n", __func__, img_request,
                atomic_read(&img_request->kref.refcount));
-       kref_put(&img_request->kref, rbd_img_request_destroy);
+       if (img_request_child_test(img_request))
+               kref_put(&img_request->kref, rbd_parent_request_destroy);
+       else
+               kref_put(&img_request->kref, rbd_img_request_destroy);
 }
 
 static inline void rbd_img_obj_request_add(struct rbd_img_request *img_request,
@@ -1472,6 +1520,12 @@ static void img_request_child_set(struct rbd_img_request *img_request)
        smp_mb();
 }
 
+static void img_request_child_clear(struct rbd_img_request *img_request)
+{
+       clear_bit(IMG_REQ_CHILD, &img_request->flags);
+       smp_mb();
+}
+
 static bool img_request_child_test(struct rbd_img_request *img_request)
 {
        smp_mb();
@@ -1484,6 +1538,12 @@ static void img_request_layered_set(struct rbd_img_request *img_request)
        smp_mb();
 }
 
+static void img_request_layered_clear(struct rbd_img_request *img_request)
+{
+       clear_bit(IMG_REQ_LAYERED, &img_request->flags);
+       smp_mb();
+}
+
 static bool img_request_layered_test(struct rbd_img_request *img_request)
 {
        smp_mb();
@@ -1827,6 +1887,74 @@ static void rbd_obj_request_destroy(struct kref *kref)
        kmem_cache_free(rbd_obj_request_cache, obj_request);
 }
 
+/* It's OK to call this for a device with no parent */
+
+static void rbd_spec_put(struct rbd_spec *spec);
+static void rbd_dev_unparent(struct rbd_device *rbd_dev)
+{
+       rbd_dev_remove_parent(rbd_dev);
+       rbd_spec_put(rbd_dev->parent_spec);
+       rbd_dev->parent_spec = NULL;
+       rbd_dev->parent_overlap = 0;
+}
+
+/*
+ * Parent image reference counting is used to determine when an
+ * image's parent fields can be safely torn down--after there are no
+ * more in-flight requests to the parent image.  When the last
+ * reference is dropped, cleaning them up is safe.
+ */
+static void rbd_dev_parent_put(struct rbd_device *rbd_dev)
+{
+       int counter;
+
+       if (!rbd_dev->parent_spec)
+               return;
+
+       counter = atomic_dec_return_safe(&rbd_dev->parent_ref);
+       if (counter > 0)
+               return;
+
+       /* Last reference; clean up parent data structures */
+
+       if (!counter)
+               rbd_dev_unparent(rbd_dev);
+       else
+               rbd_warn(rbd_dev, "parent reference underflow\n");
+}
+
+/*
+ * If an image has a non-zero parent overlap, get a reference to its
+ * parent.
+ *
+ * We must get the reference before checking for the overlap to
+ * coordinate properly with zeroing the parent overlap in
+ * rbd_dev_v2_parent_info() when an image gets flattened.  We
+ * drop it again if there is no overlap.
+ *
+ * Returns true if the rbd device has a parent with a non-zero
+ * overlap and a reference for it was successfully taken, or
+ * false otherwise.
+ */
+static bool rbd_dev_parent_get(struct rbd_device *rbd_dev)
+{
+       int counter;
+
+       if (!rbd_dev->parent_spec)
+               return false;
+
+       counter = atomic_inc_return_safe(&rbd_dev->parent_ref);
+       if (counter > 0 && rbd_dev->parent_overlap)
+               return true;
+
+       /* Image was flattened, but parent is not yet torn down */
+
+       if (counter < 0)
+               rbd_warn(rbd_dev, "parent reference overflow\n");
+
+       return false;
+}
+
 /*
  * Caller is responsible for filling in the list of object requests
  * that comprises the image request, and the Linux request pointer
@@ -1835,8 +1963,7 @@ static void rbd_obj_request_destroy(struct kref *kref)
 static struct rbd_img_request *rbd_img_request_create(
                                        struct rbd_device *rbd_dev,
                                        u64 offset, u64 length,
-                                       bool write_request,
-                                       bool child_request)
+                                       bool write_request)
 {
        struct rbd_img_request *img_request;
 
@@ -1861,9 +1988,7 @@ static struct rbd_img_request *rbd_img_request_create(
        } else {
                img_request->snap_id = rbd_dev->spec->snap_id;
        }
-       if (child_request)
-               img_request_child_set(img_request);
-       if (rbd_dev->parent_spec)
+       if (rbd_dev_parent_get(rbd_dev))
                img_request_layered_set(img_request);
        spin_lock_init(&img_request->completion_lock);
        img_request->next_completion = 0;
@@ -1873,9 +1998,6 @@ static struct rbd_img_request *rbd_img_request_create(
        INIT_LIST_HEAD(&img_request->obj_requests);
        kref_init(&img_request->kref);
 
-       rbd_img_request_get(img_request);       /* Avoid a warning */
-       rbd_img_request_put(img_request);       /* TEMPORARY */
-
        dout("%s: rbd_dev %p %s %llu/%llu -> img %p\n", __func__, rbd_dev,
                write_request ? "write" : "read", offset, length,
                img_request);
@@ -1897,15 +2019,54 @@ static void rbd_img_request_destroy(struct kref *kref)
                rbd_img_obj_request_del(img_request, obj_request);
        rbd_assert(img_request->obj_request_count == 0);
 
+       if (img_request_layered_test(img_request)) {
+               img_request_layered_clear(img_request);
+               rbd_dev_parent_put(img_request->rbd_dev);
+       }
+
        if (img_request_write_test(img_request))
                ceph_put_snap_context(img_request->snapc);
 
-       if (img_request_child_test(img_request))
-               rbd_obj_request_put(img_request->obj_request);
-
        kmem_cache_free(rbd_img_request_cache, img_request);
 }
 
+static struct rbd_img_request *rbd_parent_request_create(
+                                       struct rbd_obj_request *obj_request,
+                                       u64 img_offset, u64 length)
+{
+       struct rbd_img_request *parent_request;
+       struct rbd_device *rbd_dev;
+
+       rbd_assert(obj_request->img_request);
+       rbd_dev = obj_request->img_request->rbd_dev;
+
+       parent_request = rbd_img_request_create(rbd_dev->parent,
+                                               img_offset, length, false);
+       if (!parent_request)
+               return NULL;
+
+       img_request_child_set(parent_request);
+       rbd_obj_request_get(obj_request);
+       parent_request->obj_request = obj_request;
+
+       return parent_request;
+}
+
+static void rbd_parent_request_destroy(struct kref *kref)
+{
+       struct rbd_img_request *parent_request;
+       struct rbd_obj_request *orig_request;
+
+       parent_request = container_of(kref, struct rbd_img_request, kref);
+       orig_request = parent_request->obj_request;
+
+       parent_request->obj_request = NULL;
+       rbd_obj_request_put(orig_request);
+       img_request_child_clear(parent_request);
+
+       rbd_img_request_destroy(kref);
+}
+
 static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request)
 {
        struct rbd_img_request *img_request;
@@ -2114,7 +2275,7 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
 {
        struct rbd_img_request *img_request;
        struct rbd_device *rbd_dev;
-       u64 length;
+       struct page **pages;
        u32 page_count;
 
        rbd_assert(obj_request->type == OBJ_REQUEST_BIO);
@@ -2124,12 +2285,14 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
 
        rbd_dev = img_request->rbd_dev;
        rbd_assert(rbd_dev);
-       length = (u64)1 << rbd_dev->header.obj_order;
-       page_count = (u32)calc_pages_for(0, length);
 
-       rbd_assert(obj_request->copyup_pages);
-       ceph_release_page_vector(obj_request->copyup_pages, page_count);
+       pages = obj_request->copyup_pages;
+       rbd_assert(pages != NULL);
        obj_request->copyup_pages = NULL;
+       page_count = obj_request->copyup_page_count;
+       rbd_assert(page_count);
+       obj_request->copyup_page_count = 0;
+       ceph_release_page_vector(pages, page_count);
 
        /*
         * We want the transfer count to reflect the size of the
@@ -2153,9 +2316,11 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
        struct ceph_osd_client *osdc;
        struct rbd_device *rbd_dev;
        struct page **pages;
-       int result;
-       u64 obj_size;
-       u64 xferred;
+       u32 page_count;
+       int img_result;
+       u64 parent_length;
+       u64 offset;
+       u64 length;
 
        rbd_assert(img_request_child_test(img_request));
 
@@ -2164,46 +2329,74 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
        pages = img_request->copyup_pages;
        rbd_assert(pages != NULL);
        img_request->copyup_pages = NULL;
+       page_count = img_request->copyup_page_count;
+       rbd_assert(page_count);
+       img_request->copyup_page_count = 0;
 
        orig_request = img_request->obj_request;
        rbd_assert(orig_request != NULL);
-       rbd_assert(orig_request->type == OBJ_REQUEST_BIO);
-       result = img_request->result;
-       obj_size = img_request->length;
-       xferred = img_request->xferred;
+       rbd_assert(obj_request_type_valid(orig_request->type));
+       img_result = img_request->result;
+       parent_length = img_request->length;
+       rbd_assert(parent_length == img_request->xferred);
+       rbd_img_request_put(img_request);
 
-       rbd_dev = img_request->rbd_dev;
+       rbd_assert(orig_request->img_request);
+       rbd_dev = orig_request->img_request->rbd_dev;
        rbd_assert(rbd_dev);
-       rbd_assert(obj_size == (u64)1 << rbd_dev->header.obj_order);
 
-       rbd_img_request_put(img_request);
+       /*
+        * If the overlap has become 0 (most likely because the
+        * image has been flattened) we need to free the pages
+        * and re-submit the original write request.
+        */
+       if (!rbd_dev->parent_overlap) {
+               struct ceph_osd_client *osdc;
 
-       if (result)
-               goto out_err;
+               ceph_release_page_vector(pages, page_count);
+               osdc = &rbd_dev->rbd_client->client->osdc;
+               img_result = rbd_obj_request_submit(osdc, orig_request);
+               if (!img_result)
+                       return;
+       }
 
-       /* Allocate the new copyup osd request for the original request */
+       if (img_result)
+               goto out_err;
 
-       result = -ENOMEM;
-       rbd_assert(!orig_request->osd_req);
+       /*
+        * The original osd request is of no use to use any more.
+        * We need a new one that can hold the two ops in a copyup
+        * request.  Allocate the new copyup osd request for the
+        * original request, and release the old one.
+        */
+       img_result = -ENOMEM;
        osd_req = rbd_osd_req_create_copyup(orig_request);
        if (!osd_req)
                goto out_err;
+       rbd_osd_req_destroy(orig_request->osd_req);
        orig_request->osd_req = osd_req;
        orig_request->copyup_pages = pages;
+       orig_request->copyup_page_count = page_count;
 
        /* Initialize the copyup op */
 
        osd_req_op_cls_init(osd_req, 0, CEPH_OSD_OP_CALL, "rbd", "copyup");
-       osd_req_op_cls_request_data_pages(osd_req, 0, pages, obj_size, 0,
+       osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0,
                                                false, false);
 
        /* Then the original write request op */
 
+       offset = orig_request->offset;
+       length = orig_request->length;
        osd_req_op_extent_init(osd_req, 1, CEPH_OSD_OP_WRITE,
-                                       orig_request->offset,
-                                       orig_request->length, 0, 0);
-       osd_req_op_extent_osd_data_bio(osd_req, 1, orig_request->bio_list,
-                                       orig_request->length);
+                                       offset, length, 0, 0);
+       if (orig_request->type == OBJ_REQUEST_BIO)
+               osd_req_op_extent_osd_data_bio(osd_req, 1,
+                                       orig_request->bio_list, length);
+       else
+               osd_req_op_extent_osd_data_pages(osd_req, 1,
+                                       orig_request->pages, length,
+                                       offset & ~PAGE_MASK, false, false);
 
        rbd_osd_req_format_write(orig_request);
 
@@ -2211,13 +2404,13 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
 
        orig_request->callback = rbd_img_obj_copyup_callback;
        osdc = &rbd_dev->rbd_client->client->osdc;
-       result = rbd_obj_request_submit(osdc, orig_request);
-       if (!result)
+       img_result = rbd_obj_request_submit(osdc, orig_request);
+       if (!img_result)
                return;
 out_err:
        /* Record the error code and complete the request */
 
-       orig_request->result = result;
+       orig_request->result = img_result;
        orig_request->xferred = 0;
        obj_request_done_set(orig_request);
        rbd_obj_request_complete(orig_request);
@@ -2249,22 +2442,13 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
        int result;
 
        rbd_assert(obj_request_img_data_test(obj_request));
-       rbd_assert(obj_request->type == OBJ_REQUEST_BIO);
+       rbd_assert(obj_request_type_valid(obj_request->type));
 
        img_request = obj_request->img_request;
        rbd_assert(img_request != NULL);
        rbd_dev = img_request->rbd_dev;
        rbd_assert(rbd_dev->parent != NULL);
 
-       /*
-        * First things first.  The original osd request is of no
-        * use to use any more, we'll need a new one that can hold
-        * the two ops in a copyup request.  We'll get that later,
-        * but for now we can release the old one.
-        */
-       rbd_osd_req_destroy(obj_request->osd_req);
-       obj_request->osd_req = NULL;
-
        /*
         * Determine the byte range covered by the object in the
         * child image to which the original request was to be sent.
@@ -2295,18 +2479,16 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
        }
 
        result = -ENOMEM;
-       parent_request = rbd_img_request_create(rbd_dev->parent,
-                                               img_offset, length,
-                                               false, true);
+       parent_request = rbd_parent_request_create(obj_request,
+                                               img_offset, length);
        if (!parent_request)
                goto out_err;
-       rbd_obj_request_get(obj_request);
-       parent_request->obj_request = obj_request;
 
        result = rbd_img_request_fill(parent_request, OBJ_REQUEST_PAGES, pages);
        if (result)
                goto out_err;
        parent_request->copyup_pages = pages;
+       parent_request->copyup_page_count = page_count;
 
        parent_request->callback = rbd_img_obj_parent_read_full_callback;
        result = rbd_img_request_submit(parent_request);
@@ -2314,6 +2496,7 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
                return 0;
 
        parent_request->copyup_pages = NULL;
+       parent_request->copyup_page_count = 0;
        parent_request->obj_request = NULL;
        rbd_obj_request_put(obj_request);
 out_err:
@@ -2331,6 +2514,7 @@ out_err:
 static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request)
 {
        struct rbd_obj_request *orig_request;
+       struct rbd_device *rbd_dev;
        int result;
 
        rbd_assert(!obj_request_img_data_test(obj_request));
@@ -2353,8 +2537,21 @@ static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request)
                obj_request->xferred, obj_request->length);
        rbd_obj_request_put(obj_request);
 
-       rbd_assert(orig_request);
-       rbd_assert(orig_request->img_request);
+       /*
+        * If the overlap has become 0 (most likely because the
+        * image has been flattened) we need to free the pages
+        * and re-submit the original write request.
+        */
+       rbd_dev = orig_request->img_request->rbd_dev;
+       if (!rbd_dev->parent_overlap) {
+               struct ceph_osd_client *osdc;
+
+               rbd_obj_request_put(orig_request);
+               osdc = &rbd_dev->rbd_client->client->osdc;
+               result = rbd_obj_request_submit(osdc, orig_request);
+               if (!result)
+                       return;
+       }
 
        /*
         * Our only purpose here is to determine whether the object
@@ -2512,14 +2709,36 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
        struct rbd_obj_request *obj_request;
        struct rbd_device *rbd_dev;
        u64 obj_end;
+       u64 img_xferred;
+       int img_result;
 
        rbd_assert(img_request_child_test(img_request));
 
+       /* First get what we need from the image request and release it */
+
        obj_request = img_request->obj_request;
+       img_xferred = img_request->xferred;
+       img_result = img_request->result;
+       rbd_img_request_put(img_request);
+
+       /*
+        * If the overlap has become 0 (most likely because the
+        * image has been flattened) we need to re-submit the
+        * original request.
+        */
        rbd_assert(obj_request);
        rbd_assert(obj_request->img_request);
+       rbd_dev = obj_request->img_request->rbd_dev;
+       if (!rbd_dev->parent_overlap) {
+               struct ceph_osd_client *osdc;
+
+               osdc = &rbd_dev->rbd_client->client->osdc;
+               img_result = rbd_obj_request_submit(osdc, obj_request);
+               if (!img_result)
+                       return;
+       }
 
-       obj_request->result = img_request->result;
+       obj_request->result = img_result;
        if (obj_request->result)
                goto out;
 
@@ -2532,7 +2751,6 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
         */
        rbd_assert(obj_request->img_offset < U64_MAX - obj_request->length);
        obj_end = obj_request->img_offset + obj_request->length;
-       rbd_dev = obj_request->img_request->rbd_dev;
        if (obj_end > rbd_dev->parent_overlap) {
                u64 xferred = 0;
 
@@ -2540,43 +2758,39 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)
                        xferred = rbd_dev->parent_overlap -
                                        obj_request->img_offset;
 
-               obj_request->xferred = min(img_request->xferred, xferred);
+               obj_request->xferred = min(img_xferred, xferred);
        } else {
-               obj_request->xferred = img_request->xferred;
+               obj_request->xferred = img_xferred;
        }
 out:
-       rbd_img_request_put(img_request);
        rbd_img_obj_request_read_callback(obj_request);
        rbd_obj_request_complete(obj_request);
 }
 
 static void rbd_img_parent_read(struct rbd_obj_request *obj_request)
 {
-       struct rbd_device *rbd_dev;
        struct rbd_img_request *img_request;
        int result;
 
        rbd_assert(obj_request_img_data_test(obj_request));
        rbd_assert(obj_request->img_request != NULL);
        rbd_assert(obj_request->result == (s32) -ENOENT);
-       rbd_assert(obj_request->type == OBJ_REQUEST_BIO);
+       rbd_assert(obj_request_type_valid(obj_request->type));
 
-       rbd_dev = obj_request->img_request->rbd_dev;
-       rbd_assert(rbd_dev->parent != NULL);
        /* rbd_read_finish(obj_request, obj_request->length); */
-       img_request = rbd_img_request_create(rbd_dev->parent,
+       img_request = rbd_parent_request_create(obj_request,
                                                obj_request->img_offset,
-                                               obj_request->length,
-                                               false, true);
+                                               obj_request->length);
        result = -ENOMEM;
        if (!img_request)
                goto out_err;
 
-       rbd_obj_request_get(obj_request);
-       img_request->obj_request = obj_request;
-
-       result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
-                                       obj_request->bio_list);
+       if (obj_request->type == OBJ_REQUEST_BIO)
+               result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
+                                               obj_request->bio_list);
+       else
+               result = rbd_img_request_fill(img_request, OBJ_REQUEST_PAGES,
+                                               obj_request->pages);
        if (result)
                goto out_err;
 
@@ -2626,6 +2840,7 @@ out:
 static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
 {
        struct rbd_device *rbd_dev = (struct rbd_device *)data;
+       int ret;
 
        if (!rbd_dev)
                return;
@@ -2633,7 +2848,9 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
        dout("%s: \"%s\" notify_id %llu opcode %u\n", __func__,
                rbd_dev->header_name, (unsigned long long)notify_id,
                (unsigned int)opcode);
-       (void)rbd_dev_refresh(rbd_dev);
+       ret = rbd_dev_refresh(rbd_dev);
+       if (ret)
+               rbd_warn(rbd_dev, ": header refresh error (%d)\n", ret);
 
        rbd_obj_notify_ack(rbd_dev, notify_id);
 }
@@ -2642,7 +2859,7 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
  * Request sync osd watch/unwatch.  The value of "start" determines
  * whether a watch request is being initiated or torn down.
  */
-static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start)
+static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, bool start)
 {
        struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
        struct rbd_obj_request *obj_request;
@@ -2676,7 +2893,7 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start)
                                        rbd_dev->watch_request->osd_req);
 
        osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_WATCH,
-                               rbd_dev->watch_event->cookie, 0, start);
+                               rbd_dev->watch_event->cookie, 0, start ? 1 : 0);
        rbd_osd_req_format_write(obj_request);
 
        ret = rbd_obj_request_submit(osdc, obj_request);
@@ -2869,9 +3086,16 @@ static void rbd_request_fn(struct request_queue *q)
                        goto end_request;       /* Shouldn't happen */
                }
 
+               result = -EIO;
+               if (offset + length > rbd_dev->mapping.size) {
+                       rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)\n",
+                               offset, length, rbd_dev->mapping.size);
+                       goto end_request;
+               }
+
                result = -ENOMEM;
                img_request = rbd_img_request_create(rbd_dev, offset, length,
-                                                       write_request, false);
+                                                       write_request);
                if (!img_request)
                        goto end_request;
 
@@ -3022,17 +3246,11 @@ out:
 }
 
 /*
- * Read the complete header for the given rbd device.
- *
- * Returns a pointer to a dynamically-allocated buffer containing
- * the complete and validated header.  Caller can pass the address
- * of a variable that will be filled in with the version of the
- * header object at the time it was read.
- *
- * Returns a pointer-coded errno if a failure occurs.
+ * Read the complete header for the given rbd device.  On successful
+ * return, the rbd_dev->header field will contain up-to-date
+ * information about the image.
  */
-static struct rbd_image_header_ondisk *
-rbd_dev_v1_header_read(struct rbd_device *rbd_dev)
+static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev)
 {
        struct rbd_image_header_ondisk *ondisk = NULL;
        u32 snap_count = 0;
@@ -3057,22 +3275,22 @@ rbd_dev_v1_header_read(struct rbd_device *rbd_dev)
                size += names_size;
                ondisk = kmalloc(size, GFP_KERNEL);
                if (!ondisk)
-                       return ERR_PTR(-ENOMEM);
+                       return -ENOMEM;
 
                ret = rbd_obj_read_sync(rbd_dev, rbd_dev->header_name,
                                       0, size, ondisk);
                if (ret < 0)
-                       goto out_err;
+                       goto out;
                if ((size_t)ret < size) {
                        ret = -ENXIO;
                        rbd_warn(rbd_dev, "short header read (want %zd got %d)",
                                size, ret);
-                       goto out_err;
+                       goto out;
                }
                if (!rbd_dev_ondisk_valid(ondisk)) {
                        ret = -ENXIO;
                        rbd_warn(rbd_dev, "invalid header");
-                       goto out_err;
+                       goto out;
                }
 
                names_size = le64_to_cpu(ondisk->snap_names_len);
@@ -3080,85 +3298,13 @@ rbd_dev_v1_header_read(struct rbd_device *rbd_dev)
                snap_count = le32_to_cpu(ondisk->snap_count);
        } while (snap_count != want_count);
 
-       return ondisk;
-
-out_err:
-       kfree(ondisk);
-
-       return ERR_PTR(ret);
-}
-
-/*
- * reload the ondisk the header
- */
-static int rbd_read_header(struct rbd_device *rbd_dev,
-                          struct rbd_image_header *header)
-{
-       struct rbd_image_header_ondisk *ondisk;
-       int ret;
-
-       ondisk = rbd_dev_v1_header_read(rbd_dev);
-       if (IS_ERR(ondisk))
-               return PTR_ERR(ondisk);
-       ret = rbd_header_from_disk(header, ondisk);
+       ret = rbd_header_from_disk(rbd_dev, ondisk);
+out:
        kfree(ondisk);
 
        return ret;
 }
 
-static void rbd_update_mapping_size(struct rbd_device *rbd_dev)
-{
-       if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
-               return;
-
-       if (rbd_dev->mapping.size != rbd_dev->header.image_size) {
-               sector_t size;
-
-               rbd_dev->mapping.size = rbd_dev->header.image_size;
-               size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE;
-               dout("setting size to %llu sectors", (unsigned long long)size);
-               set_capacity(rbd_dev->disk, size);
-       }
-}
-
-/*
- * only read the first part of the ondisk header, without the snaps info
- */
-static int rbd_dev_v1_refresh(struct rbd_device *rbd_dev)
-{
-       int ret;
-       struct rbd_image_header h;
-
-       ret = rbd_read_header(rbd_dev, &h);
-       if (ret < 0)
-               return ret;
-
-       down_write(&rbd_dev->header_rwsem);
-
-       /* Update image size, and check for resize of mapped image */
-       rbd_dev->header.image_size = h.image_size;
-       rbd_update_mapping_size(rbd_dev);
-
-       /* rbd_dev->header.object_prefix shouldn't change */
-       kfree(rbd_dev->header.snap_sizes);
-       kfree(rbd_dev->header.snap_names);
-       /* osd requests may still refer to snapc */
-       ceph_put_snap_context(rbd_dev->header.snapc);
-
-       rbd_dev->header.image_size = h.image_size;
-       rbd_dev->header.snapc = h.snapc;
-       rbd_dev->header.snap_names = h.snap_names;
-       rbd_dev->header.snap_sizes = h.snap_sizes;
-       /* Free the extra copy of the object prefix */
-       if (strcmp(rbd_dev->header.object_prefix, h.object_prefix))
-               rbd_warn(rbd_dev, "object prefix changed (ignoring)");
-       kfree(h.object_prefix);
-
-       up_write(&rbd_dev->header_rwsem);
-
-       return ret;
-}
-
 /*
  * Clear the rbd device's EXISTS flag if the snapshot it's mapped to
  * has disappeared from the (just updated) snapshot context.
@@ -3180,26 +3326,29 @@ static void rbd_exists_validate(struct rbd_device *rbd_dev)
 
 static int rbd_dev_refresh(struct rbd_device *rbd_dev)
 {
-       u64 image_size;
+       u64 mapping_size;
        int ret;
 
        rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
-       image_size = rbd_dev->header.image_size;
+       mapping_size = rbd_dev->mapping.size;
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
        if (rbd_dev->image_format == 1)
-               ret = rbd_dev_v1_refresh(rbd_dev);
+               ret = rbd_dev_v1_header_info(rbd_dev);
        else
-               ret = rbd_dev_v2_refresh(rbd_dev);
+               ret = rbd_dev_v2_header_info(rbd_dev);
 
        /* If it's a mapped snapshot, validate its EXISTS flag */
 
        rbd_exists_validate(rbd_dev);
        mutex_unlock(&ctl_mutex);
-       if (ret)
-               rbd_warn(rbd_dev, "got notification but failed to "
-                          " update snaps: %d\n", ret);
-       if (image_size != rbd_dev->header.image_size)
+       if (mapping_size != rbd_dev->mapping.size) {
+               sector_t size;
+
+               size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE;
+               dout("setting size to %llu sectors", (unsigned long long)size);
+               set_capacity(rbd_dev->disk, size);
                revalidate_disk(rbd_dev->disk);
+       }
 
        return ret;
 }
@@ -3403,6 +3552,8 @@ static ssize_t rbd_image_refresh(struct device *dev,
        int ret;
 
        ret = rbd_dev_refresh(rbd_dev);
+       if (ret)
+               rbd_warn(rbd_dev, ": manual header refresh error (%d)\n", ret);
 
        return ret < 0 ? ret : size;
 }
@@ -3501,6 +3652,7 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
 
        spin_lock_init(&rbd_dev->lock);
        rbd_dev->flags = 0;
+       atomic_set(&rbd_dev->parent_ref, 0);
        INIT_LIST_HEAD(&rbd_dev->node);
        init_rwsem(&rbd_dev->header_rwsem);
 
@@ -3650,6 +3802,7 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
        __le64 snapid;
        void *p;
        void *end;
+       u64 pool_id;
        char *image_id;
        u64 overlap;
        int ret;
@@ -3680,18 +3833,37 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
        p = reply_buf;
        end = reply_buf + ret;
        ret = -ERANGE;
-       ceph_decode_64_safe(&p, end, parent_spec->pool_id, out_err);
-       if (parent_spec->pool_id == CEPH_NOPOOL)
+       ceph_decode_64_safe(&p, end, pool_id, out_err);
+       if (pool_id == CEPH_NOPOOL) {
+               /*
+                * Either the parent never existed, or we have
+                * record of it but the image got flattened so it no
+                * longer has a parent.  When the parent of a
+                * layered image disappears we immediately set the
+                * overlap to 0.  The effect of this is that all new
+                * requests will be treated as if the image had no
+                * parent.
+                */
+               if (rbd_dev->parent_overlap) {
+                       rbd_dev->parent_overlap = 0;
+                       smp_mb();
+                       rbd_dev_parent_put(rbd_dev);
+                       pr_info("%s: clone image has been flattened\n",
+                               rbd_dev->disk->disk_name);
+               }
+
                goto out;       /* No parent?  No problem. */
+       }
 
        /* The ceph file layout needs to fit pool id in 32 bits */
 
        ret = -EIO;
-       if (parent_spec->pool_id > (u64)U32_MAX) {
+       if (pool_id > (u64)U32_MAX) {
                rbd_warn(NULL, "parent pool id too large (%llu > %u)\n",
-                       (unsigned long long)parent_spec->pool_id, U32_MAX);
+                       (unsigned long long)pool_id, U32_MAX);
                goto out_err;
        }
+       parent_spec->pool_id = pool_id;
 
        image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL);
        if (IS_ERR(image_id)) {
@@ -3702,9 +3874,14 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
        ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err);
        ceph_decode_64_safe(&p, end, overlap, out_err);
 
-       rbd_dev->parent_overlap = overlap;
-       rbd_dev->parent_spec = parent_spec;
-       parent_spec = NULL;     /* rbd_dev now owns this */
+       if (overlap) {
+               rbd_spec_put(rbd_dev->parent_spec);
+               rbd_dev->parent_spec = parent_spec;
+               parent_spec = NULL;     /* rbd_dev now owns this */
+               rbd_dev->parent_overlap = overlap;
+       } else {
+               rbd_warn(rbd_dev, "ignoring parent of clone with overlap 0\n");
+       }
 out:
        ret = 0;
 out_err:
@@ -4002,6 +4179,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)
        for (i = 0; i < snap_count; i++)
                snapc->snaps[i] = ceph_decode_64(&p);
 
+       ceph_put_snap_context(rbd_dev->header.snapc);
        rbd_dev->header.snapc = snapc;
 
        dout("  snap context seq = %llu, snap_count = %u\n",
@@ -4053,21 +4231,56 @@ out:
        return snap_name;
 }
 
-static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
 {
+       bool first_time = rbd_dev->header.object_prefix == NULL;
        int ret;
 
        down_write(&rbd_dev->header_rwsem);
 
+       if (first_time) {
+               ret = rbd_dev_v2_header_onetime(rbd_dev);
+               if (ret)
+                       goto out;
+       }
+
+       /*
+        * If the image supports layering, get the parent info.  We
+        * need to probe the first time regardless.  Thereafter we
+        * only need to if there's a parent, to see if it has
+        * disappeared due to the mapped image getting flattened.
+        */
+       if (rbd_dev->header.features & RBD_FEATURE_LAYERING &&
+                       (first_time || rbd_dev->parent_spec)) {
+               bool warn;
+
+               ret = rbd_dev_v2_parent_info(rbd_dev);
+               if (ret)
+                       goto out;
+
+               /*
+                * Print a warning if this is the initial probe and
+                * the image has a parent.  Don't print it if the
+                * image now being probed is itself a parent.  We
+                * can tell at this point because we won't know its
+                * pool name yet (just its pool id).
+                */
+               warn = rbd_dev->parent_spec && rbd_dev->spec->pool_name;
+               if (first_time && warn)
+                       rbd_warn(rbd_dev, "WARNING: kernel layering "
+                                       "is EXPERIMENTAL!");
+       }
+
        ret = rbd_dev_v2_image_size(rbd_dev);
        if (ret)
                goto out;
-       rbd_update_mapping_size(rbd_dev);
+
+       if (rbd_dev->spec->snap_id == CEPH_NOSNAP)
+               if (rbd_dev->mapping.size != rbd_dev->header.image_size)
+                       rbd_dev->mapping.size = rbd_dev->header.image_size;
 
        ret = rbd_dev_v2_snap_context(rbd_dev);
        dout("rbd_dev_v2_snap_context returned %d\n", ret);
-       if (ret)
-               goto out;
 out:
        up_write(&rbd_dev->header_rwsem);
 
@@ -4490,10 +4703,10 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
 {
        struct rbd_image_header *header;
 
-       rbd_dev_remove_parent(rbd_dev);
-       rbd_spec_put(rbd_dev->parent_spec);
-       rbd_dev->parent_spec = NULL;
-       rbd_dev->parent_overlap = 0;
+       /* Drop parent reference unless it's already been done (or none) */
+
+       if (rbd_dev->parent_overlap)
+               rbd_dev_parent_put(rbd_dev);
 
        /* Free dynamic fields from the header, then zero it out */
 
@@ -4505,72 +4718,22 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
        memset(header, 0, sizeof (*header));
 }
 
-static int rbd_dev_v1_probe(struct rbd_device *rbd_dev)
+static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
 {
        int ret;
 
-       /* Populate rbd image metadata */
-
-       ret = rbd_read_header(rbd_dev, &rbd_dev->header);
-       if (ret < 0)
-               goto out_err;
-
-       /* Version 1 images have no parent (no layering) */
-
-       rbd_dev->parent_spec = NULL;
-       rbd_dev->parent_overlap = 0;
-
-       dout("discovered version 1 image, header name is %s\n",
-               rbd_dev->header_name);
-
-       return 0;
-
-out_err:
-       kfree(rbd_dev->header_name);
-       rbd_dev->header_name = NULL;
-       kfree(rbd_dev->spec->image_id);
-       rbd_dev->spec->image_id = NULL;
-
-       return ret;
-}
-
-static int rbd_dev_v2_probe(struct rbd_device *rbd_dev)
-{
-       int ret;
-
-       ret = rbd_dev_v2_image_size(rbd_dev);
-       if (ret)
-               goto out_err;
-
-       /* Get the object prefix (a.k.a. block_name) for the image */
-
        ret = rbd_dev_v2_object_prefix(rbd_dev);
        if (ret)
                goto out_err;
 
-       /* Get the and check features for the image */
-
+       /*
+        * Get the and check features for the image.  Currently the
+        * features are assumed to never change.
+        */
        ret = rbd_dev_v2_features(rbd_dev);
        if (ret)
                goto out_err;
 
-       /* If the image supports layering, get the parent info */
-
-       if (rbd_dev->header.features & RBD_FEATURE_LAYERING) {
-               ret = rbd_dev_v2_parent_info(rbd_dev);
-               if (ret)
-                       goto out_err;
-
-               /*
-                * Don't print a warning for parent images.  We can
-                * tell this point because we won't know its pool
-                * name yet (just its pool id).
-                */
-               if (rbd_dev->spec->pool_name)
-                       rbd_warn(rbd_dev, "WARNING: kernel layering "
-                                       "is EXPERIMENTAL!");
-       }
-
        /* If the image supports fancy striping, get its parameters */
 
        if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) {
@@ -4578,28 +4741,11 @@ static int rbd_dev_v2_probe(struct rbd_device *rbd_dev)
                if (ret < 0)
                        goto out_err;
        }
-
-       /* crypto and compression type aren't (yet) supported for v2 images */
-
-       rbd_dev->header.crypt_type = 0;
-       rbd_dev->header.comp_type = 0;
-
-       /* Get the snapshot context, plus the header version */
-
-       ret = rbd_dev_v2_snap_context(rbd_dev);
-       if (ret)
-               goto out_err;
-
-       dout("discovered version 2 image, header name is %s\n",
-               rbd_dev->header_name);
+       /* No support for crypto and compression type format 2 images */
 
        return 0;
 out_err:
-       rbd_dev->parent_overlap = 0;
-       rbd_spec_put(rbd_dev->parent_spec);
-       rbd_dev->parent_spec = NULL;
-       kfree(rbd_dev->header_name);
-       rbd_dev->header_name = NULL;
+       rbd_dev->header.features = 0;
        kfree(rbd_dev->header.object_prefix);
        rbd_dev->header.object_prefix = NULL;
 
@@ -4628,15 +4774,16 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
        if (!parent)
                goto out_err;
 
-       ret = rbd_dev_image_probe(parent);
+       ret = rbd_dev_image_probe(parent, false);
        if (ret < 0)
                goto out_err;
        rbd_dev->parent = parent;
+       atomic_set(&rbd_dev->parent_ref, 1);
 
        return 0;
 out_err:
        if (parent) {
-               rbd_spec_put(rbd_dev->parent_spec);
+               rbd_dev_unparent(rbd_dev);
                kfree(rbd_dev->header_name);
                rbd_dev_destroy(parent);
        } else {
@@ -4651,10 +4798,6 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
 {
        int ret;
 
-       ret = rbd_dev_mapping_set(rbd_dev);
-       if (ret)
-               return ret;
-
        /* generate unique id: find highest unique id, add one */
        rbd_dev_id_get(rbd_dev);
 
@@ -4676,13 +4819,17 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
        if (ret)
                goto err_out_blkdev;
 
-       ret = rbd_bus_add_dev(rbd_dev);
+       ret = rbd_dev_mapping_set(rbd_dev);
        if (ret)
                goto err_out_disk;
+       set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
+
+       ret = rbd_bus_add_dev(rbd_dev);
+       if (ret)
+               goto err_out_mapping;
 
        /* Everything's ready.  Announce the disk to the world. */
 
-       set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
        set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
        add_disk(rbd_dev->disk);
 
@@ -4691,6 +4838,8 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
 
        return ret;
 
+err_out_mapping:
+       rbd_dev_mapping_clear(rbd_dev);
 err_out_disk:
        rbd_free_disk(rbd_dev);
 err_out_blkdev:
@@ -4731,12 +4880,7 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev)
 
 static void rbd_dev_image_release(struct rbd_device *rbd_dev)
 {
-       int ret;
-
        rbd_dev_unprobe(rbd_dev);
-       ret = rbd_dev_header_watch_sync(rbd_dev, 0);
-       if (ret)
-               rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret);
        kfree(rbd_dev->header_name);
        rbd_dev->header_name = NULL;
        rbd_dev->image_format = 0;
@@ -4748,10 +4892,11 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
 
 /*
  * Probe for the existence of the header object for the given rbd
- * device.  For format 2 images this includes determining the image
- * id.
+ * device.  If this image is the one being mapped (i.e., not a
+ * parent), initiate a watch on its header object before using that
+ * object to get detailed information about the rbd image.
  */
-static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
+static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
 {
        int ret;
        int tmp;
@@ -4771,14 +4916,16 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
        if (ret)
                goto err_out_format;
 
-       ret = rbd_dev_header_watch_sync(rbd_dev, 1);
-       if (ret)
-               goto out_header_name;
+       if (mapping) {
+               ret = rbd_dev_header_watch_sync(rbd_dev, true);
+               if (ret)
+                       goto out_header_name;
+       }
 
        if (rbd_dev->image_format == 1)
-               ret = rbd_dev_v1_probe(rbd_dev);
+               ret = rbd_dev_v1_header_info(rbd_dev);
        else
-               ret = rbd_dev_v2_probe(rbd_dev);
+               ret = rbd_dev_v2_header_info(rbd_dev);
        if (ret)
                goto err_out_watch;
 
@@ -4787,15 +4934,22 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
                goto err_out_probe;
 
        ret = rbd_dev_probe_parent(rbd_dev);
-       if (!ret)
-               return 0;
+       if (ret)
+               goto err_out_probe;
+
+       dout("discovered format %u image, header name is %s\n",
+               rbd_dev->image_format, rbd_dev->header_name);
 
+       return 0;
 err_out_probe:
        rbd_dev_unprobe(rbd_dev);
 err_out_watch:
-       tmp = rbd_dev_header_watch_sync(rbd_dev, 0);
-       if (tmp)
-               rbd_warn(rbd_dev, "unable to tear down watch request\n");
+       if (mapping) {
+               tmp = rbd_dev_header_watch_sync(rbd_dev, false);
+               if (tmp)
+                       rbd_warn(rbd_dev, "unable to tear down "
+                                       "watch request (%d)\n", tmp);
+       }
 out_header_name:
        kfree(rbd_dev->header_name);
        rbd_dev->header_name = NULL;
@@ -4819,6 +4973,7 @@ static ssize_t rbd_add(struct bus_type *bus,
        struct rbd_spec *spec = NULL;
        struct rbd_client *rbdc;
        struct ceph_osd_client *osdc;
+       bool read_only;
        int rc = -ENOMEM;
 
        if (!try_module_get(THIS_MODULE))
@@ -4828,6 +4983,9 @@ static ssize_t rbd_add(struct bus_type *bus,
        rc = rbd_add_parse_args(buf, &ceph_opts, &rbd_opts, &spec);
        if (rc < 0)
                goto err_out_module;
+       read_only = rbd_opts->read_only;
+       kfree(rbd_opts);
+       rbd_opts = NULL;        /* done with this */
 
        rbdc = rbd_get_client(ceph_opts);
        if (IS_ERR(rbdc)) {
@@ -4858,14 +5016,16 @@ static ssize_t rbd_add(struct bus_type *bus,
        rbdc = NULL;            /* rbd_dev now owns this */
        spec = NULL;            /* rbd_dev now owns this */
 
-       rbd_dev->mapping.read_only = rbd_opts->read_only;
-       kfree(rbd_opts);
-       rbd_opts = NULL;        /* done with this */
-
-       rc = rbd_dev_image_probe(rbd_dev);
+       rc = rbd_dev_image_probe(rbd_dev, true);
        if (rc < 0)
                goto err_out_rbd_dev;
 
+       /* If we are mapping a snapshot it must be marked read-only */
+
+       if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
+               read_only = true;
+       rbd_dev->mapping.read_only = read_only;
+
        rc = rbd_dev_device_setup(rbd_dev);
        if (!rc)
                return count;
@@ -4911,7 +5071,7 @@ static void rbd_dev_device_release(struct device *dev)
 
        rbd_free_disk(rbd_dev);
        clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
-       rbd_dev_clear_mapping(rbd_dev);
+       rbd_dev_mapping_clear(rbd_dev);
        unregister_blkdev(rbd_dev->major, rbd_dev->name);
        rbd_dev->major = 0;
        rbd_dev_id_put(rbd_dev);
@@ -4978,10 +5138,13 @@ static ssize_t rbd_remove(struct bus_type *bus,
        spin_unlock_irq(&rbd_dev->lock);
        if (ret < 0)
                goto done;
-       ret = count;
        rbd_bus_del_dev(rbd_dev);
+       ret = rbd_dev_header_watch_sync(rbd_dev, false);
+       if (ret)
+               rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret);
        rbd_dev_image_release(rbd_dev);
        module_put(THIS_MODULE);
+       ret = count;
 done:
        mutex_unlock(&ctl_mutex);
 
index 4ca35e8a5d8c60a73a375dd132d0bbe196810a23..19a12ac64a9ec966149286a84a2f0db5e3e0ee60 100644 (file)
@@ -167,11 +167,6 @@ static int __init mxc_rnga_probe(struct platform_device *pdev)
        clk_prepare_enable(mxc_rng->clk);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               err = -ENOENT;
-               goto err_region;
-       }
-
        mxc_rng->mem = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(mxc_rng->mem)) {
                err = PTR_ERR(mxc_rng->mem);
@@ -189,7 +184,6 @@ static int __init mxc_rnga_probe(struct platform_device *pdev)
        return 0;
 
 err_ioremap:
-err_region:
        clk_disable_unprepare(mxc_rng->clk);
 
 out:
index 749dc16ca2cc084b81c78c47864ce430489e7e08..d2903e7722704843ac254390046b65b5b5540d6c 100644 (file)
@@ -119,11 +119,6 @@ static int omap_rng_probe(struct platform_device *pdev)
        dev_set_drvdata(&pdev->dev, priv);
 
        priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!priv->mem_res) {
-               ret = -ENOENT;
-               goto err_ioremap;
-       }
-
        priv->base = devm_ioremap_resource(&pdev->dev, priv->mem_res);
        if (IS_ERR(priv->base)) {
                ret = PTR_ERR(priv->base);
index cdd4c09fda963b2de1e1e3371090a93625d0b771..a22a7a502740ff42a4ce4413b620026d228909ee 100644 (file)
@@ -95,9 +95,9 @@ struct si_sm_data {
        enum bt_states  state;
        unsigned char   seq;            /* BT sequence number */
        struct si_sm_io *io;
-       unsigned char   write_data[IPMI_MAX_MSG_LENGTH];
+       unsigned char   write_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */
        int             write_count;
-       unsigned char   read_data[IPMI_MAX_MSG_LENGTH];
+       unsigned char   read_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */
        int             read_count;
        int             truncated;
        long            timeout;        /* microseconds countdown */
index 9eb360ff8cab0cc19178b6412ade5f4cf3d40e18..d5a5f020810afcdf8f6d5d19d1b45960c83589d5 100644 (file)
@@ -837,13 +837,25 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
                return ipmi_ioctl(filep, cmd, arg);
        }
 }
+
+static long unlocked_compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
+                                      unsigned long arg)
+{
+       int ret;
+
+       mutex_lock(&ipmi_mutex);
+       ret = compat_ipmi_ioctl(filep, cmd, arg);
+       mutex_unlock(&ipmi_mutex);
+
+       return ret;
+}
 #endif
 
 static const struct file_operations ipmi_fops = {
        .owner          = THIS_MODULE,
        .unlocked_ioctl = ipmi_unlocked_ioctl,
 #ifdef CONFIG_COMPAT
-       .compat_ioctl   = compat_ipmi_ioctl,
+       .compat_ioctl   = unlocked_compat_ipmi_ioctl,
 #endif
        .open           = ipmi_open,
        .release        = ipmi_release,
index 4d439d2fcfd685a7e3e969aee8d7cef5e1cf14ee..4445fa164a2de5de14330af41847ad2bf1ef1c3d 100644 (file)
@@ -2037,12 +2037,11 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
        entry = kmalloc(sizeof(*entry), GFP_KERNEL);
        if (!entry)
                return -ENOMEM;
-       entry->name = kmalloc(strlen(name)+1, GFP_KERNEL);
+       entry->name = kstrdup(name, GFP_KERNEL);
        if (!entry->name) {
                kfree(entry);
                return -ENOMEM;
        }
-       strcpy(entry->name, name);
 
        file = proc_create_data(name, 0, smi->proc_dir, proc_ops, data);
        if (!file) {
index 313538abe63ceaef860b0a9b6a86ceb64a134907..af4b23ffc5a659c4d515e706c66fe80b202c056e 100644 (file)
@@ -663,8 +663,10 @@ static void handle_transaction_done(struct smi_info *smi_info)
                /* We got the flags from the SMI, now handle them. */
                smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
                if (msg[2] != 0) {
-                       dev_warn(smi_info->dev, "Could not enable interrupts"
-                                ", failed get, using polled mode.\n");
+                       dev_warn(smi_info->dev,
+                                "Couldn't get irq info: %x.\n", msg[2]);
+                       dev_warn(smi_info->dev,
+                                "Maybe ok, but ipmi might run very slowly.\n");
                        smi_info->si_state = SI_NORMAL;
                } else {
                        msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
@@ -685,10 +687,12 @@ static void handle_transaction_done(struct smi_info *smi_info)
 
                /* We got the flags from the SMI, now handle them. */
                smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
-               if (msg[2] != 0)
-                       dev_warn(smi_info->dev, "Could not enable interrupts"
-                                ", failed set, using polled mode.\n");
-               else
+               if (msg[2] != 0) {
+                       dev_warn(smi_info->dev,
+                                "Couldn't set irq info: %x.\n", msg[2]);
+                       dev_warn(smi_info->dev,
+                                "Maybe ok, but ipmi might run very slowly.\n");
+               } else
                        smi_info->interrupt_disabled = 0;
                smi_info->si_state = SI_NORMAL;
                break;
index dafd9ac6428f2de6e4c2120c675337307d8bd9d6..0913d79424d3a3e81930a4c138979a621de18605 100644 (file)
@@ -622,9 +622,12 @@ static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
                                return -EFAULT;
                        break;
                case LPGETSTATUS:
+                       if (mutex_lock_interruptible(&lp_table[minor].port_mutex))
+                               return -EINTR;
                        lp_claim_parport_or_block (&lp_table[minor]);
                        status = r_str(minor);
                        lp_release_parport (&lp_table[minor]);
+                       mutex_unlock(&lp_table[minor].port_mutex);
 
                        if (copy_to_user(argp, &status, sizeof(int)))
                                return -EFAULT;
index 4945bd3d18d0e9de294ba2f1fb8c996662820a39..d5d2e4a985aa8602ff75f840f6af7e963f68471d 100644 (file)
@@ -179,7 +179,6 @@ static int __init ttyprintk_init(void)
 {
        int ret = -ENOMEM;
 
-       tpk_port.port.ops = &null_ops;
        mutex_init(&tpk_port.port_write_mutex);
 
        ttyprintk_driver = tty_alloc_driver(1,
@@ -190,6 +189,7 @@ static int __init ttyprintk_init(void)
                return PTR_ERR(ttyprintk_driver);
 
        tty_port_init(&tpk_port.port);
+       tpk_port.port.ops = &null_ops;
 
        ttyprintk_driver->driver_name = "ttyprintk";
        ttyprintk_driver->name = "ttyprintk";
index a1488f58f6ca40eb0b660a82e97a54ce0246a430..534fcb8251538a31d2695313b1d565990f8d51d4 100644 (file)
@@ -47,7 +47,7 @@ config CPU_FREQ_STAT_DETAILS
 
 choice
        prompt "Default CPUFreq governor"
-       default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110
+       default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ || ARM_SA1110_CPUFREQ
        default CPU_FREQ_DEFAULT_GOV_PERFORMANCE
        help
          This option sets which CPUFreq governor shall be loaded at
index f3af18b9acc50f299b7f105b5e0b59effe5f4f33..6e57543fe0b981e55cfdd9623c5eb1ed910ffd8c 100644 (file)
@@ -3,16 +3,17 @@
 #
 
 config ARM_BIG_LITTLE_CPUFREQ
-       tristate
-       depends on ARM_CPU_TOPOLOGY
+       tristate "Generic ARM big LITTLE CPUfreq driver"
+       depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK
+       help
+         This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
 
 config ARM_DT_BL_CPUFREQ
-       tristate "Generic ARM big LITTLE CPUfreq driver probed via DT"
-       select ARM_BIG_LITTLE_CPUFREQ
-       depends on OF && HAVE_CLK
+       tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
+       depends on ARM_BIG_LITTLE_CPUFREQ && OF
        help
-         This enables the Generic CPUfreq driver for ARM big.LITTLE platform.
-         This gets frequency tables from DT.
+         This enables probing via DT for Generic CPUfreq driver for ARM
+         big.LITTLE platform. This gets frequency tables from DT.
 
 config ARM_EXYNOS_CPUFREQ
        bool "SAMSUNG EXYNOS SoCs"
index dbdf677d2f3610e4e28340a3785090b245d5c336..5d7f53fcd6f5eac052d4a0bfed4d48f531921d8c 100644 (file)
@@ -40,11 +40,6 @@ static struct clk *clk[MAX_CLUSTERS];
 static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS];
 static atomic_t cluster_usage[MAX_CLUSTERS] = {ATOMIC_INIT(0), ATOMIC_INIT(0)};
 
-static int cpu_to_cluster(int cpu)
-{
-       return topology_physical_package_id(cpu);
-}
-
 static unsigned int bL_cpufreq_get(unsigned int cpu)
 {
        u32 cur_cluster = cpu_to_cluster(cpu);
@@ -192,7 +187,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)
 
        cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu));
 
-       dev_info(cpu_dev, "CPU %d initialized\n", policy->cpu);
+       dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu);
        return 0;
 }
 
index 70f18fc12d4ad2a1a2c14f00ae1844e5378cdaee..79b2ce17884dd9cc645cb5a34c33e90290bba10a 100644 (file)
@@ -34,6 +34,11 @@ struct cpufreq_arm_bL_ops {
        int (*init_opp_table)(struct device *cpu_dev);
 };
 
+static inline int cpu_to_cluster(int cpu)
+{
+       return topology_physical_package_id(cpu);
+}
+
 int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops);
 void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops);
 
index 44be3115375ca968897b16726a3f9192ab0e1695..173ed059d95f5fa2d46093d69b7912d1074df3de 100644 (file)
@@ -66,8 +66,8 @@ static int dt_get_transition_latency(struct device *cpu_dev)
 
        parent = of_find_node_by_path("/cpus");
        if (!parent) {
-               pr_err("failed to find OF /cpus\n");
-               return -ENOENT;
+               pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n");
+               return CPUFREQ_ETERNAL;
        }
 
        for_each_child_of_node(parent, np) {
@@ -78,10 +78,11 @@ static int dt_get_transition_latency(struct device *cpu_dev)
                of_node_put(np);
                of_node_put(parent);
 
-               return 0;
+               return transition_latency;
        }
 
-       return -ENODEV;
+       pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n");
+       return CPUFREQ_ETERNAL;
 }
 
 static struct cpufreq_arm_bL_ops dt_bL_ops = {
index 3ab8294eab04f280f04ce3c2ea42b0fb2722fc86..a64eb8b70444b4a9cf183e8696117d28445a8efc 100644 (file)
@@ -189,12 +189,29 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
 
        if (!np) {
                pr_err("failed to find cpu0 node\n");
-               return -ENOENT;
+               ret = -ENOENT;
+               goto out_put_parent;
        }
 
        cpu_dev = &pdev->dev;
        cpu_dev->of_node = np;
 
+       cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
+       if (IS_ERR(cpu_reg)) {
+               /*
+                * If cpu0 regulator supply node is present, but regulator is
+                * not yet registered, we should try defering probe.
+                */
+               if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) {
+                       dev_err(cpu_dev, "cpu0 regulator not ready, retry\n");
+                       ret = -EPROBE_DEFER;
+                       goto out_put_node;
+               }
+               pr_warn("failed to get cpu0 regulator: %ld\n",
+                       PTR_ERR(cpu_reg));
+               cpu_reg = NULL;
+       }
+
        cpu_clk = devm_clk_get(cpu_dev, NULL);
        if (IS_ERR(cpu_clk)) {
                ret = PTR_ERR(cpu_clk);
@@ -202,12 +219,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
                goto out_put_node;
        }
 
-       cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
-       if (IS_ERR(cpu_reg)) {
-               pr_warn("failed to get cpu0 regulator\n");
-               cpu_reg = NULL;
-       }
-
        ret = of_init_opp_table(cpu_dev);
        if (ret) {
                pr_err("failed to init OPP table: %d\n", ret);
@@ -264,6 +275,8 @@ out_free_table:
        opp_free_cpufreq_table(cpu_dev, &freq_table);
 out_put_node:
        of_node_put(np);
+out_put_parent:
+       of_node_put(parent);
        return ret;
 }
 
index 1b8a48eaf90f1c4d2e541e9e03e58f03ca8b6d80..4b8c7f297d74db41778aa31b5e0fbcf4c389bda5 100644 (file)
@@ -1075,14 +1075,14 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
                                __func__, cpu_dev->id, cpu);
        }
 
+       if ((cpus == 1) && (cpufreq_driver->target))
+               __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
+
        pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
        cpufreq_cpu_put(data);
 
        /* If cpu is last user of policy, free policy */
        if (cpus == 1) {
-               if (cpufreq_driver->target)
-                       __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
-
                lock_policy_rwsem_read(cpu);
                kobj = &data->kobj;
                cmp = &data->kobj_unregister;
@@ -1832,15 +1832,13 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
        if (dev) {
                switch (action) {
                case CPU_ONLINE:
-               case CPU_ONLINE_FROZEN:
                        cpufreq_add_dev(dev, NULL);
                        break;
                case CPU_DOWN_PREPARE:
-               case CPU_DOWN_PREPARE_FROZEN:
+               case CPU_UP_CANCELED_FROZEN:
                        __cpufreq_remove_dev(dev, NULL);
                        break;
                case CPU_DOWN_FAILED:
-               case CPU_DOWN_FAILED_FROZEN:
                        cpufreq_add_dev(dev, NULL);
                        break;
                }
index 443442df113be73b33173c1a44109b4619508d7a..5af40ad82d231f7fd23bfd862590c30ab7d4b38e 100644 (file)
@@ -255,6 +255,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                if (have_governor_per_policy()) {
                        WARN_ON(dbs_data);
                } else if (dbs_data) {
+                       dbs_data->usage_count++;
                        policy->governor_data = dbs_data;
                        return 0;
                }
@@ -266,6 +267,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                }
 
                dbs_data->cdata = cdata;
+               dbs_data->usage_count = 1;
                rc = cdata->init(dbs_data);
                if (rc) {
                        pr_err("%s: POLICY_INIT: init() failed\n", __func__);
@@ -294,7 +296,8 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate,
                                        latency * LATENCY_MULTIPLIER));
 
-               if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
+               if ((cdata->governor == GOV_CONSERVATIVE) &&
+                               (!policy->governor->initialized)) {
                        struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
 
                        cpufreq_register_notifier(cs_ops->notifier_block,
@@ -306,12 +309,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 
                return 0;
        case CPUFREQ_GOV_POLICY_EXIT:
-               if ((policy->governor->initialized == 1) ||
-                               have_governor_per_policy()) {
+               if (!--dbs_data->usage_count) {
                        sysfs_remove_group(get_governor_parent_kobj(policy),
                                        get_sysfs_attr(dbs_data));
 
-                       if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
+                       if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
+                               (policy->governor->initialized == 1)) {
                                struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
 
                                cpufreq_unregister_notifier(cs_ops->notifier_block,
index 8ac33538d0bdb4f66cc7572f53db4c463190ae92..e16a96130cb3491d30f376728144cdca92e441cd 100644 (file)
@@ -211,6 +211,7 @@ struct common_dbs_data {
 struct dbs_data {
        struct common_dbs_data *cdata;
        unsigned int min_sampling_rate;
+       int usage_count;
        void *tuners;
 
        /* dbs_mutex protects dbs_enable in governor start/stop */
index b0ffef96bf77a2c1bcaf0680c6a500a7430a6858..4b9bb5def6f159a126e4f05aa6a76d365c6a23f8 100644 (file)
@@ -547,7 +547,6 @@ static int od_init(struct dbs_data *dbs_data)
        tuners->io_is_busy = should_io_be_busy();
 
        dbs_data->tuners = tuners;
-       pr_info("%s: tuners %p\n", __func__, tuners);
        mutex_init(&dbs_data->mutex);
        return 0;
 }
index bfd6273fd873531d864f3b4e104d37018a5d8dda..fb65decffa28128ded8817441b2e5eff8ecad8e3 100644 (file)
@@ -349,15 +349,16 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
 
        switch (action) {
        case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
                cpufreq_update_policy(cpu);
                break;
        case CPU_DOWN_PREPARE:
-       case CPU_DOWN_PREPARE_FROZEN:
                cpufreq_stats_free_sysfs(cpu);
                break;
        case CPU_DEAD:
-       case CPU_DEAD_FROZEN:
+               cpufreq_stats_free_table(cpu);
+               break;
+       case CPU_UP_CANCELED_FROZEN:
+               cpufreq_stats_free_sysfs(cpu);
                cpufreq_stats_free_table(cpu);
                break;
        }
index cc3a8e6c92beca8669e1e45e48051d9a9d26a81d..9c36ace92a39c4c0d501fb4692c91a19af132727 100644 (file)
@@ -48,12 +48,7 @@ static inline int32_t div_fp(int32_t x, int32_t y)
 }
 
 struct sample {
-       ktime_t start_time;
-       ktime_t end_time;
        int core_pct_busy;
-       int pstate_pct_busy;
-       u64 duration_us;
-       u64 idletime_us;
        u64 aperf;
        u64 mperf;
        int freq;
@@ -86,13 +81,9 @@ struct cpudata {
        struct pstate_adjust_policy *pstate_policy;
        struct pstate_data pstate;
        struct _pid pid;
-       struct _pid idle_pid;
 
        int min_pstate_count;
-       int idle_mode;
 
-       ktime_t prev_sample;
-       u64     prev_idle_time_us;
        u64     prev_aperf;
        u64     prev_mperf;
        int     sample_ptr;
@@ -124,6 +115,8 @@ struct perf_limits {
        int min_perf_pct;
        int32_t max_perf;
        int32_t min_perf;
+       int max_policy_pct;
+       int max_sysfs_pct;
 };
 
 static struct perf_limits limits = {
@@ -132,6 +125,8 @@ static struct perf_limits limits = {
        .max_perf = int_tofp(1),
        .min_perf_pct = 0,
        .min_perf = 0,
+       .max_policy_pct = 100,
+       .max_sysfs_pct = 100,
 };
 
 static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
@@ -202,19 +197,6 @@ static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu)
                0);
 }
 
-static inline void intel_pstate_idle_pid_reset(struct cpudata *cpu)
-{
-       pid_p_gain_set(&cpu->idle_pid, cpu->pstate_policy->p_gain_pct);
-       pid_d_gain_set(&cpu->idle_pid, cpu->pstate_policy->d_gain_pct);
-       pid_i_gain_set(&cpu->idle_pid, cpu->pstate_policy->i_gain_pct);
-
-       pid_reset(&cpu->idle_pid,
-               75,
-               50,
-               cpu->pstate_policy->deadband,
-               0);
-}
-
 static inline void intel_pstate_reset_all_pid(void)
 {
        unsigned int cpu;
@@ -302,7 +284,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
        if (ret != 1)
                return -EINVAL;
 
-       limits.max_perf_pct = clamp_t(int, input, 0 , 100);
+       limits.max_sysfs_pct = clamp_t(int, input, 0 , 100);
+       limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
        limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
        return count;
 }
@@ -408,9 +391,8 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
        if (pstate == cpu->pstate.current_pstate)
                return;
 
-#ifndef MODULE
        trace_cpu_frequency(pstate * 100000, cpu->cpu);
-#endif
+
        cpu->pstate.current_pstate = pstate;
        wrmsrl(MSR_IA32_PERF_CTL, pstate << 8);
 
@@ -450,48 +432,26 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
                                        struct sample *sample)
 {
        u64 core_pct;
-       sample->pstate_pct_busy = 100 - div64_u64(
-                                       sample->idletime_us * 100,
-                                       sample->duration_us);
        core_pct = div64_u64(sample->aperf * 100, sample->mperf);
        sample->freq = cpu->pstate.max_pstate * core_pct * 1000;
 
-       sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct),
-                                       100);
+       sample->core_pct_busy = core_pct;
 }
 
 static inline void intel_pstate_sample(struct cpudata *cpu)
 {
-       ktime_t now;
-       u64 idle_time_us;
        u64 aperf, mperf;
 
-       now = ktime_get();
-       idle_time_us = get_cpu_idle_time_us(cpu->cpu, NULL);
-
        rdmsrl(MSR_IA32_APERF, aperf);
        rdmsrl(MSR_IA32_MPERF, mperf);
-       /* for the first sample, don't actually record a sample, just
-        * set the baseline */
-       if (cpu->prev_idle_time_us > 0) {
-               cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
-               cpu->samples[cpu->sample_ptr].start_time = cpu->prev_sample;
-               cpu->samples[cpu->sample_ptr].end_time = now;
-               cpu->samples[cpu->sample_ptr].duration_us =
-                       ktime_us_delta(now, cpu->prev_sample);
-               cpu->samples[cpu->sample_ptr].idletime_us =
-                       idle_time_us - cpu->prev_idle_time_us;
-
-               cpu->samples[cpu->sample_ptr].aperf = aperf;
-               cpu->samples[cpu->sample_ptr].mperf = mperf;
-               cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
-               cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
-
-               intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);
-       }
+       cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT;
+       cpu->samples[cpu->sample_ptr].aperf = aperf;
+       cpu->samples[cpu->sample_ptr].mperf = mperf;
+       cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf;
+       cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf;
+
+       intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]);
 
-       cpu->prev_sample = now;
-       cpu->prev_idle_time_us = idle_time_us;
        cpu->prev_aperf = aperf;
        cpu->prev_mperf = mperf;
 }
@@ -505,16 +465,6 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
        mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
-static inline void intel_pstate_idle_mode(struct cpudata *cpu)
-{
-       cpu->idle_mode = 1;
-}
-
-static inline void intel_pstate_normal_mode(struct cpudata *cpu)
-{
-       cpu->idle_mode = 0;
-}
-
 static inline int intel_pstate_get_scaled_busy(struct cpudata *cpu)
 {
        int32_t busy_scaled;
@@ -547,50 +497,21 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
                intel_pstate_pstate_decrease(cpu, steps);
 }
 
-static inline void intel_pstate_adjust_idle_pstate(struct cpudata *cpu)
-{
-       int busy_scaled;
-       struct _pid *pid;
-       int ctl = 0;
-       int steps;
-
-       pid = &cpu->idle_pid;
-
-       busy_scaled = intel_pstate_get_scaled_busy(cpu);
-
-       ctl = pid_calc(pid, 100 - busy_scaled);
-
-       steps = abs(ctl);
-       if (ctl < 0)
-               intel_pstate_pstate_decrease(cpu, steps);
-       else
-               intel_pstate_pstate_increase(cpu, steps);
-
-       if (cpu->pstate.current_pstate == cpu->pstate.min_pstate)
-               intel_pstate_normal_mode(cpu);
-}
-
 static void intel_pstate_timer_func(unsigned long __data)
 {
        struct cpudata *cpu = (struct cpudata *) __data;
 
        intel_pstate_sample(cpu);
+       intel_pstate_adjust_busy_pstate(cpu);
 
-       if (!cpu->idle_mode)
-               intel_pstate_adjust_busy_pstate(cpu);
-       else
-               intel_pstate_adjust_idle_pstate(cpu);
-
-#if defined(XPERF_FIX)
        if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) {
                cpu->min_pstate_count++;
                if (!(cpu->min_pstate_count % 5)) {
                        intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
-                       intel_pstate_idle_mode(cpu);
                }
        } else
                cpu->min_pstate_count = 0;
-#endif
+
        intel_pstate_set_sample_time(cpu);
 }
 
@@ -631,7 +552,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
                (unsigned long)cpu;
        cpu->timer.expires = jiffies + HZ/100;
        intel_pstate_busy_pid_reset(cpu);
-       intel_pstate_idle_pid_reset(cpu);
        intel_pstate_sample(cpu);
        intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
 
@@ -675,8 +595,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
        limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100);
        limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
 
-       limits.max_perf_pct = policy->max * 100 / policy->cpuinfo.max_freq;
-       limits.max_perf_pct = clamp_t(int, limits.max_perf_pct, 0 , 100);
+       limits.max_policy_pct = policy->max * 100 / policy->cpuinfo.max_freq;
+       limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100);
+       limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
        limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
 
        return 0;
@@ -788,10 +709,9 @@ static int __init intel_pstate_init(void)
 
        pr_info("Intel P-state driver initializing.\n");
 
-       all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus());
+       all_cpu_data = vzalloc(sizeof(void *) * num_possible_cpus());
        if (!all_cpu_data)
                return -ENOMEM;
-       memset(all_cpu_data, 0, sizeof(void *) * num_possible_cpus());
 
        rc = cpufreq_register_driver(&intel_pstate_driver);
        if (rc)
index d36ea8dc96eb9fdc0812e0e93512f8f97cda66f8..b2644af985ec8e741daf009262069694c671513b 100644 (file)
@@ -171,10 +171,6 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
        priv.dev = &pdev->dev;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Cannot get memory resource\n");
-               return -ENODEV;
-       }
        priv.base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(priv.base))
                return PTR_ERR(priv.base);
index 84889573b5669f22e1632108c5f32b94285d5814..d53912768946b96c1c27b017dbaeb7a10e7c2feb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 
 #include <asm/clock.h>
+#include <asm/idle.h>
 
 #include <asm/mach-loongson/loongson.h>
 
@@ -200,6 +201,7 @@ static void loongson2_cpu_wait(void)
        LOONGSON_CHIPCFG0 &= ~0x7;      /* Put CPU into wait mode */
        LOONGSON_CHIPCFG0 = cpu_freq;   /* Restore CPU state */
        spin_unlock_irqrestore(&loongson2_wait_lock, flags);
+       local_irq_enable();
 }
 
 static int __init cpufreq_init(void)
index ce193409ebd32345e997dad798625c41565b438e..33f59ecd256e1487ce3dca17cd5f0822e2308c34 100644 (file)
@@ -1273,11 +1273,6 @@ static int tegra_dma_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, tdma);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "No mem resource for DMA\n");
-               return -EINVAL;
-       }
-
        tdma->base_addr = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(tdma->base_addr))
                return PTR_ERR(tdma->base_addr);
index bf69a7eff370cbabc72ba01591727ba20c81338c..3a4816adc137de912b51fca601c50d65f8baea19 100644 (file)
@@ -619,11 +619,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
         * per-CPU registers */
        if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-               if (!res) {
-                       dev_err(&pdev->dev, "Cannot get memory resource\n");
-                       return -ENODEV;
-               }
-
                mvchip->percpu_membase = devm_ioremap_resource(&pdev->dev,
                                                               res);
                if (IS_ERR(mvchip->percpu_membase))
index da4cb5b0cb87612fed241b9a4ebc6245716377cd..9a62672f1bed97185b26132966dd0ddcb50534f3 100644 (file)
@@ -463,11 +463,6 @@ static int tegra_gpio_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Missing MEM resource\n");
-               return -ENODEV;
-       }
-
        regs = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(regs))
                return PTR_ERR(regs);
index 3a8f7e6db2950fc175759e558c7663ae84d3702f..e7e92429d10f9e36d80d48e5f8a0004e4eb0284e 100644 (file)
@@ -78,6 +78,10 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
 {
        struct drm_crtc *crtc;
 
+       /* Locking is currently fubar in the panic handler. */
+       if (oops_in_progress)
+               return;
+
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
                WARN_ON(!mutex_is_locked(&crtc->mutex));
 
@@ -246,6 +250,7 @@ char *drm_get_connector_status_name(enum drm_connector_status status)
        else
                return "unknown";
 }
+EXPORT_SYMBOL(drm_get_connector_status_name);
 
 /**
  * drm_mode_object_get - allocate a new modeset identifier
index e974f9309b72697d3c9918ab979c8469d548c25d..ed1334e27c33283442fceb604892e55666bdfe2c 100644 (file)
@@ -121,6 +121,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
                connector->helper_private;
        int count = 0;
        int mode_flags = 0;
+       bool verbose_prune = true;
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
                        drm_get_connector_name(connector));
@@ -149,6 +150,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
                DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
                        connector->base.id, drm_get_connector_name(connector));
                drm_mode_connector_update_edid_property(connector, NULL);
+               verbose_prune = false;
                goto prune;
        }
 
@@ -182,7 +184,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
        }
 
 prune:
-       drm_mode_prune_invalid(dev, &connector->modes, true);
+       drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
 
        if (list_empty(&connector->modes))
                return 0;
@@ -1005,12 +1007,20 @@ static void output_poll_execute(struct work_struct *work)
                        continue;
 
                connector->status = connector->funcs->detect(connector, false);
-               DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
-                             connector->base.id,
-                             drm_get_connector_name(connector),
-                             old_status, connector->status);
-               if (old_status != connector->status)
+               if (old_status != connector->status) {
+                       const char *old, *new;
+
+                       old = drm_get_connector_status_name(old_status);
+                       new = drm_get_connector_status_name(connector->status);
+
+                       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
+                                     "status updated from %s to %s\n",
+                                     connector->base.id,
+                                     drm_get_connector_name(connector),
+                                     old, new);
+
                        changed = true;
+               }
        }
 
        mutex_unlock(&dev->mode_config.mutex);
@@ -1083,10 +1093,11 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
                old_status = connector->status;
 
                connector->status = connector->funcs->detect(connector, false);
-               DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+               DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
                              connector->base.id,
                              drm_get_connector_name(connector),
-                             old_status, connector->status);
+                             drm_get_connector_status_name(old_status),
+                             drm_get_connector_status_name(connector->status));
                if (old_status != connector->status)
                        changed = true;
        }
index 8d4f29075af5bd24f0b03461cac4d35c511530dd..9cc247f555028f41046cbacd57a6b31cdf8f5e20 100644 (file)
@@ -57,7 +57,7 @@ static int drm_version(struct drm_device *dev, void *data,
                       struct drm_file *file_priv);
 
 #define DRM_IOCTL_DEF(ioctl, _func, _flags) \
-       [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0}
+       [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
 
 /** Ioctl table */
 static const struct drm_ioctl_desc drm_ioctls[] = {
@@ -375,7 +375,7 @@ long drm_ioctl(struct file *filp,
 {
        struct drm_file *file_priv = filp->private_data;
        struct drm_device *dev;
-       const struct drm_ioctl_desc *ioctl;
+       const struct drm_ioctl_desc *ioctl = NULL;
        drm_ioctl_t *func;
        unsigned int nr = DRM_IOCTL_NR(cmd);
        int retcode = -EINVAL;
@@ -392,11 +392,6 @@ long drm_ioctl(struct file *filp,
        atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
        ++file_priv->ioctl_count;
 
-       DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
-                 task_pid_nr(current), cmd, nr,
-                 (long)old_encode_dev(file_priv->minor->device),
-                 file_priv->authenticated);
-
        if ((nr >= DRM_CORE_IOCTL_COUNT) &&
            ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
                goto err_i1;
@@ -417,6 +412,11 @@ long drm_ioctl(struct file *filp,
        } else
                goto err_i1;
 
+       DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
+                 task_pid_nr(current),
+                 (long)old_encode_dev(file_priv->minor->device),
+                 file_priv->authenticated, ioctl->name);
+
        /* Do not trust userspace, use our own definition */
        func = ioctl->func;
        /* is there a local override? */
@@ -471,6 +471,12 @@ long drm_ioctl(struct file *filp,
        }
 
       err_i1:
+       if (!ioctl)
+               DRM_DEBUG("invalid iotcl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
+                         task_pid_nr(current),
+                         (long)old_encode_dev(file_priv->minor->device),
+                         file_priv->authenticated, cmd, nr);
+
        if (kdata != stack_kdata)
                kfree(kdata);
        atomic_dec(&dev->ioctl_count);
index 48c52f7df4e63affac527e1f86e06188a03e2021..0cfb60f5476655edc097ca71c648d11544f3357e 100644 (file)
@@ -54,16 +54,12 @@ int drm_i2c_encoder_init(struct drm_device *dev,
                         struct i2c_adapter *adap,
                         const struct i2c_board_info *info)
 {
-       char modalias[sizeof(I2C_MODULE_PREFIX)
-                     + I2C_NAME_SIZE];
        struct module *module = NULL;
        struct i2c_client *client;
        struct drm_i2c_encoder_driver *encoder_drv;
        int err = 0;
 
-       snprintf(modalias, sizeof(modalias),
-                "%s%s", I2C_MODULE_PREFIX, info->type);
-       request_module(modalias);
+       request_module("%s%s", I2C_MODULE_PREFIX, info->type);
 
        client = i2c_new_device(adap, info);
        if (!client) {
index db1e2d6f90d7221d713c04b70560d85a08ad6732..07cf99cc886283aedf9feee690d71ee6fbe2fb77 100644 (file)
@@ -755,33 +755,35 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
 EXPORT_SYMBOL(drm_mm_debug_table);
 
 #if defined(CONFIG_DEBUG_FS)
-int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
+static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry)
 {
-       struct drm_mm_node *entry;
-       unsigned long total_used = 0, total_free = 0, total = 0;
        unsigned long hole_start, hole_end, hole_size;
 
-       hole_start = drm_mm_hole_node_start(&mm->head_node);
-       hole_end = drm_mm_hole_node_end(&mm->head_node);
-       hole_size = hole_end - hole_start;
-       if (hole_size)
+       if (entry->hole_follows) {
+               hole_start = drm_mm_hole_node_start(entry);
+               hole_end = drm_mm_hole_node_end(entry);
+               hole_size = hole_end - hole_start;
                seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n",
                                hole_start, hole_end, hole_size);
-       total_free += hole_size;
+               return hole_size;
+       }
+
+       return 0;
+}
+
+int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
+{
+       struct drm_mm_node *entry;
+       unsigned long total_used = 0, total_free = 0, total = 0;
+
+       total_free += drm_mm_dump_hole(m, &mm->head_node);
 
        drm_mm_for_each_node(entry, mm) {
                seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n",
                                entry->start, entry->start + entry->size,
                                entry->size);
                total_used += entry->size;
-               if (entry->hole_follows) {
-                       hole_start = drm_mm_hole_node_start(entry);
-                       hole_end = drm_mm_hole_node_end(entry);
-                       hole_size = hole_end - hole_start;
-                       seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n",
-                                       hole_start, hole_end, hole_size);
-                       total_free += hole_size;
-               }
+               total_free += drm_mm_dump_hole(m, entry);
        }
        total = total_free + total_used;
 
index faa79df0264802e985719da65be37ee369a87a69..a371ff865a887755b81de57663a819429a34ed4c 100644 (file)
@@ -1143,6 +1143,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
                                was_digit = false;
                        } else
                                goto done;
+                       break;
                case '0' ... '9':
                        was_digit = true;
                        break;
index bbfc3840080cf03b718e76fb0aa9f3119ec4ba24..6652597586a18415280e790da3c5ac6b591c4d31 100644 (file)
@@ -2005,11 +2005,6 @@ static int hdmi_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               DRM_ERROR("failed to find registers\n");
-               return -ENOENT;
-       }
-
        hdata->regs = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(hdata->regs))
                return PTR_ERR(hdata->regs);
index 6be940effefd1cf3dd69262e826c9cc999e4c26c..6165535d15f07af8969a74f075994d31bfbae47e 100644 (file)
@@ -1045,6 +1045,8 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
        if (timeout) {
                struct timespec sleep_time = timespec_sub(now, before);
                *timeout = timespec_sub(*timeout, sleep_time);
+               if (!timespec_valid(timeout)) /* i.e. negative time remains */
+                       set_normalized_timespec(timeout, 0, 0);
        }
 
        switch (end) {
@@ -1053,8 +1055,6 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
        case -ERESTARTSYS: /* Signal */
                return (int)end;
        case 0: /* Timeout */
-               if (timeout)
-                       set_normalized_timespec(timeout, 0, 0);
                return -ETIME;
        default: /* Completed */
                WARN_ON(end < 0); /* We're not aware of other errors */
@@ -2377,10 +2377,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
        mutex_unlock(&dev->struct_mutex);
 
        ret = __wait_seqno(ring, seqno, reset_counter, true, timeout);
-       if (timeout) {
-               WARN_ON(!timespec_valid(timeout));
+       if (timeout)
                args->timeout_ns = timespec_to_ns(timeout);
-       }
        return ret;
 
 out:
index dca614de71b6a34189bb40fa0a99cc0f60fcb6ec..bdb0d7717bc77937dce3c4de563f1e7066c7bb2e 100644 (file)
@@ -709,15 +709,6 @@ static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl)
        return snb_gmch_ctl << 25; /* 32 MB units */
 }
 
-static inline size_t gen7_get_stolen_size(u16 snb_gmch_ctl)
-{
-       static const int stolen_decoder[] = {
-               0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352};
-       snb_gmch_ctl >>= IVB_GMCH_GMS_SHIFT;
-       snb_gmch_ctl &= IVB_GMCH_GMS_MASK;
-       return stolen_decoder[snb_gmch_ctl] << 20;
-}
-
 static int gen6_gmch_probe(struct drm_device *dev,
                           size_t *gtt_total,
                           size_t *stolen,
@@ -747,11 +738,7 @@ static int gen6_gmch_probe(struct drm_device *dev,
        pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
        gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl);
 
-       if (IS_GEN7(dev) && !IS_VALLEYVIEW(dev))
-               *stolen = gen7_get_stolen_size(snb_gmch_ctl);
-       else
-               *stolen = gen6_get_stolen_size(snb_gmch_ctl);
-
+       *stolen = gen6_get_stolen_size(snb_gmch_ctl);
        *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT;
 
        /* For Modern GENs the PTEs and register space are split in the BAR */
index 83f9c26e1adbf7b9451e02303545eb1b076b03fa..2d6b62e42daf324478ea64bc49e6e722330c3e2b 100644 (file)
@@ -46,8 +46,6 @@
 #define    SNB_GMCH_GGMS_MASK  0x3
 #define    SNB_GMCH_GMS_SHIFT   3 /* Graphics Mode Select */
 #define    SNB_GMCH_GMS_MASK    0x1f
-#define    IVB_GMCH_GMS_SHIFT   4
-#define    IVB_GMCH_GMS_MASK    0xf
 
 
 /* PCI config space */
index 26a0a570f92e0eba28fa443b28176252a7bb577d..fb961bb81903c95550289845a846bd0308c448d7 100644 (file)
@@ -1265,6 +1265,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
                intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
                intel_dp_start_link_train(intel_dp);
                intel_dp_complete_link_train(intel_dp);
+               if (port != PORT_A)
+                       intel_dp_stop_link_train(intel_dp);
        }
 }
 
@@ -1326,6 +1328,9 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
        } else if (type == INTEL_OUTPUT_EDP) {
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
+               if (port == PORT_A)
+                       intel_dp_stop_link_train(intel_dp);
+
                ironlake_edp_backlight_on(intel_dp);
        }
 
index fb2fbc1e08b9ba0048b17c02badb8fd8ed29d089..3d704b706a8d42d974e70f4fa3e095fbcbcdb910 100644 (file)
@@ -702,6 +702,9 @@ intel_dp_compute_config(struct intel_encoder *encoder,
        /* Walk through all bpp values. Luckily they're all nicely spaced with 2
         * bpc in between. */
        bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
+       if (is_edp(intel_dp) && dev_priv->edp.bpp)
+               bpp = min_t(int, bpp, dev_priv->edp.bpp);
+
        for (; bpp >= 6*3; bpp -= 2*3) {
                mode_rate = intel_dp_link_required(target_clock, bpp);
 
@@ -739,6 +742,7 @@ found:
        intel_dp->link_bw = bws[clock];
        intel_dp->lane_count = lane_count;
        adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
+       pipe_config->pipe_bpp = bpp;
        pipe_config->pixel_target_clock = target_clock;
 
        DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
@@ -751,20 +755,6 @@ found:
                               target_clock, adjusted_mode->clock,
                               &pipe_config->dp_m_n);
 
-       /*
-        * XXX: We have a strange regression where using the vbt edp bpp value
-        * for the link bw computation results in black screens, the panel only
-        * works when we do the computation at the usual 24bpp (but still
-        * requires us to use 18bpp). Until that's fully debugged, stay
-        * bug-for-bug compatible with the old code.
-        */
-       if (is_edp(intel_dp) && dev_priv->edp.bpp) {
-               DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n",
-                             bpp, dev_priv->edp.bpp);
-               bpp = min_t(int, bpp, dev_priv->edp.bpp);
-       }
-       pipe_config->pipe_bpp = bpp;
-
        return true;
 }
 
@@ -1389,6 +1379,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
        ironlake_edp_panel_on(intel_dp);
        ironlake_edp_panel_vdd_off(intel_dp, true);
        intel_dp_complete_link_train(intel_dp);
+       intel_dp_stop_link_train(intel_dp);
        ironlake_edp_backlight_on(intel_dp);
 }
 
@@ -1711,10 +1702,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum port port = intel_dig_port->port;
        int ret;
-       uint32_t temp;
 
        if (HAS_DDI(dev)) {
-               temp = I915_READ(DP_TP_CTL(port));
+               uint32_t temp = I915_READ(DP_TP_CTL(port));
 
                if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
                        temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
@@ -1724,18 +1714,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
                temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
                switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
                case DP_TRAINING_PATTERN_DISABLE:
-
-                       if (port != PORT_A) {
-                               temp |= DP_TP_CTL_LINK_TRAIN_IDLE;
-                               I915_WRITE(DP_TP_CTL(port), temp);
-
-                               if (wait_for((I915_READ(DP_TP_STATUS(port)) &
-                                             DP_TP_STATUS_IDLE_DONE), 1))
-                                       DRM_ERROR("Timed out waiting for DP idle patterns\n");
-
-                               temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
-                       }
-
                        temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
 
                        break;
@@ -1811,6 +1789,37 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
        return true;
 }
 
+static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
+{
+       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+       struct drm_device *dev = intel_dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum port port = intel_dig_port->port;
+       uint32_t val;
+
+       if (!HAS_DDI(dev))
+               return;
+
+       val = I915_READ(DP_TP_CTL(port));
+       val &= ~DP_TP_CTL_LINK_TRAIN_MASK;
+       val |= DP_TP_CTL_LINK_TRAIN_IDLE;
+       I915_WRITE(DP_TP_CTL(port), val);
+
+       /*
+        * On PORT_A we can have only eDP in SST mode. There the only reason
+        * we need to set idle transmission mode is to work around a HW issue
+        * where we enable the pipe while not in idle link-training mode.
+        * In this case there is requirement to wait for a minimum number of
+        * idle patterns to be sent.
+        */
+       if (port == PORT_A)
+               return;
+
+       if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_IDLE_DONE),
+                    1))
+               DRM_ERROR("Timed out waiting for DP idle patterns\n");
+}
+
 /* Enable corresponding port and start training pattern 1 */
 void
 intel_dp_start_link_train(struct intel_dp *intel_dp)
@@ -1953,10 +1962,19 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                ++tries;
        }
 
+       intel_dp_set_idle_link_train(intel_dp);
+
+       intel_dp->DP = DP;
+
        if (channel_eq)
                DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
 
-       intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE);
+}
+
+void intel_dp_stop_link_train(struct intel_dp *intel_dp)
+{
+       intel_dp_set_link_train(intel_dp, intel_dp->DP,
+                               DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void
@@ -2164,6 +2182,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
                              drm_get_encoder_name(&intel_encoder->base));
                intel_dp_start_link_train(intel_dp);
                intel_dp_complete_link_train(intel_dp);
+               intel_dp_stop_link_train(intel_dp);
        }
 }
 
index b5b6d19e6dd3ff30293799980d1efafef6540812..624a9e6b8d718ebe64a3aa41019137b673b3b296 100644 (file)
@@ -499,6 +499,7 @@ extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
 extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
 extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
+extern void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
 extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
index 0e19e575a1b41e456cbe3e82877502fa1906c875..6b7c3ca2c035e5514c2c333877966ff1cb3d3cfd 100644 (file)
@@ -262,10 +262,22 @@ void intel_fbdev_fini(struct drm_device *dev)
 void intel_fbdev_set_suspend(struct drm_device *dev, int state)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       if (!dev_priv->fbdev)
+       struct intel_fbdev *ifbdev = dev_priv->fbdev;
+       struct fb_info *info;
+
+       if (!ifbdev)
                return;
 
-       fb_set_suspend(dev_priv->fbdev->helper.fbdev, state);
+       info = ifbdev->helper.fbdev;
+
+       /* On resume from hibernation: If the object is shmemfs backed, it has
+        * been restored from swap. If the object is stolen however, it will be
+        * full of whatever garbage was left in there.
+        */
+       if (!state && ifbdev->ifb.obj->stolen)
+               memset_io(info->screen_base, 0, info->screen_size);
+
+       fb_set_suspend(info, state);
 }
 
 MODULE_LICENSE("GPL and additional rights");
index de3b0dc5658bcf0c84081ec23ee1cc0add9d93c5..aa01128ff192cc6c5860c881a9aa8a71cb756fd7 100644 (file)
@@ -1301,17 +1301,17 @@ static void valleyview_update_wm(struct drm_device *dev)
 
        vlv_update_drain_latency(dev);
 
-       if (g4x_compute_wm0(dev, 0,
+       if (g4x_compute_wm0(dev, PIPE_A,
                            &valleyview_wm_info, latency_ns,
                            &valleyview_cursor_wm_info, latency_ns,
                            &planea_wm, &cursora_wm))
-               enabled |= 1;
+               enabled |= 1 << PIPE_A;
 
-       if (g4x_compute_wm0(dev, 1,
+       if (g4x_compute_wm0(dev, PIPE_B,
                            &valleyview_wm_info, latency_ns,
                            &valleyview_cursor_wm_info, latency_ns,
                            &planeb_wm, &cursorb_wm))
-               enabled |= 2;
+               enabled |= 1 << PIPE_B;
 
        if (single_plane_enabled(enabled) &&
            g4x_compute_srwm(dev, ffs(enabled) - 1,
@@ -1357,17 +1357,17 @@ static void g4x_update_wm(struct drm_device *dev)
        int plane_sr, cursor_sr;
        unsigned int enabled = 0;
 
-       if (g4x_compute_wm0(dev, 0,
+       if (g4x_compute_wm0(dev, PIPE_A,
                            &g4x_wm_info, latency_ns,
                            &g4x_cursor_wm_info, latency_ns,
                            &planea_wm, &cursora_wm))
-               enabled |= 1;
+               enabled |= 1 << PIPE_A;
 
-       if (g4x_compute_wm0(dev, 1,
+       if (g4x_compute_wm0(dev, PIPE_B,
                            &g4x_wm_info, latency_ns,
                            &g4x_cursor_wm_info, latency_ns,
                            &planeb_wm, &cursorb_wm))
-               enabled |= 2;
+               enabled |= 1 << PIPE_B;
 
        if (single_plane_enabled(enabled) &&
            g4x_compute_srwm(dev, ffs(enabled) - 1,
@@ -1716,7 +1716,7 @@ static void ironlake_update_wm(struct drm_device *dev)
        unsigned int enabled;
 
        enabled = 0;
-       if (g4x_compute_wm0(dev, 0,
+       if (g4x_compute_wm0(dev, PIPE_A,
                            &ironlake_display_wm_info,
                            ILK_LP0_PLANE_LATENCY,
                            &ironlake_cursor_wm_info,
@@ -1727,10 +1727,10 @@ static void ironlake_update_wm(struct drm_device *dev)
                DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
                              " plane %d, " "cursor: %d\n",
                              plane_wm, cursor_wm);
-               enabled |= 1;
+               enabled |= 1 << PIPE_A;
        }
 
-       if (g4x_compute_wm0(dev, 1,
+       if (g4x_compute_wm0(dev, PIPE_B,
                            &ironlake_display_wm_info,
                            ILK_LP0_PLANE_LATENCY,
                            &ironlake_cursor_wm_info,
@@ -1741,7 +1741,7 @@ static void ironlake_update_wm(struct drm_device *dev)
                DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
                              " plane %d, cursor: %d\n",
                              plane_wm, cursor_wm);
-               enabled |= 2;
+               enabled |= 1 << PIPE_B;
        }
 
        /*
@@ -1801,7 +1801,7 @@ static void sandybridge_update_wm(struct drm_device *dev)
        unsigned int enabled;
 
        enabled = 0;
-       if (g4x_compute_wm0(dev, 0,
+       if (g4x_compute_wm0(dev, PIPE_A,
                            &sandybridge_display_wm_info, latency,
                            &sandybridge_cursor_wm_info, latency,
                            &plane_wm, &cursor_wm)) {
@@ -1812,10 +1812,10 @@ static void sandybridge_update_wm(struct drm_device *dev)
                DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
                              " plane %d, " "cursor: %d\n",
                              plane_wm, cursor_wm);
-               enabled |= 1;
+               enabled |= 1 << PIPE_A;
        }
 
-       if (g4x_compute_wm0(dev, 1,
+       if (g4x_compute_wm0(dev, PIPE_B,
                            &sandybridge_display_wm_info, latency,
                            &sandybridge_cursor_wm_info, latency,
                            &plane_wm, &cursor_wm)) {
@@ -1826,7 +1826,7 @@ static void sandybridge_update_wm(struct drm_device *dev)
                DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
                              " plane %d, cursor: %d\n",
                              plane_wm, cursor_wm);
-               enabled |= 2;
+               enabled |= 1 << PIPE_B;
        }
 
        /*
@@ -1904,7 +1904,7 @@ static void ivybridge_update_wm(struct drm_device *dev)
        unsigned int enabled;
 
        enabled = 0;
-       if (g4x_compute_wm0(dev, 0,
+       if (g4x_compute_wm0(dev, PIPE_A,
                            &sandybridge_display_wm_info, latency,
                            &sandybridge_cursor_wm_info, latency,
                            &plane_wm, &cursor_wm)) {
@@ -1915,10 +1915,10 @@ static void ivybridge_update_wm(struct drm_device *dev)
                DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
                              " plane %d, " "cursor: %d\n",
                              plane_wm, cursor_wm);
-               enabled |= 1;
+               enabled |= 1 << PIPE_A;
        }
 
-       if (g4x_compute_wm0(dev, 1,
+       if (g4x_compute_wm0(dev, PIPE_B,
                            &sandybridge_display_wm_info, latency,
                            &sandybridge_cursor_wm_info, latency,
                            &plane_wm, &cursor_wm)) {
@@ -1929,10 +1929,10 @@ static void ivybridge_update_wm(struct drm_device *dev)
                DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
                              " plane %d, cursor: %d\n",
                              plane_wm, cursor_wm);
-               enabled |= 2;
+               enabled |= 1 << PIPE_B;
        }
 
-       if (g4x_compute_wm0(dev, 2,
+       if (g4x_compute_wm0(dev, PIPE_C,
                            &sandybridge_display_wm_info, latency,
                            &sandybridge_cursor_wm_info, latency,
                            &plane_wm, &cursor_wm)) {
@@ -1943,7 +1943,7 @@ static void ivybridge_update_wm(struct drm_device *dev)
                DRM_DEBUG_KMS("FIFO watermarks For pipe C -"
                              " plane %d, cursor: %d\n",
                              plane_wm, cursor_wm);
-               enabled |= 3;
+               enabled |= 1 << PIPE_C;
        }
 
        /*
index f9889658329bfd1aa613cc595a143511e9f94386..77b8a45fb10a3c872aa86304f22abf16266a0249 100644 (file)
@@ -46,29 +46,26 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc)
 
 static inline void mga_wait_vsync(struct mga_device *mdev)
 {
-       unsigned int count = 0;
+       unsigned long timeout = jiffies + HZ/10;
        unsigned int status = 0;
 
        do {
                status = RREG32(MGAREG_Status);
-               count++;
-       } while ((status & 0x08) && (count < 250000));
-       count = 0;
+       } while ((status & 0x08) && time_before(jiffies, timeout));
+       timeout = jiffies + HZ/10;
        status = 0;
        do {
                status = RREG32(MGAREG_Status);
-               count++;
-       } while (!(status & 0x08) && (count < 250000));
+       } while (!(status & 0x08) && time_before(jiffies, timeout));
 }
 
 static inline void mga_wait_busy(struct mga_device *mdev)
 {
-       unsigned int count = 0;
+       unsigned long timeout = jiffies + HZ;
        unsigned int status = 0;
        do {
                status = RREG8(MGAREG_Status + 2);
-               count++;
-       } while ((status & 0x01) && (count < 500000));
+       } while ((status & 0x01) && time_before(jiffies, timeout));
 }
 
 /*
@@ -189,12 +186,12 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
                tmp = RREG8(DAC_DATA);
                tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
-               WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
+               WREG8(DAC_DATA, tmp);
 
                WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
                tmp = RREG8(DAC_DATA);
                tmp |= MGA1064_REMHEADCTL_CLKDIS;
-               WREG_DAC(MGA1064_REMHEADCTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                /* select PLL Set C */
                tmp = RREG8(MGAREG_MEM_MISC_READ);
@@ -204,7 +201,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
                tmp = RREG8(DAC_DATA);
                tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
-               WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                udelay(500);
 
@@ -212,7 +209,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
                WREG8(DAC_INDEX, MGA1064_VREF_CTL);
                tmp = RREG8(DAC_DATA);
                tmp &= ~0x04;
-               WREG_DAC(MGA1064_VREF_CTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                udelay(50);
 
@@ -236,13 +233,13 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
                tmp = RREG8(DAC_DATA);
                tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
                tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
-               WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
                tmp = RREG8(DAC_DATA);
                tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
                tmp |= MGA1064_REMHEADCTL_CLKSL_PLL;
-               WREG_DAC(MGA1064_REMHEADCTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                /* reset dotclock rate bit */
                WREG8(MGAREG_SEQ_INDEX, 1);
@@ -253,7 +250,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
                tmp = RREG8(DAC_DATA);
                tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
-               WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                vcount = RREG8(MGAREG_VCOUNT);
 
@@ -318,7 +315,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
        tmp = RREG8(DAC_DATA);
        tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
-       WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
+       WREG8(DAC_DATA, tmp);
 
        tmp = RREG8(MGAREG_MEM_MISC_READ);
        tmp |= 0x3 << 2;
@@ -326,12 +323,12 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
 
        WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
        tmp = RREG8(DAC_DATA);
-       WREG_DAC(MGA1064_PIX_PLL_STAT, tmp & ~0x40);
+       WREG8(DAC_DATA, tmp & ~0x40);
 
        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
        tmp = RREG8(DAC_DATA);
        tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
-       WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+       WREG8(DAC_DATA, tmp);
 
        WREG_DAC(MGA1064_EV_PIX_PLLC_M, m);
        WREG_DAC(MGA1064_EV_PIX_PLLC_N, n);
@@ -342,7 +339,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
        tmp = RREG8(DAC_DATA);
        tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
-       WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+       WREG8(DAC_DATA, tmp);
 
        udelay(500);
 
@@ -350,11 +347,11 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
        tmp = RREG8(DAC_DATA);
        tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
        tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
-       WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+       WREG8(DAC_DATA, tmp);
 
        WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
        tmp = RREG8(DAC_DATA);
-       WREG_DAC(MGA1064_PIX_PLL_STAT, tmp | 0x40);
+       WREG8(DAC_DATA, tmp | 0x40);
 
        tmp = RREG8(MGAREG_MEM_MISC_READ);
        tmp |= (0x3 << 2);
@@ -363,7 +360,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
        tmp = RREG8(DAC_DATA);
        tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
-       WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+       WREG8(DAC_DATA, tmp);
 
        return 0;
 }
@@ -416,7 +413,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
                tmp = RREG8(DAC_DATA);
                tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
-               WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
+               WREG8(DAC_DATA, tmp);
 
                tmp = RREG8(MGAREG_MEM_MISC_READ);
                tmp |= 0x3 << 2;
@@ -425,7 +422,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
                tmp = RREG8(DAC_DATA);
                tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
-               WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                udelay(500);
 
@@ -439,13 +436,13 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
                tmp = RREG8(DAC_DATA);
                tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
                tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
-               WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
                tmp = RREG8(DAC_DATA);
                tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
                tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
-               WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+               WREG8(DAC_DATA, tmp);
 
                vcount = RREG8(MGAREG_VCOUNT);
 
@@ -515,12 +512,12 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
        tmp = RREG8(DAC_DATA);
        tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
-       WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
+       WREG8(DAC_DATA, tmp);
 
        WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
        tmp = RREG8(DAC_DATA);
        tmp |= MGA1064_REMHEADCTL_CLKDIS;
-       WREG_DAC(MGA1064_REMHEADCTL, tmp);
+       WREG8(DAC_DATA, tmp);
 
        tmp = RREG8(MGAREG_MEM_MISC_READ);
        tmp |= (0x3<<2) | 0xc0;
@@ -530,7 +527,7 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
        tmp = RREG8(DAC_DATA);
        tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
        tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
-       WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
+       WREG8(DAC_DATA, tmp);
 
        udelay(500);
 
@@ -657,12 +654,26 @@ static void mga_g200wb_commit(struct drm_crtc *crtc)
        WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
 }
 
-
+/*
+   This is how the framebuffer base address is stored in g200 cards:
+   * Assume @offset is the gpu_addr variable of the framebuffer object
+   * Then addr is the number of _pixels_ (not bytes) from the start of
+     VRAM to the first pixel we want to display. (divided by 2 for 32bit
+     framebuffers)
+   * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
+   addr<20> -> CRTCEXT0<6>
+   addr<19-16> -> CRTCEXT0<3-0>
+   addr<15-8> -> CRTCC<7-0>
+   addr<7-0> -> CRTCD<7-0>
+   CRTCEXT0 has to be programmed last to trigger an update and make the
+   new addr variable take effect.
+ */
 void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
 {
        struct mga_device *mdev = crtc->dev->dev_private;
        u32 addr;
        int count;
+       u8 crtcext0;
 
        while (RREG8(0x1fda) & 0x08);
        while (!(RREG8(0x1fda) & 0x08));
@@ -670,10 +681,17 @@ void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
        count = RREG8(MGAREG_VCOUNT) + 2;
        while (RREG8(MGAREG_VCOUNT) < count);
 
-       addr = offset >> 2;
+       WREG8(MGAREG_CRTCEXT_INDEX, 0);
+       crtcext0 = RREG8(MGAREG_CRTCEXT_DATA);
+       crtcext0 &= 0xB0;
+       addr = offset / 8;
+       /* Can't store addresses any higher than that...
+          but we also don't have more than 16MB of memory, so it should be fine. */
+       WARN_ON(addr > 0x1fffff);
+       crtcext0 |= (!!(addr & (1<<20)))<<6;
        WREG_CRT(0x0d, (u8)(addr & 0xff));
        WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
-       WREG_CRT(0xaf, (u8)(addr >> 16) & 0xf);
+       WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0);
 }
 
 
@@ -829,11 +847,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
 
 
        for (i = 0; i < sizeof(dacvalue); i++) {
-               if ((i <= 0x03) ||
-                   (i == 0x07) ||
-                   (i == 0x0b) ||
-                   (i == 0x0f) ||
-                   ((i >= 0x13) && (i <= 0x17)) ||
+               if ((i <= 0x17) ||
                    (i == 0x1b) ||
                    (i == 0x1c) ||
                    ((i >= 0x1f) && (i <= 0x29)) ||
index 955af122c3a68dc06eb0cea0360e746447416966..a36e64e98ef372a91566da1d6fb0fff6ebef400f 100644 (file)
@@ -138,7 +138,6 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
                device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
                device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
-               device->oclass[NVDEV_ENGINE_COPY1  ] = &nvc0_copy1_oclass;
                device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
                break;
        case 0xce:
@@ -225,7 +224,6 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
                device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
                device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
-               device->oclass[NVDEV_ENGINE_COPY1  ] = &nvc0_copy1_oclass;
                device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
                break;
        case 0xc8:
index ddaeb55729038ee4572b17c78c6ec94198ac0280..89bf459d584bb2f8272c0443ed8411715c2c0ed5 100644 (file)
@@ -47,6 +47,7 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
        struct nouveau_gpuobj *cur;
        int i, p;
 
+       mutex_lock(&nv_subdev(priv)->mutex);
        cur = priv->playlist[priv->cur_playlist];
        priv->cur_playlist = !priv->cur_playlist;
 
@@ -60,6 +61,7 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
        nv_wr32(priv, 0x0032f4, cur->addr >> 12);
        nv_wr32(priv, 0x0032ec, p);
        nv_wr32(priv, 0x002500, 0x00000101);
+       mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
 static int
index 4d4a6b905370b2633b6afb199de3eb3973943ece..46dfa68c47bbd84ca4c30d07955111aab2bb29b5 100644 (file)
@@ -71,6 +71,7 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv)
        struct nouveau_gpuobj *cur;
        int i, p;
 
+       mutex_lock(&nv_subdev(priv)->mutex);
        cur = priv->playlist[priv->cur_playlist];
        priv->cur_playlist = !priv->cur_playlist;
 
@@ -87,6 +88,7 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv)
        nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3));
        if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000))
                nv_error(priv, "playlist update failed\n");
+       mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
 static int
@@ -248,9 +250,17 @@ nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
        struct nvc0_fifo_priv *priv = (void *)object->engine;
        struct nvc0_fifo_chan *chan = (void *)object;
        u32 chid = chan->base.chid;
+       u32 mask, engine;
 
        nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000);
        nvc0_fifo_playlist_update(priv);
+       mask = nv_rd32(priv, 0x0025a4);
+       for (engine = 0; mask && engine < 16; engine++) {
+               if (!(mask & (1 << engine)))
+                       continue;
+               nv_mask(priv, 0x0025a8 + (engine * 4), 0x00000000, 0x00000000);
+               mask &= ~(1 << engine);
+       }
        nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000);
 
        return nouveau_fifo_channel_fini(&chan->base, suspend);
index 9151919fb83152a3c5035299f04fcbbd472b74f9..56192a7242aee51ab1fdbb575b8463a47a41acb7 100644 (file)
@@ -94,11 +94,13 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine)
        u32 match = (engine << 16) | 0x00000001;
        int i, p;
 
+       mutex_lock(&nv_subdev(priv)->mutex);
        cur = engn->playlist[engn->cur_playlist];
        if (unlikely(cur == NULL)) {
                int ret = nouveau_gpuobj_new(nv_object(priv), NULL,
                                             0x8000, 0x1000, 0, &cur);
                if (ret) {
+                       mutex_unlock(&nv_subdev(priv)->mutex);
                        nv_error(priv, "playlist alloc failed\n");
                        return;
                }
@@ -122,6 +124,7 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine)
        nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3));
        if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000))
                nv_error(priv, "playlist %d update timeout\n", engine);
+       mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
 static int
index c300b5e7b67048550c4d019bc94b31dc9c0ac6a9..c434d398d16f0302bec862c95b6421cb8e505652 100644 (file)
@@ -1940,8 +1940,8 @@ init_zm_mask_add(struct nvbios_init *init)
        trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add);
        init->offset += 13;
 
-       data  =  init_rd32(init, addr) & mask;
-       data |= ((data + add) & ~mask);
+       data =  init_rd32(init, addr);
+       data = (data & mask) | ((data + add) & ~mask);
        init_wr32(init, addr, data);
 }
 
index e4940fb166e8ead8280d7d4f4ee9659aa8b3d133..fb794e997fbccdeef0f03a460f0112766d1cc8fd 100644 (file)
@@ -29,7 +29,6 @@
 struct nvc0_ltcg_priv {
        struct nouveau_ltcg base;
        u32 part_nr;
-       u32 part_mask;
        u32 subp_nr;
        struct nouveau_mm tags;
        u32 num_tags;
@@ -105,8 +104,6 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count)
 
        /* wait until it's finished with clearing */
        for (p = 0; p < priv->part_nr; ++p) {
-               if (!(priv->part_mask & (1 << p)))
-                       continue;
                for (i = 0; i < priv->subp_nr; ++i)
                        nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0);
        }
@@ -121,6 +118,8 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
        int ret;
 
        nv_wr32(priv, 0x17e8d8, priv->part_nr);
+       if (nv_device(pfb)->card_type >= NV_E0)
+               nv_wr32(priv, 0x17e000, priv->part_nr);
 
        /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
        priv->num_tags = (pfb->ram.size >> 17) / 4;
@@ -167,16 +166,20 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 {
        struct nvc0_ltcg_priv *priv;
        struct nouveau_fb *pfb = nouveau_fb(parent);
-       int ret;
+       u32 parts, mask;
+       int ret, i;
 
        ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
 
-       priv->part_nr = nv_rd32(priv, 0x022438);
-       priv->part_mask = nv_rd32(priv, 0x022554);
-
+       parts = nv_rd32(priv, 0x022438);
+       mask = nv_rd32(priv, 0x022554);
+       for (i = 0; i < parts; i++) {
+               if (!(mask & (1 << i)))
+                       priv->part_nr++;
+       }
        priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
 
        nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
index 46c152ff0a80f41a102a332a2378867cf0e88f3a..383f4e6ea9d164c59509c7788666cf89fb6abbe0 100644 (file)
@@ -453,18 +453,32 @@ nouveau_do_suspend(struct drm_device *dev)
        NV_INFO(drm, "evicting buffers...\n");
        ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
 
+       NV_INFO(drm, "waiting for kernel channels to go idle...\n");
+       if (drm->cechan) {
+               ret = nouveau_channel_idle(drm->cechan);
+               if (ret)
+                       return ret;
+       }
+
+       if (drm->channel) {
+               ret = nouveau_channel_idle(drm->channel);
+               if (ret)
+                       return ret;
+       }
+
+       NV_INFO(drm, "suspending client object trees...\n");
        if (drm->fence && nouveau_fence(drm)->suspend) {
                if (!nouveau_fence(drm)->suspend(drm))
                        return -ENOMEM;
        }
 
-       NV_INFO(drm, "suspending client object trees...\n");
        list_for_each_entry(cli, &drm->clients, head) {
                ret = nouveau_client_fini(&cli->base, true);
                if (ret)
                        goto fail_client;
        }
 
+       NV_INFO(drm, "suspending kernel object tree...\n");
        ret = nouveau_client_fini(&drm->client.base, true);
        if (ret)
                goto fail_client;
@@ -514,17 +528,18 @@ nouveau_do_resume(struct drm_device *dev)
 
        nouveau_agp_reset(drm);
 
-       NV_INFO(drm, "resuming client object trees...\n");
+       NV_INFO(drm, "resuming kernel object tree...\n");
        nouveau_client_init(&drm->client.base);
        nouveau_agp_init(drm);
 
+       NV_INFO(drm, "resuming client object trees...\n");
+       if (drm->fence && nouveau_fence(drm)->resume)
+               nouveau_fence(drm)->resume(drm);
+
        list_for_each_entry(cli, &drm->clients, head) {
                nouveau_client_init(&cli->base);
        }
 
-       if (drm->fence && nouveau_fence(drm)->resume)
-               nouveau_fence(drm)->resume(drm);
-
        nouveau_run_vbios_init(dev);
        nouveau_pm_resume(dev);
 
index 08b0823c93d526405d506aca4849f2c83a9d9eb5..f86771481317b77d565675c956d77fdcb22f2789 100644 (file)
@@ -277,7 +277,7 @@ out_unref:
        return 0;
 }
 
-static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port)
+static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, bool intr)
 {
        int irq_num;
        long addr = qdev->io_base + port;
@@ -285,20 +285,29 @@ static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port)
 
        mutex_lock(&qdev->async_io_mutex);
        irq_num = atomic_read(&qdev->irq_received_io_cmd);
-
-
        if (qdev->last_sent_io_cmd > irq_num) {
-               ret = wait_event_interruptible(qdev->io_cmd_event,
-                                              atomic_read(&qdev->irq_received_io_cmd) > irq_num);
-               if (ret)
+               if (intr)
+                       ret = wait_event_interruptible_timeout(qdev->io_cmd_event,
+                                                              atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
+               else
+                       ret = wait_event_timeout(qdev->io_cmd_event,
+                                                atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
+               /* 0 is timeout, just bail the "hw" has gone away */
+               if (ret <= 0)
                        goto out;
                irq_num = atomic_read(&qdev->irq_received_io_cmd);
        }
        outb(val, addr);
        qdev->last_sent_io_cmd = irq_num + 1;
-       ret = wait_event_interruptible(qdev->io_cmd_event,
-                                      atomic_read(&qdev->irq_received_io_cmd) > irq_num);
+       if (intr)
+               ret = wait_event_interruptible_timeout(qdev->io_cmd_event,
+                                                      atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
+       else
+               ret = wait_event_timeout(qdev->io_cmd_event,
+                                        atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ);
 out:
+       if (ret > 0)
+               ret = 0;
        mutex_unlock(&qdev->async_io_mutex);
        return ret;
 }
@@ -308,7 +317,7 @@ static void wait_for_io_cmd(struct qxl_device *qdev, uint8_t val, long port)
        int ret;
 
 restart:
-       ret = wait_for_io_cmd_user(qdev, val, port);
+       ret = wait_for_io_cmd_user(qdev, val, port, false);
        if (ret == -ERESTARTSYS)
                goto restart;
 }
@@ -340,7 +349,7 @@ int qxl_io_update_area(struct qxl_device *qdev, struct qxl_bo *surf,
        mutex_lock(&qdev->update_area_mutex);
        qdev->ram_header->update_area = *area;
        qdev->ram_header->update_surface = surface_id;
-       ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC);
+       ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC, true);
        mutex_unlock(&qdev->update_area_mutex);
        return ret;
 }
index fcfd4436ceedd50f335afdc84edac0001036e2d8..823d29e926ec0aa6c9715b4cb93448b3c4e90215 100644 (file)
@@ -428,10 +428,10 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb,
        int inc = 1;
 
        qobj = gem_to_qxl_bo(qxl_fb->obj);
-       if (qxl_fb != qdev->active_user_framebuffer) {
-               DRM_INFO("%s: qxl_fb 0x%p != qdev->active_user_framebuffer 0x%p\n",
-                       __func__, qxl_fb, qdev->active_user_framebuffer);
-       }
+       /* if we aren't primary surface ignore this */
+       if (!qobj->is_primary)
+               return 0;
+
        if (!num_clips) {
                num_clips = 1;
                clips = &norect;
@@ -604,7 +604,6 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
                                               mode->hdisplay,
                                               mode->vdisplay);
        }
-       qdev->mode_set = true;
        return 0;
 }
 
@@ -893,7 +892,6 @@ qxl_user_framebuffer_create(struct drm_device *dev,
 {
        struct drm_gem_object *obj;
        struct qxl_framebuffer *qxl_fb;
-       struct qxl_device *qdev = dev->dev_private;
        int ret;
 
        obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
@@ -909,13 +907,6 @@ qxl_user_framebuffer_create(struct drm_device *dev,
                return NULL;
        }
 
-       if (qdev->active_user_framebuffer) {
-               DRM_INFO("%s: active_user_framebuffer %p -> %p\n",
-                        __func__,
-                        qdev->active_user_framebuffer, qxl_fb);
-       }
-       qdev->active_user_framebuffer = qxl_fb;
-
        return &qxl_fb->base;
 }
 
index 52b582c211da9dc8e8ff4f28dbd52c8a0242c23a..43d06ab28a21195c5c81e03bd3f1b1b838381c80 100644 (file)
@@ -255,12 +255,6 @@ struct qxl_device {
        struct qxl_gem          gem;
        struct qxl_mode_info mode_info;
 
-       /*
-        * last created framebuffer with fb_create
-        * only used by debugfs dumbppm
-        */
-       struct qxl_framebuffer *active_user_framebuffer;
-
        struct fb_info                  *fbdev_info;
        struct qxl_framebuffer  *fbdev_qfb;
        void *ram_physical;
@@ -270,7 +264,6 @@ struct qxl_device {
        struct qxl_ring *cursor_ring;
 
        struct qxl_ram_header *ram_header;
-       bool mode_set;
 
        bool primary_created;
 
index 04b64f9cbfdb94b2c6dc1fa5e09a2df1c2b0b2cc..6db7370373ea4782b3ccc85c9a31a732d907b66b 100644 (file)
@@ -294,6 +294,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data,
                goto out;
 
        if (!qobj->pin_count) {
+               qxl_ttm_placement_from_domain(qobj, qobj->type);
                ret = ttm_bo_validate(&qobj->tbo, &qobj->placement,
                                      true, false);
                if (unlikely(ret))
index 6d6fdb3ba0d07d859b8c0fba223c0fe8193b1e46..d5df8fd1021755ad1ca39543bc0218ea9531b5ae 100644 (file)
@@ -1811,12 +1811,9 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
 
 static void atombios_crtc_prepare(struct drm_crtc *crtc)
 {
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
 
-       radeon_crtc->in_mode_set = true;
-
        /* disable crtc pair power gating before programming */
        if (ASIC_IS_DCE6(rdev))
                atombios_powergate_crtc(crtc, ATOM_DISABLE);
@@ -1827,11 +1824,8 @@ static void atombios_crtc_prepare(struct drm_crtc *crtc)
 
 static void atombios_crtc_commit(struct drm_crtc *crtc)
 {
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
        atombios_lock_crtc(crtc, ATOM_DISABLE);
-       radeon_crtc->in_mode_set = false;
 }
 
 static void atombios_crtc_disable(struct drm_crtc *crtc)
index 105bafb6c29d8aab2a6d22018d6a48c86a805cf4..8f9e2d31b25513e1cee9d8a0d24a354c2035df86 100644 (file)
@@ -2343,11 +2343,13 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
        u32 crtc_enabled, tmp, frame_count, blackout;
        int i, j;
 
-       save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
-       save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
+       if (!ASIC_IS_NODCE(rdev)) {
+               save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
+               save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
 
-       /* disable VGA render */
-       WREG32(VGA_RENDER_CONTROL, 0);
+               /* disable VGA render */
+               WREG32(VGA_RENDER_CONTROL, 0);
+       }
        /* blank the display controllers */
        for (i = 0; i < rdev->num_crtc; i++) {
                crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN;
@@ -2438,8 +2440,11 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
                WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
                       (u32)rdev->mc.vram_start);
        }
-       WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
-       WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
+
+       if (!ASIC_IS_NODCE(rdev)) {
+               WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
+               WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
+       }
 
        /* unlock regs and wait for update */
        for (i = 0; i < rdev->num_crtc; i++) {
@@ -2499,10 +2504,12 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
                        }
                }
        }
-       /* Unlock vga access */
-       WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
-       mdelay(1);
-       WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
+       if (!ASIC_IS_NODCE(rdev)) {
+               /* Unlock vga access */
+               WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
+               mdelay(1);
+               WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
+       }
 }
 
 void evergreen_mc_program(struct radeon_device *rdev)
@@ -3405,8 +3412,8 @@ int evergreen_mc_init(struct radeon_device *rdev)
                rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
        } else {
                /* size in MB on evergreen/cayman/tn */
-               rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
-               rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
+               rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+               rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
        }
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
        r700_vram_gtt_location(rdev, &rdev->mc);
index b4ab8ceb16545d115d6b39428e54c42a6f6ce1d2..ed7c8a7680929e5589fe84daa70f36d2e3bce74a 100644 (file)
@@ -154,19 +154,18 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
-       u32 base_rate = 48000;
+       u32 base_rate = 24000;
 
        if (!dig || !dig->afmt)
                return;
 
-       /* XXX: properly calculate this */
        /* XXX two dtos; generally use dto0 for hdmi */
        /* Express [24MHz / target pixel clock] as an exact rational
         * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
         * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
         */
-       WREG32(DCCG_AUDIO_DTO0_PHASE, (base_rate*50) & 0xffffff);
-       WREG32(DCCG_AUDIO_DTO0_MODULE, (clock*100) & 0xffffff);
+       WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
+       WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
        WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
 }
 
index 865e2c9980dbd5b2245a40ed23cdbb19af1044d5..60170ea5e3a228c0483c18f0fd1652b30ec7760b 100644 (file)
@@ -75,7 +75,7 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
                OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1));
 
                for (i = 0; i < nr; ++i) {
-                       if (DRM_COPY_FROM_USER_UNCHECKED
+                       if (DRM_COPY_FROM_USER
                            (&box, &cmdbuf->boxes[n + i], sizeof(box))) {
                                DRM_ERROR("copy cliprect faulted\n");
                                return -EFAULT;
index 47f180a79352a48d5eb083df80181f0b7aab597f..456750a0daa5c98409e040d6c3ed4731e533a0a1 100644 (file)
@@ -232,7 +232,7 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-       u32 base_rate = 48000;
+       u32 base_rate = 24000;
 
        if (!dig || !dig->afmt)
                return;
@@ -240,7 +240,6 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
        /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
         * doesn't matter which one you use.  Just use the first one.
         */
-       /* XXX: properly calculate this */
        /* XXX two dtos; generally use dto0 for hdmi */
        /* Express [24MHz / target pixel clock] as an exact rational
         * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
@@ -250,13 +249,13 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
                /* according to the reg specs, this should DCE3.2 only, but in
                 * practice it seems to cover DCE3.0 as well.
                 */
-               WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 50);
+               WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
                WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
                WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
        } else {
                /* according to the reg specs, this should be DCE2.0 and DCE3.0 */
-               WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate * 50) |
-                      AUDIO_DTO_MODULE(clock * 100));
+               WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
+                      AUDIO_DTO_MODULE(clock / 10));
        }
 }
 
index 1442ce765d48a74be071a89b9e7f30beee0332d7..142ce6cc69f5e3564299102ceaa2982adce628e7 100644 (file)
@@ -1694,6 +1694,7 @@ struct radeon_device {
        int num_crtc; /* number of crtcs */
        struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
        bool audio_enabled;
+       bool has_uvd;
        struct r600_audio audio_status; /* audio stuff */
        struct notifier_block acpi_nb;
        /* only one userspace can use Hyperz features or CMASK at a time */
@@ -1838,6 +1839,7 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
 #define ASIC_IS_DCE61(rdev) ((rdev->family >= CHIP_ARUBA) && \
                             (rdev->flags & RADEON_IS_IGP))
 #define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND))
+#define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN))
 
 /*
  * BIOS helpers.
index 6417132c50cf5bf8df186225cc8233d182188197..06b8c19ab19e7cda0de46325d15291adc8eabf79 100644 (file)
@@ -1935,6 +1935,8 @@ int radeon_asic_init(struct radeon_device *rdev)
        else
                rdev->num_crtc = 2;
 
+       rdev->has_uvd = false;
+
        switch (rdev->family) {
        case CHIP_R100:
        case CHIP_RV100:
@@ -1999,16 +2001,22 @@ int radeon_asic_init(struct radeon_device *rdev)
        case CHIP_RV635:
        case CHIP_RV670:
                rdev->asic = &r600_asic;
+               if (rdev->family == CHIP_R600)
+                       rdev->has_uvd = false;
+               else
+                       rdev->has_uvd = true;
                break;
        case CHIP_RS780:
        case CHIP_RS880:
                rdev->asic = &rs780_asic;
+               rdev->has_uvd = true;
                break;
        case CHIP_RV770:
        case CHIP_RV730:
        case CHIP_RV710:
        case CHIP_RV740:
                rdev->asic = &rv770_asic;
+               rdev->has_uvd = true;
                break;
        case CHIP_CEDAR:
        case CHIP_REDWOOD:
@@ -2021,11 +2029,13 @@ int radeon_asic_init(struct radeon_device *rdev)
                else
                        rdev->num_crtc = 6;
                rdev->asic = &evergreen_asic;
+               rdev->has_uvd = true;
                break;
        case CHIP_PALM:
        case CHIP_SUMO:
        case CHIP_SUMO2:
                rdev->asic = &sumo_asic;
+               rdev->has_uvd = true;
                break;
        case CHIP_BARTS:
        case CHIP_TURKS:
@@ -2036,27 +2046,37 @@ int radeon_asic_init(struct radeon_device *rdev)
                else
                        rdev->num_crtc = 6;
                rdev->asic = &btc_asic;
+               rdev->has_uvd = true;
                break;
        case CHIP_CAYMAN:
                rdev->asic = &cayman_asic;
                /* set num crtcs */
                rdev->num_crtc = 6;
+               rdev->has_uvd = true;
                break;
        case CHIP_ARUBA:
                rdev->asic = &trinity_asic;
                /* set num crtcs */
                rdev->num_crtc = 4;
+               rdev->has_uvd = true;
                break;
        case CHIP_TAHITI:
        case CHIP_PITCAIRN:
        case CHIP_VERDE:
        case CHIP_OLAND:
+       case CHIP_HAINAN:
                rdev->asic = &si_asic;
                /* set num crtcs */
-               if (rdev->family == CHIP_OLAND)
+               if (rdev->family == CHIP_HAINAN)
+                       rdev->num_crtc = 0;
+               else if (rdev->family == CHIP_OLAND)
                        rdev->num_crtc = 2;
                else
                        rdev->num_crtc = 6;
+               if (rdev->family == CHIP_HAINAN)
+                       rdev->has_uvd = false;
+               else
+                       rdev->has_uvd = true;
                break;
        default:
                /* FIXME: not supported yet */
index fa3c56fba294fe1a433b2d7b6a3e1507e357d1ca..061b227dae0c45f88f506bf497c75faa1195aca1 100644 (file)
@@ -244,24 +244,28 @@ static bool ni_read_disabled_bios(struct radeon_device *rdev)
 
        /* enable the rom */
        WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
-       /* Disable VGA mode */
-       WREG32(AVIVO_D1VGA_CONTROL,
-              (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
-               AVIVO_DVGA_CONTROL_TIMING_SELECT)));
-       WREG32(AVIVO_D2VGA_CONTROL,
-              (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
-               AVIVO_DVGA_CONTROL_TIMING_SELECT)));
-       WREG32(AVIVO_VGA_RENDER_CONTROL,
-              (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
+       if (!ASIC_IS_NODCE(rdev)) {
+               /* Disable VGA mode */
+               WREG32(AVIVO_D1VGA_CONTROL,
+                      (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
+                                         AVIVO_DVGA_CONTROL_TIMING_SELECT)));
+               WREG32(AVIVO_D2VGA_CONTROL,
+                      (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
+                                         AVIVO_DVGA_CONTROL_TIMING_SELECT)));
+               WREG32(AVIVO_VGA_RENDER_CONTROL,
+                      (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
+       }
        WREG32(R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE);
 
        r = radeon_read_bios(rdev);
 
        /* restore regs */
        WREG32(R600_BUS_CNTL, bus_cntl);
-       WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
-       WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
-       WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
+       if (!ASIC_IS_NODCE(rdev)) {
+               WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
+               WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
+               WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
+       }
        WREG32(R600_ROM_CNTL, rom_cntl);
        return r;
 }
index a8f6089039896f47f22152746d6baeceb1b07603..c2c59fb1ea0173965361c2af1f181e22dc6707c2 100644 (file)
@@ -94,6 +94,7 @@ static const char radeon_family_name[][16] = {
        "PITCAIRN",
        "VERDE",
        "OLAND",
+       "HAINAN",
        "LAST",
 };
 
index d33f484ace48792d746e812d81fd84d56ce5d4b8..094e7e5ea39e00fb391e63364c9c2f5978ce9c57 100644 (file)
@@ -147,7 +147,7 @@ static inline void radeon_unregister_atpx_handler(void) {}
 #endif
 
 int radeon_no_wb;
-int radeon_modeset = 1;
+int radeon_modeset = -1;
 int radeon_dynclks = -1;
 int radeon_r4xx_atom = 0;
 int radeon_agpmode = 0;
@@ -456,6 +456,16 @@ static struct pci_driver radeon_kms_pci_driver = {
 
 static int __init radeon_init(void)
 {
+#ifdef CONFIG_VGA_CONSOLE
+       if (vgacon_text_force() && radeon_modeset == -1) {
+               DRM_INFO("VGACON disable radeon kernel modesetting.\n");
+               radeon_modeset = 0;
+       }
+#endif
+       /* set to modesetting by default if not nomodeset */
+       if (radeon_modeset == -1)
+               radeon_modeset = 1;
+
        if (radeon_modeset == 1) {
                DRM_INFO("radeon kernel modesetting enabled.\n");
                driver = &kms_driver;
index 2d91123f2759dd3556310581dda6fa188988e958..36e9803b077d8a5a50a54e0d9e1e70f16b691db7 100644 (file)
@@ -92,6 +92,7 @@ enum radeon_family {
        CHIP_PITCAIRN,
        CHIP_VERDE,
        CHIP_OLAND,
+       CHIP_HAINAN,
        CHIP_LAST,
 };
 
index 6857cb4efb768c932f23d4645c3969fd9c792f18..7cb178a34a0f18c0b50c7cd48a3e151f5ce05b4b 100644 (file)
@@ -1031,11 +1031,9 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
 
 static void radeon_crtc_prepare(struct drm_crtc *crtc)
 {
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct drm_crtc *crtci;
 
-       radeon_crtc->in_mode_set = true;
        /*
        * The hardware wedges sometimes if you reconfigure one CRTC
        * whilst another is running (see fdo bug #24611).
@@ -1046,7 +1044,6 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc)
 
 static void radeon_crtc_commit(struct drm_crtc *crtc)
 {
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct drm_crtc *crtci;
 
@@ -1057,7 +1054,6 @@ static void radeon_crtc_commit(struct drm_crtc *crtc)
                if (crtci->enabled)
                        radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
        }
-       radeon_crtc->in_mode_set = false;
 }
 
 static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
index 44e579e75fd0950e6a644d5be110687fbab0efae..69ad4fe224c1951eb370f6396b257b85dda7e4da 100644 (file)
@@ -302,7 +302,6 @@ struct radeon_crtc {
        u16 lut_r[256], lut_g[256], lut_b[256];
        bool enabled;
        bool can_tile;
-       bool in_mode_set;
        uint32_t crtc_offset;
        struct drm_gem_object *cursor_bo;
        uint64_t cursor_addr;
index 93f760e27a9200a81b94dfee8ce6d14ac935b49a..6c0ce8915fac9efc399654a8b25e4bd180285d0a 100644 (file)
@@ -726,7 +726,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
                return r;
        }
        DRM_INFO("radeon: %uM of VRAM memory ready\n",
-                (unsigned)rdev->mc.real_vram_size / (1024 * 1024));
+                (unsigned) (rdev->mc.real_vram_size / (1024 * 1024)));
        r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT,
                                rdev->mc.gtt_size >> PAGE_SHIFT);
        if (r) {
index f0b6c2f87c4d70fd752d41918a792a43b6b93cac..5ffade69af253d7844d73097651c730f9c7f6a04 100644 (file)
@@ -60,6 +60,11 @@ MODULE_FIRMWARE("radeon/OLAND_me.bin");
 MODULE_FIRMWARE("radeon/OLAND_ce.bin");
 MODULE_FIRMWARE("radeon/OLAND_mc.bin");
 MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
+MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
+MODULE_FIRMWARE("radeon/HAINAN_me.bin");
+MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
+MODULE_FIRMWARE("radeon/HAINAN_mc.bin");
+MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
 
 extern int r600_ih_ring_alloc(struct radeon_device *rdev);
 extern void r600_ih_ring_fini(struct radeon_device *rdev);
@@ -265,6 +270,40 @@ static const u32 oland_golden_registers[] =
        0x15c0, 0x000c0fc0, 0x000c0400
 };
 
+static const u32 hainan_golden_registers[] =
+{
+       0x9a10, 0x00010000, 0x00018208,
+       0x9830, 0xffffffff, 0x00000000,
+       0x9834, 0xf00fffff, 0x00000400,
+       0x9838, 0x0002021c, 0x00020200,
+       0xd0c0, 0xff000fff, 0x00000100,
+       0xd030, 0x000300c0, 0x00800040,
+       0xd8c0, 0xff000fff, 0x00000100,
+       0xd830, 0x000300c0, 0x00800040,
+       0x2ae4, 0x00073ffe, 0x000022a2,
+       0x240c, 0x000007ff, 0x00000000,
+       0x8a14, 0xf000001f, 0x00000007,
+       0x8b24, 0xffffffff, 0x00ffffff,
+       0x8b10, 0x0000ff0f, 0x00000000,
+       0x28a4c, 0x07ffffff, 0x4e000000,
+       0x28350, 0x3f3f3fff, 0x00000000,
+       0x30, 0x000000ff, 0x0040,
+       0x34, 0x00000040, 0x00004040,
+       0x9100, 0x03e00000, 0x03600000,
+       0x9060, 0x0000007f, 0x00000020,
+       0x9508, 0x00010000, 0x00010000,
+       0xac14, 0x000003ff, 0x000000f1,
+       0xac10, 0xffffffff, 0x00000000,
+       0xac0c, 0xffffffff, 0x00003210,
+       0x88d4, 0x0000001f, 0x00000010,
+       0x15c0, 0x000c0fc0, 0x000c0400
+};
+
+static const u32 hainan_golden_registers2[] =
+{
+       0x98f8, 0xffffffff, 0x02010001
+};
+
 static const u32 tahiti_mgcg_cgcg_init[] =
 {
        0xc400, 0xffffffff, 0xfffffffc,
@@ -673,6 +712,83 @@ static const u32 oland_mgcg_cgcg_init[] =
        0xd8c0, 0xfffffff0, 0x00000100
 };
 
+static const u32 hainan_mgcg_cgcg_init[] =
+{
+       0xc400, 0xffffffff, 0xfffffffc,
+       0x802c, 0xffffffff, 0xe0000000,
+       0x9a60, 0xffffffff, 0x00000100,
+       0x92a4, 0xffffffff, 0x00000100,
+       0xc164, 0xffffffff, 0x00000100,
+       0x9774, 0xffffffff, 0x00000100,
+       0x8984, 0xffffffff, 0x06000100,
+       0x8a18, 0xffffffff, 0x00000100,
+       0x92a0, 0xffffffff, 0x00000100,
+       0xc380, 0xffffffff, 0x00000100,
+       0x8b28, 0xffffffff, 0x00000100,
+       0x9144, 0xffffffff, 0x00000100,
+       0x8d88, 0xffffffff, 0x00000100,
+       0x8d8c, 0xffffffff, 0x00000100,
+       0x9030, 0xffffffff, 0x00000100,
+       0x9034, 0xffffffff, 0x00000100,
+       0x9038, 0xffffffff, 0x00000100,
+       0x903c, 0xffffffff, 0x00000100,
+       0xad80, 0xffffffff, 0x00000100,
+       0xac54, 0xffffffff, 0x00000100,
+       0x897c, 0xffffffff, 0x06000100,
+       0x9868, 0xffffffff, 0x00000100,
+       0x9510, 0xffffffff, 0x00000100,
+       0xaf04, 0xffffffff, 0x00000100,
+       0xae04, 0xffffffff, 0x00000100,
+       0x949c, 0xffffffff, 0x00000100,
+       0x802c, 0xffffffff, 0xe0000000,
+       0x9160, 0xffffffff, 0x00010000,
+       0x9164, 0xffffffff, 0x00030002,
+       0x9168, 0xffffffff, 0x00040007,
+       0x916c, 0xffffffff, 0x00060005,
+       0x9170, 0xffffffff, 0x00090008,
+       0x9174, 0xffffffff, 0x00020001,
+       0x9178, 0xffffffff, 0x00040003,
+       0x917c, 0xffffffff, 0x00000007,
+       0x9180, 0xffffffff, 0x00060005,
+       0x9184, 0xffffffff, 0x00090008,
+       0x9188, 0xffffffff, 0x00030002,
+       0x918c, 0xffffffff, 0x00050004,
+       0x9190, 0xffffffff, 0x00000008,
+       0x9194, 0xffffffff, 0x00070006,
+       0x9198, 0xffffffff, 0x000a0009,
+       0x919c, 0xffffffff, 0x00040003,
+       0x91a0, 0xffffffff, 0x00060005,
+       0x91a4, 0xffffffff, 0x00000009,
+       0x91a8, 0xffffffff, 0x00080007,
+       0x91ac, 0xffffffff, 0x000b000a,
+       0x91b0, 0xffffffff, 0x00050004,
+       0x91b4, 0xffffffff, 0x00070006,
+       0x91b8, 0xffffffff, 0x0008000b,
+       0x91bc, 0xffffffff, 0x000a0009,
+       0x91c0, 0xffffffff, 0x000d000c,
+       0x91c4, 0xffffffff, 0x00060005,
+       0x91c8, 0xffffffff, 0x00080007,
+       0x91cc, 0xffffffff, 0x0000000b,
+       0x91d0, 0xffffffff, 0x000a0009,
+       0x91d4, 0xffffffff, 0x000d000c,
+       0x9150, 0xffffffff, 0x96940200,
+       0x8708, 0xffffffff, 0x00900100,
+       0xc478, 0xffffffff, 0x00000080,
+       0xc404, 0xffffffff, 0x0020003f,
+       0x30, 0xffffffff, 0x0000001c,
+       0x34, 0x000f0000, 0x000f0000,
+       0x160c, 0xffffffff, 0x00000100,
+       0x1024, 0xffffffff, 0x00000100,
+       0x20a8, 0xffffffff, 0x00000104,
+       0x264c, 0x000c0000, 0x000c0000,
+       0x2648, 0x000c0000, 0x000c0000,
+       0x2f50, 0x00000001, 0x00000001,
+       0x30cc, 0xc0000fff, 0x00000104,
+       0xc1e4, 0x00000001, 0x00000001,
+       0xd0c0, 0xfffffff0, 0x00000100,
+       0xd8c0, 0xfffffff0, 0x00000100
+};
+
 static u32 verde_pg_init[] =
 {
        0x353c, 0xffffffff, 0x40000,
@@ -853,6 +969,17 @@ static void si_init_golden_registers(struct radeon_device *rdev)
                                                 oland_mgcg_cgcg_init,
                                                 (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
                break;
+       case CHIP_HAINAN:
+               radeon_program_register_sequence(rdev,
+                                                hainan_golden_registers,
+                                                (const u32)ARRAY_SIZE(hainan_golden_registers));
+               radeon_program_register_sequence(rdev,
+                                                hainan_golden_registers2,
+                                                (const u32)ARRAY_SIZE(hainan_golden_registers2));
+               radeon_program_register_sequence(rdev,
+                                                hainan_mgcg_cgcg_init,
+                                                (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init));
+               break;
        default:
                break;
        }
@@ -1062,6 +1189,45 @@ static const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
        {0x0000009f, 0x00a17730}
 };
 
+static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
+       {0x0000006f, 0x03044000},
+       {0x00000070, 0x0480c018},
+       {0x00000071, 0x00000040},
+       {0x00000072, 0x01000000},
+       {0x00000074, 0x000000ff},
+       {0x00000075, 0x00143400},
+       {0x00000076, 0x08ec0800},
+       {0x00000077, 0x040000cc},
+       {0x00000079, 0x00000000},
+       {0x0000007a, 0x21000409},
+       {0x0000007c, 0x00000000},
+       {0x0000007d, 0xe8000000},
+       {0x0000007e, 0x044408a8},
+       {0x0000007f, 0x00000003},
+       {0x00000080, 0x00000000},
+       {0x00000081, 0x01000000},
+       {0x00000082, 0x02000000},
+       {0x00000083, 0x00000000},
+       {0x00000084, 0xe3f3e4f4},
+       {0x00000085, 0x00052024},
+       {0x00000087, 0x00000000},
+       {0x00000088, 0x66036603},
+       {0x00000089, 0x01000000},
+       {0x0000008b, 0x1c0a0000},
+       {0x0000008c, 0xff010000},
+       {0x0000008e, 0xffffefff},
+       {0x0000008f, 0xfff3efff},
+       {0x00000090, 0xfff3efbf},
+       {0x00000094, 0x00101101},
+       {0x00000095, 0x00000fff},
+       {0x00000096, 0x00116fff},
+       {0x00000097, 0x60010000},
+       {0x00000098, 0x10010000},
+       {0x00000099, 0x00006000},
+       {0x0000009a, 0x00001000},
+       {0x0000009f, 0x00a07730}
+};
+
 /* ucode loading */
 static int si_mc_load_microcode(struct radeon_device *rdev)
 {
@@ -1095,6 +1261,11 @@ static int si_mc_load_microcode(struct radeon_device *rdev)
                ucode_size = OLAND_MC_UCODE_SIZE;
                regs_size = TAHITI_IO_MC_REGS_SIZE;
                break;
+       case CHIP_HAINAN:
+               io_mc_regs = (u32 *)&hainan_io_mc_regs;
+               ucode_size = OLAND_MC_UCODE_SIZE;
+               regs_size = TAHITI_IO_MC_REGS_SIZE;
+               break;
        }
 
        running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
@@ -1198,6 +1369,15 @@ static int si_init_microcode(struct radeon_device *rdev)
                rlc_req_size = SI_RLC_UCODE_SIZE * 4;
                mc_req_size = OLAND_MC_UCODE_SIZE * 4;
                break;
+       case CHIP_HAINAN:
+               chip_name = "HAINAN";
+               rlc_chip_name = "HAINAN";
+               pfp_req_size = SI_PFP_UCODE_SIZE * 4;
+               me_req_size = SI_PM4_UCODE_SIZE * 4;
+               ce_req_size = SI_CE_UCODE_SIZE * 4;
+               rlc_req_size = SI_RLC_UCODE_SIZE * 4;
+               mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+               break;
        default: BUG();
        }
 
@@ -2003,7 +2183,8 @@ static void si_tiling_mode_table_init(struct radeon_device *rdev)
                        WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
                }
        } else if ((rdev->family == CHIP_VERDE) ||
-                  (rdev->family == CHIP_OLAND)) {
+                  (rdev->family == CHIP_OLAND) ||
+                  (rdev->family == CHIP_HAINAN)) {
                for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
                        switch (reg_offset) {
                        case 0:  /* non-AA compressed depth or any compressed stencil */
@@ -2466,6 +2647,23 @@ static void si_gpu_init(struct radeon_device *rdev)
                rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
                gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
                break;
+       case CHIP_HAINAN:
+               rdev->config.si.max_shader_engines = 1;
+               rdev->config.si.max_tile_pipes = 4;
+               rdev->config.si.max_cu_per_sh = 5;
+               rdev->config.si.max_sh_per_se = 1;
+               rdev->config.si.max_backends_per_se = 1;
+               rdev->config.si.max_texture_channel_caches = 2;
+               rdev->config.si.max_gprs = 256;
+               rdev->config.si.max_gs_threads = 16;
+               rdev->config.si.max_hw_contexts = 8;
+
+               rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
+               rdev->config.si.sc_prim_fifo_size_backend = 0x40;
+               rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
+               rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
+               gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN;
+               break;
        }
 
        /* Initialize HDP */
@@ -2559,9 +2757,11 @@ static void si_gpu_init(struct radeon_device *rdev)
        WREG32(HDP_ADDR_CONFIG, gb_addr_config);
        WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
        WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
-       WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
-       WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
-       WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
+       if (rdev->has_uvd) {
+               WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
+               WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
+               WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
+       }
 
        si_tiling_mode_table_init(rdev);
 
@@ -3304,8 +3504,9 @@ static void si_mc_program(struct radeon_device *rdev)
        if (radeon_mc_wait_for_idle(rdev)) {
                dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
-       /* Lockout access through VGA aperture*/
-       WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
+       if (!ASIC_IS_NODCE(rdev))
+               /* Lockout access through VGA aperture*/
+               WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
        /* Update configuration */
        WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
               rdev->mc.vram_start >> 12);
@@ -3327,9 +3528,11 @@ static void si_mc_program(struct radeon_device *rdev)
                dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
        evergreen_mc_resume(rdev, &save);
-       /* we need to own VRAM, so turn off the VGA renderer here
-        * to stop it overwriting our objects */
-       rv515_vga_render_disable(rdev);
+       if (!ASIC_IS_NODCE(rdev)) {
+               /* we need to own VRAM, so turn off the VGA renderer here
+                * to stop it overwriting our objects */
+               rv515_vga_render_disable(rdev);
+       }
 }
 
 static void si_vram_gtt_location(struct radeon_device *rdev,
@@ -3397,8 +3600,8 @@ static int si_mc_init(struct radeon_device *rdev)
        rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
        rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
        /* size in MB on si */
-       rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
-       rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
+       rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
+       rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
        rdev->mc.visible_vram_size = rdev->mc.aper_size;
        si_vram_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
@@ -4251,8 +4454,10 @@ static void si_disable_interrupt_state(struct radeon_device *rdev)
        tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
        WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp);
        WREG32(GRBM_INT_CNTL, 0);
-       WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
-       WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+       if (rdev->num_crtc >= 2) {
+               WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+               WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+       }
        if (rdev->num_crtc >= 4) {
                WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
                WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
@@ -4262,8 +4467,10 @@ static void si_disable_interrupt_state(struct radeon_device *rdev)
                WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
        }
 
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+       if (rdev->num_crtc >= 2) {
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+       }
        if (rdev->num_crtc >= 4) {
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
@@ -4273,21 +4480,22 @@ static void si_disable_interrupt_state(struct radeon_device *rdev)
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
        }
 
-       WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
-
-       tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-       WREG32(DC_HPD1_INT_CONTROL, tmp);
-       tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-       WREG32(DC_HPD2_INT_CONTROL, tmp);
-       tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-       WREG32(DC_HPD3_INT_CONTROL, tmp);
-       tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-       WREG32(DC_HPD4_INT_CONTROL, tmp);
-       tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-       WREG32(DC_HPD5_INT_CONTROL, tmp);
-       tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-       WREG32(DC_HPD6_INT_CONTROL, tmp);
+       if (!ASIC_IS_NODCE(rdev)) {
+               WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
 
+               tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+               WREG32(DC_HPD1_INT_CONTROL, tmp);
+               tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+               WREG32(DC_HPD2_INT_CONTROL, tmp);
+               tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+               WREG32(DC_HPD3_INT_CONTROL, tmp);
+               tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+               WREG32(DC_HPD4_INT_CONTROL, tmp);
+               tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+               WREG32(DC_HPD5_INT_CONTROL, tmp);
+               tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+               WREG32(DC_HPD6_INT_CONTROL, tmp);
+       }
 }
 
 static int si_irq_init(struct radeon_device *rdev)
@@ -4366,7 +4574,7 @@ int si_irq_set(struct radeon_device *rdev)
        u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
        u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
        u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
-       u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
+       u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0;
        u32 grbm_int_cntl = 0;
        u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
        u32 dma_cntl, dma_cntl1;
@@ -4383,12 +4591,14 @@ int si_irq_set(struct radeon_device *rdev)
                return 0;
        }
 
-       hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
-       hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
-       hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
-       hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
-       hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
-       hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
+       if (!ASIC_IS_NODCE(rdev)) {
+               hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
+               hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
+               hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
+               hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
+               hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
+               hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
+       }
 
        dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
        dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
@@ -4479,8 +4689,10 @@ int si_irq_set(struct radeon_device *rdev)
 
        WREG32(GRBM_INT_CNTL, grbm_int_cntl);
 
-       WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
-       WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
+       if (rdev->num_crtc >= 2) {
+               WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
+               WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
+       }
        if (rdev->num_crtc >= 4) {
                WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
                WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
@@ -4490,8 +4702,10 @@ int si_irq_set(struct radeon_device *rdev)
                WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
        }
 
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
-       WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
+       if (rdev->num_crtc >= 2) {
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
+               WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
+       }
        if (rdev->num_crtc >= 4) {
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
@@ -4501,12 +4715,14 @@ int si_irq_set(struct radeon_device *rdev)
                WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
        }
 
-       WREG32(DC_HPD1_INT_CONTROL, hpd1);
-       WREG32(DC_HPD2_INT_CONTROL, hpd2);
-       WREG32(DC_HPD3_INT_CONTROL, hpd3);
-       WREG32(DC_HPD4_INT_CONTROL, hpd4);
-       WREG32(DC_HPD5_INT_CONTROL, hpd5);
-       WREG32(DC_HPD6_INT_CONTROL, hpd6);
+       if (!ASIC_IS_NODCE(rdev)) {
+               WREG32(DC_HPD1_INT_CONTROL, hpd1);
+               WREG32(DC_HPD2_INT_CONTROL, hpd2);
+               WREG32(DC_HPD3_INT_CONTROL, hpd3);
+               WREG32(DC_HPD4_INT_CONTROL, hpd4);
+               WREG32(DC_HPD5_INT_CONTROL, hpd5);
+               WREG32(DC_HPD6_INT_CONTROL, hpd6);
+       }
 
        return 0;
 }
@@ -4515,6 +4731,9 @@ static inline void si_irq_ack(struct radeon_device *rdev)
 {
        u32 tmp;
 
+       if (ASIC_IS_NODCE(rdev))
+               return;
+
        rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS);
        rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
        rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2);
@@ -5118,15 +5337,17 @@ static int si_startup(struct radeon_device *rdev)
                return r;
        }
 
-       r = rv770_uvd_resume(rdev);
-       if (!r) {
-               r = radeon_fence_driver_start_ring(rdev,
-                                                  R600_RING_TYPE_UVD_INDEX);
+       if (rdev->has_uvd) {
+               r = rv770_uvd_resume(rdev);
+               if (!r) {
+                       r = radeon_fence_driver_start_ring(rdev,
+                                                          R600_RING_TYPE_UVD_INDEX);
+                       if (r)
+                               dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
+               }
                if (r)
-                       dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
+                       rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
        }
-       if (r)
-               rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
 
        /* Enable IRQ */
        r = si_irq_init(rdev);
@@ -5185,16 +5406,18 @@ static int si_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
-       if (ring->ring_size) {
-               r = radeon_ring_init(rdev, ring, ring->ring_size,
-                                    R600_WB_UVD_RPTR_OFFSET,
-                                    UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
-                                    0, 0xfffff, RADEON_CP_PACKET2);
-               if (!r)
-                       r = r600_uvd_init(rdev);
-               if (r)
-                       DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
+       if (rdev->has_uvd) {
+               ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+               if (ring->ring_size) {
+                       r = radeon_ring_init(rdev, ring, ring->ring_size,
+                                            R600_WB_UVD_RPTR_OFFSET,
+                                            UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
+                                            0, 0xfffff, RADEON_CP_PACKET2);
+                       if (!r)
+                               r = r600_uvd_init(rdev);
+                       if (r)
+                               DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
+               }
        }
 
        r = radeon_ib_pool_init(rdev);
@@ -5243,8 +5466,10 @@ int si_suspend(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        si_cp_enable(rdev, false);
        cayman_dma_stop(rdev);
-       r600_uvd_rbc_stop(rdev);
-       radeon_uvd_suspend(rdev);
+       if (rdev->has_uvd) {
+               r600_uvd_rbc_stop(rdev);
+               radeon_uvd_suspend(rdev);
+       }
        si_irq_suspend(rdev);
        radeon_wb_disable(rdev);
        si_pcie_gart_disable(rdev);
@@ -5332,11 +5557,13 @@ int si_init(struct radeon_device *rdev)
        ring->ring_obj = NULL;
        r600_ring_init(rdev, ring, 64 * 1024);
 
-       r = radeon_uvd_init(rdev);
-       if (!r) {
-               ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
-               ring->ring_obj = NULL;
-               r600_ring_init(rdev, ring, 4096);
+       if (rdev->has_uvd) {
+               r = radeon_uvd_init(rdev);
+               if (!r) {
+                       ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+                       ring->ring_obj = NULL;
+                       r600_ring_init(rdev, ring, 4096);
+               }
        }
 
        rdev->ih.ring_obj = NULL;
@@ -5384,7 +5611,8 @@ void si_fini(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
-       radeon_uvd_fini(rdev);
+       if (rdev->has_uvd)
+               radeon_uvd_fini(rdev);
        si_pcie_gart_fini(rdev);
        r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
index 222877ba6cf5b3f9e8deb0738b15d5662aca0cf0..8f2d7d4f9b282e05f7d1e4f2e0b9d2e5325967c4 100644 (file)
@@ -28,6 +28,7 @@
 
 #define TAHITI_GB_ADDR_CONFIG_GOLDEN        0x12011003
 #define VERDE_GB_ADDR_CONFIG_GOLDEN         0x12010002
+#define HAINAN_GB_ADDR_CONFIG_GOLDEN        0x02010001
 
 /* discrete uvd clocks */
 #define        CG_UPLL_FUNC_CNTL                               0x634
index 1e2060324f02fd77cbbb3c4d5e2081816cbd0a53..8c04943f82e3531d75ee5565eab06c16e6f46b16 100644 (file)
@@ -1128,11 +1128,6 @@ static int tegra_dc_probe(struct platform_device *pdev)
                return err;
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!regs) {
-               dev_err(&pdev->dev, "failed to get registers\n");
-               return -ENXIO;
-       }
-
        dc->regs = devm_ioremap_resource(&pdev->dev, regs);
        if (IS_ERR(dc->regs))
                return PTR_ERR(dc->regs);
index bad8128b283a8752a11e1c3a13d02c83bb1df07b..21ef68934a20bba366c1ea1c5be9705f0fafe6fa 100644 (file)
@@ -329,7 +329,7 @@ static u32 get_vp_index(uuid_le *type_guid)
                return 0;
        }
        cur_cpu = (++next_vp % max_cpus);
-       return cur_cpu;
+       return hv_context.vp_index[cur_cpu];
 }
 
 /*
index df0b69987914d0c2241d746956db3d9d4e02a351..2ebd6ce46108ec4e44797cb695194672ad81bdac 100644 (file)
@@ -1414,14 +1414,18 @@ static int abituguru_probe(struct platform_device *pdev)
        pr_info("found Abit uGuru\n");
 
        /* Register sysfs hooks */
-       for (i = 0; i < sysfs_attr_i; i++)
-               if (device_create_file(&pdev->dev,
-                               &data->sysfs_attr[i].dev_attr))
+       for (i = 0; i < sysfs_attr_i; i++) {
+               res = device_create_file(&pdev->dev,
+                                        &data->sysfs_attr[i].dev_attr);
+               if (res)
                        goto abituguru_probe_error;
-       for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
-               if (device_create_file(&pdev->dev,
-                               &abituguru_sysfs_attr[i].dev_attr))
+       }
+       for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) {
+               res = device_create_file(&pdev->dev,
+                                        &abituguru_sysfs_attr[i].dev_attr);
+               if (res)
                        goto abituguru_probe_error;
+       }
 
        data->hwmon_dev = hwmon_device_register(&pdev->dev);
        if (!IS_ERR(data->hwmon_dev))
index aafa4531b9614e4b068c9b91698927272c7dc588..52b77afebde120a17ce75bf6401103cad556d021 100644 (file)
@@ -84,8 +84,10 @@ static int iio_hwmon_probe(struct platform_device *pdev)
                return PTR_ERR(channels);
 
        st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
-       if (st == NULL)
-               return -ENOMEM;
+       if (st == NULL) {
+               ret = -ENOMEM;
+               goto error_release_channels;
+       }
 
        st->channels = channels;
 
@@ -159,7 +161,7 @@ static int iio_hwmon_probe(struct platform_device *pdev)
 error_remove_group:
        sysfs_remove_group(&dev->kobj, &st->attr_group);
 error_release_channels:
-       iio_channel_release_all(st->channels);
+       iio_channel_release_all(channels);
        return ret;
 }
 
index f43f5e571db97a9b178f76a88ef82e8414c9ff39..04638aee90398f44e73a620e3a3cffc9631b8d40 100644 (file)
@@ -3705,8 +3705,10 @@ static int nct6775_probe(struct platform_device *pdev)
                        data->have_temp |= 1 << i;
                        data->have_temp_fixed |= 1 << i;
                        data->reg_temp[0][i] = reg_temp_alternate[i];
-                       data->reg_temp[1][i] = reg_temp_over[i];
-                       data->reg_temp[2][i] = reg_temp_hyst[i];
+                       if (i < num_reg_temp) {
+                               data->reg_temp[1][i] = reg_temp_over[i];
+                               data->reg_temp[2][i] = reg_temp_hyst[i];
+                       }
                        data->temp_src[i] = i + 1;
                        continue;
                }
index a478454f690fbc318aefa16b8952040944692149..dfe6d9527efb4b6489676468d495e56e7841b2a9 100644 (file)
@@ -240,7 +240,7 @@ static struct tmp401_data *tmp401_update_device(struct device *dev)
        mutex_lock(&data->update_lock);
 
        next_update = data->last_updated +
-                     msecs_to_jiffies(data->update_interval) + 1;
+                     msecs_to_jiffies(data->update_interval);
        if (time_after(jiffies, next_update) || !data->valid) {
                if (data->kind != tmp432) {
                        /*
index 21fbb340ad6603a249d052d8f7accb6aed0f7753..c41ca6354fc59d8d2111dfdbbb47bdab87f725a8 100644 (file)
@@ -383,7 +383,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
        /* Enable the adapter */
        __i2c_dw_enable(dev, true);
 
-       /* Enable interrupts */
+       /* Clear and enable interrupts */
+       i2c_dw_clear_int(dev);
        dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK);
 }
 
@@ -448,8 +449,14 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
                                cmd |= BIT(9);
 
                        if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
+
+                               /* avoid rx buffer overrun */
+                               if (rx_limit - dev->rx_outstanding <= 0)
+                                       break;
+
                                dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD);
                                rx_limit--;
+                               dev->rx_outstanding++;
                        } else
                                dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD);
                        tx_limit--; buf_len--;
@@ -502,8 +509,10 @@ i2c_dw_read(struct dw_i2c_dev *dev)
 
                rx_valid = dw_readl(dev, DW_IC_RXFLR);
 
-               for (; len > 0 && rx_valid > 0; len--, rx_valid--)
+               for (; len > 0 && rx_valid > 0; len--, rx_valid--) {
                        *buf++ = dw_readl(dev, DW_IC_DATA_CMD);
+                       dev->rx_outstanding--;
+               }
 
                if (len > 0) {
                        dev->status |= STATUS_READ_IN_PROGRESS;
@@ -561,6 +570,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        dev->msg_err = 0;
        dev->status = STATUS_IDLE;
        dev->abort_source = 0;
+       dev->rx_outstanding = 0;
 
        ret = i2c_dw_wait_bus_not_busy(dev);
        if (ret < 0)
index 9c1840ee09c7a4fde94a468a5ff339bdb42ae2ac..e761ad18dd61b8888e77a2989b772f79431d8b26 100644 (file)
@@ -60,6 +60,7 @@
  * @adapter: i2c subsystem adapter node
  * @tx_fifo_depth: depth of the hardware tx fifo
  * @rx_fifo_depth: depth of the hardware rx fifo
+ * @rx_outstanding: current master-rx elements in tx fifo
  */
 struct dw_i2c_dev {
        struct device           *dev;
@@ -88,6 +89,7 @@ struct dw_i2c_dev {
        u32                     master_cfg;
        unsigned int            tx_fifo_depth;
        unsigned int            rx_fifo_depth;
+       int                     rx_outstanding;
 };
 
 #define ACCESS_SWAP            0x00000001
index 8ec91335d95a52c679193cabbd4a522cbb3851bc..35b70a1edf572bedda30222ec8c9d49693491314 100644 (file)
@@ -69,6 +69,7 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
 static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "INT33C2", 0 },
        { "INT33C3", 0 },
+       { "80860F41", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
index e1cf2e0e1f23de900e92c1839d8c6e856658ea37..3a6903f639137af09d28ab623c345d01812bd0e7 100644 (file)
@@ -231,7 +231,11 @@ static const char *i801_feature_names[] = {
 
 static unsigned int disable_features;
 module_param(disable_features, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(disable_features, "Disable selected driver features");
+MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n"
+       "\t\t  0x01  disable SMBus PEC\n"
+       "\t\t  0x02  disable the block buffer\n"
+       "\t\t  0x08  disable the I2C block read functionality\n"
+       "\t\t  0x10  don't use interrupts ");
 
 /* Make sure the SMBus host is ready to start transmitting.
    Return 0 if it is, -EBUSY if it is not. */
index 3bbd65d35a5e05365361a4d7711e41de99fa8a31..1a3abd6a0bfcb7166bc7cfd7a9cb7be15016e48e 100644 (file)
@@ -252,7 +252,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
                writel(drv_data->cntl_bits,
                        drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
                drv_data->block = 0;
-               wake_up_interruptible(&drv_data->waitq);
+               wake_up(&drv_data->waitq);
                break;
 
        case MV64XXX_I2C_ACTION_CONTINUE:
@@ -300,7 +300,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
                writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
                        drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
                drv_data->block = 0;
-               wake_up_interruptible(&drv_data->waitq);
+               wake_up(&drv_data->waitq);
                break;
 
        case MV64XXX_I2C_ACTION_INVALID:
@@ -315,7 +315,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
                writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
                        drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
                drv_data->block = 0;
-               wake_up_interruptible(&drv_data->waitq);
+               wake_up(&drv_data->waitq);
                break;
        }
 }
@@ -381,7 +381,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
        unsigned long   flags;
        char            abort = 0;
 
-       time_left = wait_event_interruptible_timeout(drv_data->waitq,
+       time_left = wait_event_timeout(drv_data->waitq,
                !drv_data->block, drv_data->adapter.timeout);
 
        spin_lock_irqsave(&drv_data->lock, flags);
index 6e8ee92ab55398aec8f5517334166c38e9eb0ba8..cab1c91b75a3a8e300057ef2aaf3e98b6af999d4 100644 (file)
@@ -1082,11 +1082,6 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        /* map the registers */
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "cannot find IO resource\n");
-               return -ENOENT;
-       }
-
        i2c->regs = devm_ioremap_resource(&pdev->dev, res);
 
        if (IS_ERR(i2c->regs))
index 5a7ad240bd264bd53764f3053acab0e7127a28b7..a63c7d50683676f5e01969573ffce373b3ce578f 100644 (file)
@@ -303,12 +303,6 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
        adap->class = I2C_CLASS_HWMON;
 
        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (mem_res == NULL) {
-               dev_err(&pdev->dev, "Unable to get MEM resource\n");
-               err = -EINVAL;
-               goto out;
-       }
-
        siic->base = devm_ioremap_resource(&pdev->dev, mem_res);
        if (IS_ERR(siic->base)) {
                err = PTR_ERR(siic->base);
index b60ff90adc39a92ed3940a53076d53cf6f7ae4f6..9aa1b60f7fdd86581e2f694d96a2834e0ecad055 100644 (file)
@@ -714,11 +714,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
        int ret = 0;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "no mem resource\n");
-               return -EINVAL;
-       }
-
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base))
                return PTR_ERR(base);
index 6b63cc7eb71e38ff31253c0e6af496b3b3b0bccb..48e31ed69dbf159f5e44f2ab2a4968896320c3eb 100644 (file)
@@ -892,7 +892,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
 }
 
 static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device);
-static DEVICE_ATTR(delete_device, S_IWUSR, NULL, i2c_sysfs_delete_device);
+static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, S_IWUSR, NULL,
+                                  i2c_sysfs_delete_device);
 
 static struct attribute *i2c_adapter_attrs[] = {
        &dev_attr_name.attr,
index a0d931bcb37c5cda58766ff365a0a42dd112f45d..b02b679abf3183a7b6d798c212ed21b349453548 100644 (file)
@@ -107,6 +107,10 @@ static int create_gpio_led(const struct gpio_led *template,
                return 0;
        }
 
+       ret = devm_gpio_request(parent, template->gpio, template->name);
+       if (ret < 0)
+               return ret;
+
        led_dat->cdev.name = template->name;
        led_dat->cdev.default_trigger = template->default_trigger;
        led_dat->gpio = template->gpio;
@@ -126,10 +130,7 @@ static int create_gpio_led(const struct gpio_led *template,
        if (!template->retain_state_suspended)
                led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 
-       ret = devm_gpio_request_one(parent, template->gpio,
-                                   (led_dat->active_low ^ state) ?
-                                   GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
-                                   template->name);
+       ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
        if (ret < 0)
                return ret;
 
index 699187ab380099a32d926a83dde84d96e7124e85..5b9ac32801c7604b25c64804fb888aa1ebbbceab 100644 (file)
@@ -1002,6 +1002,7 @@ void guest_set_pgd(struct lguest *lg, unsigned long gpgdir, u32 idx)
                        kill_guest(&lg->cpus[0],
                                   "Cannot populate switcher mapping");
                }
+               lg->pgdirs[pgdir].last_host_cpu = -1;
        }
 }
 
index 759cffc45cabce8414c883f329b52fd56513bccf..88f2f802d528be23b8e64c26085913677082be03 100644 (file)
@@ -2188,7 +2188,7 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit)
 
        *need_commit = false;
 
-       metadata_dev_size = get_metadata_dev_size(pool->md_dev);
+       metadata_dev_size = get_metadata_dev_size_in_blocks(pool->md_dev);
 
        r = dm_pool_get_metadata_dev_size(pool->pmd, &sb_metadata_dev_size);
        if (r) {
@@ -2197,7 +2197,7 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit)
        }
 
        if (metadata_dev_size < sb_metadata_dev_size) {
-               DMERR("metadata device (%llu sectors) too small: expected %llu",
+               DMERR("metadata device (%llu blocks) too small: expected %llu",
                      metadata_dev_size, sb_metadata_dev_size);
                return -EINVAL;
 
index cadf1cc19aafb918d03665815caffb0c11839155..04644e7b42b123ca5407840d11a9e412a26dc6dd 100644 (file)
@@ -1560,12 +1560,6 @@ static int __init_or_module emif_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, emif);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(emif->dev, "%s: error getting memory resource\n",
-                       __func__);
-               goto error;
-       }
-
        emif->base = devm_ioremap_resource(emif->dev, res);
        if (IS_ERR(emif->base))
                goto error;
index d9aed1593e5d34855b488a89750da5ed68f1a0fe..d54e985748b78403956a0b7ba0d2b8634b949244 100644 (file)
@@ -579,7 +579,7 @@ config AB8500_CORE
 
 config AB8500_DEBUG
        bool "Enable debug info via debugfs"
-       depends on AB8500_CORE && DEBUG_FS
+       depends on AB8500_GPADC && DEBUG_FS
        default y if DEBUG_FS
        help
          Select this option if you want debug information using the debug
@@ -818,6 +818,7 @@ config MFD_TPS65910
 config MFD_TPS65912
        bool "TI TPS65912 Power Management chip"
        depends on GPIOLIB
+       select MFD_CORE
        help
          If you say yes here you get support for the TPS65912 series of
          PM chips.
index 8e8a016effe95251cca5692fed6c7b4442139630..258b367e39891468eb4dd0a9dabf05558a75446d 100644 (file)
@@ -867,6 +867,15 @@ static struct resource ab8500_chargalg_resources[] = {};
 
 #ifdef CONFIG_DEBUG_FS
 static struct resource ab8500_debug_resources[] = {
+       {
+               .name   = "IRQ_AB8500",
+               /*
+                * Number will be filled in. NOTE: this is deliberately
+                * not flagged as an IRQ in ordet to avoid remapping using
+                * the irqdomain in the MFD core, so that this IRQ passes
+                * unremapped to the debug code.
+                */
+       },
        {
                .name   = "IRQ_FIRST",
                .start  = AB8500_INT_MAIN_EXT_CH_NOT_OK,
@@ -1051,6 +1060,7 @@ static struct mfd_cell ab8500_devs[] = {
        },
        {
                .name = "ab8500-gpadc",
+               .of_compatible = "stericsson,ab8500-gpadc",
                .num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
                .resources = ab8500_gpadc_resources,
        },
@@ -1097,7 +1107,7 @@ static struct mfd_cell ab8500_devs[] = {
                .of_compatible = "stericsson,ab8500-denc",
        },
        {
-               .name = "ab8500-gpio",
+               .name = "pinctrl-ab8500",
                .of_compatible = "stericsson,ab8500-gpio",
        },
        {
@@ -1208,6 +1218,7 @@ static struct mfd_cell ab8505_devs[] = {
        },
        {
                .name = "ab8500-gpadc",
+               .of_compatible = "stericsson,ab8500-gpadc",
                .num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
                .resources = ab8505_gpadc_resources,
        },
@@ -1234,7 +1245,7 @@ static struct mfd_cell ab8505_devs[] = {
                .name = "ab8500-leds",
        },
        {
-               .name = "ab8500-gpio",
+               .name = "pinctrl-ab8505",
        },
        {
                .name = "ab8500-usb",
@@ -1271,6 +1282,7 @@ static struct mfd_cell ab8540_devs[] = {
        },
        {
                .name = "ab8500-gpadc",
+               .of_compatible = "stericsson,ab8500-gpadc",
                .num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
                .resources = ab8505_gpadc_resources,
        },
@@ -1302,7 +1314,7 @@ static struct mfd_cell ab8540_devs[] = {
                .resources = ab8500_temp_resources,
        },
        {
-               .name = "ab8500-gpio",
+               .name = "pinctrl-ab8540",
        },
        {
                .name = "ab8540-usb",
@@ -1712,6 +1724,12 @@ static int ab8500_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+#if CONFIG_DEBUG_FS
+       /* Pass to debugfs */
+       ab8500_debug_resources[0].start = ab8500->irq;
+       ab8500_debug_resources[0].end = ab8500->irq;
+#endif
+
        if (is_ab9540(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
                                ARRAY_SIZE(ab9540_devs), NULL,
index b88bbbc15f1e962f8f131d0f50bc25768091f55c..37b7ce4c7c3be57b4c8ea30474ec1edee47f8ad5 100644 (file)
 #include <linux/ctype.h>
 #endif
 
-/* TODO: this file should not reference IRQ_DB8500_AB8500! */
-#include <mach/irqs.h>
-
 static u32 debug_bank;
 static u32 debug_address;
 
+static int irq_ab8500;
 static int irq_first;
 static int irq_last;
 static u32 *irq_count;
@@ -1589,7 +1587,7 @@ void ab8500_debug_register_interrupt(int line)
 {
        if (line < num_interrupt_lines) {
                num_interrupts[line]++;
-               if (suspend_test_wake_cause_interrupt_is_mine(IRQ_DB8500_AB8500))
+               if (suspend_test_wake_cause_interrupt_is_mine(irq_ab8500))
                        num_wake_interrupts[line]++;
        }
 }
@@ -2941,6 +2939,7 @@ static int ab8500_debug_probe(struct platform_device *plf)
        struct dentry *file;
        int ret = -ENOMEM;
        struct ab8500 *ab8500;
+       struct resource *res;
        debug_bank = AB8500_MISC;
        debug_address = AB8500_REV_REG & 0x00FF;
 
@@ -2959,6 +2958,15 @@ static int ab8500_debug_probe(struct platform_device *plf)
        if (!event_name)
                goto out_freedev_attr;
 
+       res = platform_get_resource_byname(plf, 0, "IRQ_AB8500");
+       if (!res) {
+               dev_err(&plf->dev, "AB8500 irq not found, err %d\n",
+                       irq_first);
+               ret = -ENXIO;
+               goto out_freeevent_name;
+       }
+       irq_ab8500 = res->start;
+
        irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
        if (irq_first < 0) {
                dev_err(&plf->dev, "First irq not found, err %d\n",
index 5e65b28a5d0901e1dc5058c084dc444cd2c4a1bd..13f7866de46eb21a4cdf0363f0386d315f8171dd 100644 (file)
@@ -907,14 +907,17 @@ static int ab8500_gpadc_suspend(struct device *dev)
 static int ab8500_gpadc_resume(struct device *dev)
 {
        struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
+       int ret;
 
-       regulator_enable(gpadc->regu);
+       ret = regulator_enable(gpadc->regu);
+       if (ret)
+               dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret);
 
        pm_runtime_mark_last_busy(gpadc->dev);
        pm_runtime_put_autosuspend(gpadc->dev);
 
        mutex_unlock(&gpadc->ab8500_gpadc_lock);
-       return 0;
+       return ret;
 }
 
 static int ab8500_gpadc_probe(struct platform_device *pdev)
index fbca1ced49faac60bfffdef6ff6e19474475ff7b..8e0dae59844d494cd4e2c79904779b8f0a3c0acf 100644 (file)
@@ -23,7 +23,7 @@
 
 static struct device *sysctrl_dev;
 
-void ab8500_power_off(void)
+static void ab8500_power_off(void)
 {
        sigset_t old;
        sigset_t all;
@@ -104,7 +104,7 @@ void ab8500_restart(char mode, const char *cmd)
 
        plat = dev_get_platdata(sysctrl_dev->parent);
        pdata = plat->sysctrl;
-       if (pdata->reboot_reason_code)
+       if (pdata && pdata->reboot_reason_code)
                reason = pdata->reboot_reason_code(cmd);
        else
                pr_warn("[%s] No reboot reason set. Default reason %d\n",
@@ -188,14 +188,15 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 
        plat = dev_get_platdata(pdev->dev.parent);
 
-       if (!(plat && plat->sysctrl))
+       if (!plat)
                return -EINVAL;
 
-       if (plat->pm_power_off)
+       sysctrl_dev = &pdev->dev;
+
+       if (!pm_power_off)
                pm_power_off = ab8500_power_off;
 
        pdata = plat->sysctrl;
-
        if (pdata) {
                int last, ret, i, j;
 
@@ -226,6 +227,10 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 static int ab8500_sysctrl_remove(struct platform_device *pdev)
 {
        sysctrl_dev = NULL;
+
+       if (pm_power_off == ab8500_power_off)
+               pm_power_off = NULL;
+
        return 0;
 }
 
index 9818afba25153b377cf2b64b54b18bccc02f3e2c..3714acb6145864611cd29fd314c7bfd9d0af5bfb 100644 (file)
@@ -156,7 +156,7 @@ EXPORT_SYMBOL(abx500_startup_irq_enabled);
 void abx500_dump_all_banks(void)
 {
        struct abx500_ops *ops;
-       struct device dummy_child = {0};
+       struct device dummy_child = {NULL};
        struct abx500_device_entry *dev_entry;
 
        list_for_each_entry(dev_entry, &abx500_list, list) {
index 19193cf1e7a1bf9075a4eb63e157b6a419eba14f..367ccb58ecb15a1954cf39e936c46bc5a4bf3498 100644 (file)
@@ -120,7 +120,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
 
                for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
                        if (*ptr == EC_MSG_HEADER) {
-                               dev_dbg(ec_dev->dev, "msg found at %ld\n",
+                               dev_dbg(ec_dev->dev, "msg found at %zd\n",
                                        ptr - ec_dev->din);
                                break;
                        }
@@ -154,7 +154,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
                 * maximum-supported transfer size.
                 */
                todo = min(need_len, 256);
-               dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%ld\n",
+               dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
                        todo, need_len, ptr - ec_dev->din);
 
                memset(&trans, '\0', sizeof(trans));
@@ -178,7 +178,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
                need_len -= todo;
        }
 
-       dev_dbg(ec_dev->dev, "loop done, ptr=%ld\n", ptr - ec_dev->din);
+       dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din);
 
        return 0;
 }
index 319b8abe742b4ef0d4bf5b74e300514e5c031c91..66f80973596bd8833557d13c1bfc5426a6b1290d 100644 (file)
@@ -1613,6 +1613,8 @@ static unsigned long dsiclk_rate(u8 n)
 
        if (divsel == PRCM_DSI_PLLOUT_SEL_OFF)
                divsel = dsiclk[n].divsel;
+       else
+               dsiclk[n].divsel = divsel;
 
        switch (divsel) {
        case PRCM_DSI_PLLOUT_SEL_PHI_4:
@@ -3095,6 +3097,7 @@ static struct mfd_cell db8500_prcmu_devs[] = {
                .num_resources = ARRAY_SIZE(db8500_thsens_resources),
                .resources = db8500_thsens_resources,
                .platform_data = &db8500_thsens_data,
+               .pdata_size = sizeof(db8500_thsens_data),
        },
 };
 
index 5be3b5e13855045f27c4697da69710ec324e74e9..d8d5137f9717214f70b235c15e51215ac684807b 100644 (file)
@@ -414,11 +414,6 @@ static int intel_msic_probe(struct platform_device *pdev)
         * the clients via intel_msic_irq_read().
         */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "failed to get SRAM iomem resource\n");
-               return -ENODEV;
-       }
-
        msic->irq_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(msic->irq_base))
                return PTR_ERR(msic->irq_base);
index de48b4e884501b7cce5540f87f9144c0a8b60742..6f1ef63086c9df98c56c00369c7b91b60c5320c5 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <linux/mfd/si476x-core.h>
 
+#include <asm/unaligned.h>
+
 #define msb(x)                  ((u8)((u16) x >> 8))
 #define lsb(x)                  ((u8)((u16) x &  0x00FF))
 
@@ -150,7 +152,7 @@ enum si476x_acf_status_report_bits {
        SI476X_ACF_SOFTMUTE_INT = (1 << 0),
 
        SI476X_ACF_SMUTE        = (1 << 0),
-       SI476X_ACF_SMATTN       = 0b11111,
+       SI476X_ACF_SMATTN       = 0x1f,
        SI476X_ACF_PILOT        = (1 << 7),
        SI476X_ACF_STBLEND      = ~SI476X_ACF_PILOT,
 };
@@ -483,7 +485,7 @@ int si476x_core_cmd_get_property(struct si476x_core *core, u16 property)
        if (err < 0)
                return err;
        else
-               return be16_to_cpup((__be16 *)(resp + 2));
+               return get_unaligned_be16(resp + 2);
 }
 EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property);
 
@@ -772,18 +774,18 @@ int si476x_core_cmd_am_rsq_status(struct si476x_core *core,
        if (!report)
                return err;
 
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
 
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
 
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -931,26 +933,26 @@ int si476x_core_cmd_fm_rds_status(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->rdstpptyint     = 0b00010000 & resp[1];
-       report->rdspiint        = 0b00001000 & resp[1];
-       report->rdssyncint      = 0b00000010 & resp[1];
-       report->rdsfifoint      = 0b00000001 & resp[1];
+       report->rdstpptyint     = 0x10 & resp[1];
+       report->rdspiint        = 0x08 & resp[1];
+       report->rdssyncint      = 0x02 & resp[1];
+       report->rdsfifoint      = 0x01 & resp[1];
 
-       report->tpptyvalid      = 0b00010000 & resp[2];
-       report->pivalid         = 0b00001000 & resp[2];
-       report->rdssync         = 0b00000010 & resp[2];
-       report->rdsfifolost     = 0b00000001 & resp[2];
+       report->tpptyvalid      = 0x10 & resp[2];
+       report->pivalid         = 0x08 & resp[2];
+       report->rdssync         = 0x02 & resp[2];
+       report->rdsfifolost     = 0x01 & resp[2];
 
-       report->tp              = 0b00100000 & resp[3];
-       report->pty             = 0b00011111 & resp[3];
+       report->tp              = 0x20 & resp[3];
+       report->pty             = 0x1f & resp[3];
 
-       report->pi              = be16_to_cpup((__be16 *)(resp + 4));
+       report->pi              = get_unaligned_be16(resp + 4);
        report->rdsfifoused     = resp[6];
 
-       report->ble[V4L2_RDS_BLOCK_A]   = 0b11000000 & resp[7];
-       report->ble[V4L2_RDS_BLOCK_B]   = 0b00110000 & resp[7];
-       report->ble[V4L2_RDS_BLOCK_C]   = 0b00001100 & resp[7];
-       report->ble[V4L2_RDS_BLOCK_D]   = 0b00000011 & resp[7];
+       report->ble[V4L2_RDS_BLOCK_A]   = 0xc0 & resp[7];
+       report->ble[V4L2_RDS_BLOCK_B]   = 0x30 & resp[7];
+       report->ble[V4L2_RDS_BLOCK_C]   = 0x0c & resp[7];
+       report->ble[V4L2_RDS_BLOCK_D]   = 0x03 & resp[7];
 
        report->rds[V4L2_RDS_BLOCK_A].block = V4L2_RDS_BLOCK_A;
        report->rds[V4L2_RDS_BLOCK_A].msb = resp[8];
@@ -991,9 +993,9 @@ int si476x_core_cmd_fm_rds_blockcount(struct si476x_core *core,
                                       SI476X_DEFAULT_TIMEOUT);
 
        if (!err) {
-               report->expected        = be16_to_cpup((__be16 *)(resp + 2));
-               report->received        = be16_to_cpup((__be16 *)(resp + 4));
-               report->uncorrectable   = be16_to_cpup((__be16 *)(resp + 6));
+               report->expected        = get_unaligned_be16(resp + 2);
+               report->received        = get_unaligned_be16(resp + 4);
+               report->uncorrectable   = get_unaligned_be16(resp + 6);
        }
 
        return err;
@@ -1005,7 +1007,7 @@ int si476x_core_cmd_fm_phase_diversity(struct si476x_core *core,
 {
        u8       resp[CMD_FM_PHASE_DIVERSITY_NRESP];
        const u8 args[CMD_FM_PHASE_DIVERSITY_NARGS] = {
-               mode & 0b111,
+               mode & 0x07,
        };
 
        return si476x_core_send_command(core, CMD_FM_PHASE_DIVERSITY,
@@ -1162,7 +1164,7 @@ static int si476x_core_cmd_am_tune_freq_a20(struct si476x_core *core,
        const int am_freq = tuneargs->freq;
        u8       resp[CMD_AM_TUNE_FREQ_NRESP];
        const u8 args[CMD_AM_TUNE_FREQ_NARGS] = {
-               (tuneargs->zifsr << 6) | (tuneargs->injside & 0b11),
+               (tuneargs->zifsr << 6) | (tuneargs->injside & 0x03),
                msb(am_freq),
                lsb(am_freq),
        };
@@ -1197,20 +1199,20 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->multhint        = 0b10000000 & resp[1];
-       report->multlint        = 0b01000000 & resp[1];
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
+       report->multhint        = 0x80 & resp[1];
+       report->multlint        = 0x40 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
 
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
 
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -1218,7 +1220,7 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core,
        report->hassi           = resp[10];
        report->mult            = resp[11];
        report->dev             = resp[12];
-       report->readantcap      = be16_to_cpup((__be16 *)(resp + 13));
+       report->readantcap      = get_unaligned_be16(resp + 13);
        report->assi            = resp[15];
        report->usn             = resp[16];
 
@@ -1251,20 +1253,20 @@ static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->multhint        = 0b10000000 & resp[1];
-       report->multlint        = 0b01000000 & resp[1];
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
+       report->multhint        = 0x80 & resp[1];
+       report->multlint        = 0x40 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
 
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
 
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -1272,7 +1274,7 @@ static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core,
        report->hassi           = resp[10];
        report->mult            = resp[11];
        report->dev             = resp[12];
-       report->readantcap      = be16_to_cpup((__be16 *)(resp + 13));
+       report->readantcap      = get_unaligned_be16(resp + 13);
        report->assi            = resp[15];
        report->usn             = resp[16];
 
@@ -1306,21 +1308,21 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
        if (err < 0 || report == NULL)
                return err;
 
-       report->multhint        = 0b10000000 & resp[1];
-       report->multlint        = 0b01000000 & resp[1];
-       report->snrhint         = 0b00001000 & resp[1];
-       report->snrlint         = 0b00000100 & resp[1];
-       report->rssihint        = 0b00000010 & resp[1];
-       report->rssilint        = 0b00000001 & resp[1];
-
-       report->bltf            = 0b10000000 & resp[2];
-       report->snr_ready       = 0b00100000 & resp[2];
-       report->rssiready       = 0b00001000 & resp[2];
-       report->injside         = 0b00000100 & resp[2];
-       report->afcrl           = 0b00000010 & resp[2];
-       report->valid           = 0b00000001 & resp[2];
-
-       report->readfreq        = be16_to_cpup((__be16 *)(resp + 3));
+       report->multhint        = 0x80 & resp[1];
+       report->multlint        = 0x40 & resp[1];
+       report->snrhint         = 0x08 & resp[1];
+       report->snrlint         = 0x04 & resp[1];
+       report->rssihint        = 0x02 & resp[1];
+       report->rssilint        = 0x01 & resp[1];
+
+       report->bltf            = 0x80 & resp[2];
+       report->snr_ready       = 0x20 & resp[2];
+       report->rssiready       = 0x08 & resp[2];
+       report->injside         = 0x04 & resp[2];
+       report->afcrl           = 0x02 & resp[2];
+       report->valid           = 0x01 & resp[2];
+
+       report->readfreq        = get_unaligned_be16(resp + 3);
        report->freqoff         = resp[5];
        report->rssi            = resp[6];
        report->snr             = resp[7];
@@ -1329,7 +1331,7 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
        report->hassi           = resp[10];
        report->mult            = resp[11];
        report->dev             = resp[12];
-       report->readantcap      = be16_to_cpup((__be16 *)(resp + 13));
+       report->readantcap      = get_unaligned_be16(resp + 13);
        report->assi            = resp[15];
        report->usn             = resp[16];
 
@@ -1337,7 +1339,7 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
        report->rdsdev          = resp[18];
        report->assidev         = resp[19];
        report->strongdev       = resp[20];
-       report->rdspi           = be16_to_cpup((__be16 *)(resp + 21));
+       report->rdspi           = get_unaligned_be16(resp + 21);
 
        return err;
 }
index c09c28f92055b156245305da692e1c98582839cc..1abd5ad599251cc655672f656c2718bf65c49aa2 100644 (file)
@@ -154,11 +154,6 @@ static int ssc_probe(struct platform_device *pdev)
        ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat;
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!regs) {
-               dev_dbg(&pdev->dev, "no mmio resource defined\n");
-               return -ENXIO;
-       }
-
        ssc->regs = devm_ioremap_resource(&pdev->dev, regs);
        if (IS_ERR(ssc->regs))
                return PTR_ERR(ssc->regs);
index 7014167e2c619f23acc05398973552fd8ab23f9e..c37eeedfe215634775a59fa581d83f749a3fb536 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 
-static int irq;
+static int irq = -1;
 
 static irqreturn_t dummy_interrupt(int irq, void *dev_id)
 {
@@ -36,6 +36,10 @@ static irqreturn_t dummy_interrupt(int irq, void *dev_id)
 
 static int __init dummy_irq_init(void)
 {
+       if (irq < 0) {
+               printk(KERN_ERR "dummy-irq: no IRQ given.  Use irq=N\n");
+               return -EIO;
+       }
        if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) {
                printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq);
                return -EIO;
index 1e935eacaa7faee9903e20303dc703c75ed014ff..9ecd49a7be1b33cac4ece186e35e3ebc255d9d78 100644 (file)
@@ -496,6 +496,8 @@ int mei_cl_disable_device(struct mei_cl_device *device)
                }
        }
 
+       device->event_cb = NULL;
+
        mutex_unlock(&dev->device_lock);
 
        if (!device->ops || !device->ops->disable)
index 7c44c8dbae424904c53e041f5723ab51bf974e6f..053139f610861fa98c6778176d86f5a4969660f7 100644 (file)
@@ -489,11 +489,16 @@ static int mei_ioctl_connect_client(struct file *file,
 
        /* find ME client we're trying to connect to */
        i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
-       if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
-               cl->me_client_id = dev->me_clients[i].client_id;
-               cl->state = MEI_FILE_CONNECTING;
+       if (i < 0 || dev->me_clients[i].props.fixed_address) {
+               dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n",
+                               &data->in_client_uuid);
+               rets = -ENODEV;
+               goto end;
        }
 
+       cl->me_client_id = dev->me_clients[i].client_id;
+       cl->state = MEI_FILE_CONNECTING;
+
        dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
                        cl->me_client_id);
        dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
@@ -527,11 +532,6 @@ static int mei_ioctl_connect_client(struct file *file,
                goto end;
        }
 
-       if (cl->state != MEI_FILE_CONNECTING) {
-               rets = -ENODEV;
-               goto end;
-       }
-
 
        /* prepare the output buffer */
        client = &data->out_client_properties;
@@ -543,7 +543,6 @@ static int mei_ioctl_connect_client(struct file *file,
        rets = mei_cl_connect(cl, file);
 
 end:
-       dev_dbg(&dev->pdev->dev, "free connect cb memory.");
        return rets;
 }
 
index ea98f7e9ccd19d6ef8ea862616bcc4c0f3055b8d..39c2ecadb273d374b41be572bee6431e7b81e784 100644 (file)
@@ -4,7 +4,7 @@
 
 config VMWARE_VMCI
        tristate "VMware VMCI Driver"
-       depends on X86 && PCI && NET
+       depends on X86 && PCI
        help
          This is VMware's Virtual Machine Communication Interface.  It enables
          high-speed communication between host and guest in a virtual
index d94245dbd7651edc70e9bb23d6d9dcacbfdbd5d7..8ff2e5ee8fb8b955f8da30c8b2a2eba94ed43710 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/pagemap.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/socket.h>
+#include <linux/uio.h>
 #include <linux/wait.h>
 #include <linux/vmalloc.h>
 
index 375c109607ff2020e632834cb4ffe7eca95fc2b1..f4f3038c1df08e2d5934014875abe38782f67db6 100644 (file)
@@ -1130,6 +1130,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct variant_data *variant = host->variant;
        u32 pwr = 0;
        unsigned long flags;
+       int ret;
 
        pm_runtime_get_sync(mmc_dev(mmc));
 
@@ -1161,8 +1162,12 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                break;
        case MMC_POWER_ON:
                if (!IS_ERR(mmc->supply.vqmmc) &&
-                   !regulator_is_enabled(mmc->supply.vqmmc))
-                       regulator_enable(mmc->supply.vqmmc);
+                   !regulator_is_enabled(mmc->supply.vqmmc)) {
+                       ret = regulator_enable(mmc->supply.vqmmc);
+                       if (ret < 0)
+                               dev_err(mmc_dev(mmc),
+                                       "failed to enable vqmmc regulator\n");
+               }
 
                pwr |= MCI_PWR_ON;
                break;
index a94facb46e5ca76bb239af03a32b160571ccd467..fd1df5e13ae44d77207d19fb492064166bf46525 100644 (file)
@@ -672,11 +672,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
        }
 
        rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (rc == NULL) {
-               dev_err(&pdev->dev, "No memory resource found for device!\r\n");
-               return -ENXIO;
-       }
-
        host->io_base = devm_ioremap_resource(&pdev->dev, rc);
        if (IS_ERR(host->io_base))
                return PTR_ERR(host->io_base);
index 7ffc756131a214a7b896f81d05e9c499c12cf752..547098086773cd06a936a4010bb8b66ffc933dfd 100644 (file)
@@ -43,7 +43,7 @@ config CAIF_HSI
 
 config CAIF_VIRTIO
        tristate "CAIF virtio transport driver"
-       depends on CAIF
+       depends on CAIF && HAS_DMA
        select VHOST_RING
        select VIRTIO
        select GENERIC_ALLOCATOR
index de570a8f896742f5e0c345579b736d8030326356..072c6f14e8fcea3c88f04d74d68afa73aef60554 100644 (file)
@@ -632,7 +632,6 @@ struct vortex_private {
                pm_state_valid:1,                               /* pci_dev->saved_config_space has sane contents */
                open:1,
                medialock:1,
-               must_free_region:1,                             /* Flag: if zero, Cardbus owns the I/O region */
                large_frames:1,                 /* accept large frames */
                handling_irq:1;                 /* private in_irq indicator */
        /* {get|set}_wol operations are already serialized by rtnl.
@@ -1012,6 +1011,12 @@ static int vortex_init_one(struct pci_dev *pdev,
        if (rc < 0)
                goto out;
 
+       rc = pci_request_regions(pdev, DRV_NAME);
+       if (rc < 0) {
+               pci_disable_device(pdev);
+               goto out;
+       }
+
        unit = vortex_cards_found;
 
        if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
@@ -1027,6 +1032,7 @@ static int vortex_init_one(struct pci_dev *pdev,
        if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
                ioaddr = pci_iomap(pdev, 0, 0);
        if (!ioaddr) {
+               pci_release_regions(pdev);
                pci_disable_device(pdev);
                rc = -ENOMEM;
                goto out;
@@ -1036,6 +1042,7 @@ static int vortex_init_one(struct pci_dev *pdev,
                           ent->driver_data, unit);
        if (rc < 0) {
                pci_iounmap(pdev, ioaddr);
+               pci_release_regions(pdev);
                pci_disable_device(pdev);
                goto out;
        }
@@ -1178,11 +1185,6 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
 
        /* PCI-only startup logic */
        if (pdev) {
-               /* EISA resources already marked, so only PCI needs to do this here */
-               /* Ignore return value, because Cardbus drivers already allocate for us */
-               if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
-                       vp->must_free_region = 1;
-
                /* enable bus-mastering if necessary */
                if (vci->flags & PCI_USES_MASTER)
                        pci_set_master(pdev);
@@ -1220,7 +1222,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
                                           &vp->rx_ring_dma);
        retval = -ENOMEM;
        if (!vp->rx_ring)
-               goto free_region;
+               goto free_device;
 
        vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE);
        vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE;
@@ -1484,9 +1486,7 @@ free_ring:
                                                        + sizeof(struct boom_tx_desc) * TX_RING_SIZE,
                                                vp->rx_ring,
                                                vp->rx_ring_dma);
-free_region:
-       if (vp->must_free_region)
-               release_region(dev->base_addr, vci->io_size);
+free_device:
        free_netdev(dev);
        pr_err(PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
@@ -3254,8 +3254,9 @@ static void vortex_remove_one(struct pci_dev *pdev)
                                                        + sizeof(struct boom_tx_desc) * TX_RING_SIZE,
                                                vp->rx_ring,
                                                vp->rx_ring_dma);
-       if (vp->must_free_region)
-               release_region(dev->base_addr, vp->io_size);
+
+       pci_release_regions(pdev);
+
        free_netdev(dev);
 }
 
index ce4a030d3d0cab9705e8715b6169a9031b0fd840..07f7ef05c3f20b00b3b3f287b412deb1ff747b35 100644 (file)
@@ -3236,9 +3236,10 @@ bnad_init(struct bnad *bnad,
 
        sprintf(bnad->wq_name, "%s_wq_%d", BNAD_NAME, bnad->id);
        bnad->work_q = create_singlethread_workqueue(bnad->wq_name);
-
-       if (!bnad->work_q)
+       if (!bnad->work_q) {
+               iounmap(bnad->bar0);
                return -ENOMEM;
+       }
 
        return 0;
 }
index 1194446f859a0018f2be94d945b03a64a568d861..768285ec10f4d427362cc595be307e8e4d447eb0 100644 (file)
@@ -22,7 +22,7 @@ if NET_CADENCE
 
 config ARM_AT91_ETHER
        tristate "AT91RM9200 Ethernet support"
-       depends on GENERIC_HARDIRQS
+       depends on GENERIC_HARDIRQS && HAS_DMA
        select NET_CORE
        select MACB
        ---help---
@@ -31,6 +31,7 @@ config ARM_AT91_ETHER
 
 config MACB
        tristate "Cadence MACB/GEM support"
+       depends on HAS_DMA
        select PHYLIB
        ---help---
          The Cadence MACB ethernet interface is found on many Atmel AT32 and
index aba435c3d4ae9fa315cbb3781447cb0b1ac1470e..184a063bed5fa59bbdc705e29355134a2d31d731 100644 (file)
@@ -1,6 +1,6 @@
 config NET_CALXEDA_XGMAC
        tristate "Calxeda 1G/10G XGMAC Ethernet driver"
-       depends on HAS_IOMEM
+       depends on HAS_IOMEM && HAS_DMA
        select CRC32
        help
          This is the driver for the XGMAC Ethernet IP block found on Calxeda
index aff0310a778bf7afb545c4b53f995770f7f03ec2..ca9825ca88c92c91adc24e16fd995bff076e4b67 100644 (file)
@@ -87,6 +87,8 @@
 #define FEC_QUIRK_HAS_GBIT             (1 << 3)
 /* Controller has extend desc buffer */
 #define FEC_QUIRK_HAS_BUFDESC_EX       (1 << 4)
+/* Controller has hardware checksum support */
+#define FEC_QUIRK_HAS_CSUM             (1 << 5)
 
 static struct platform_device_id fec_devtype[] = {
        {
@@ -105,7 +107,7 @@ static struct platform_device_id fec_devtype[] = {
        }, {
                .name = "imx6q-fec",
                .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
-                               FEC_QUIRK_HAS_BUFDESC_EX,
+                               FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM,
        }, {
                .name = "mvf-fec",
                .driver_data = FEC_QUIRK_ENET_MAC,
@@ -1744,6 +1746,8 @@ static const struct net_device_ops fec_netdev_ops = {
 static int fec_enet_init(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
+       const struct platform_device_id *id_entry =
+                               platform_get_device_id(fep->pdev);
        struct bufdesc *cbd_base;
 
        /* Allocate memory for buffer descriptors. */
@@ -1775,12 +1779,14 @@ static int fec_enet_init(struct net_device *ndev)
        writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
        netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT);
 
-       /* enable hw accelerator */
-       ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
-                       | NETIF_F_RXCSUM);
-       ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
-                       | NETIF_F_RXCSUM);
-       fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
+       if (id_entry->driver_data & FEC_QUIRK_HAS_CSUM) {
+               /* enable hw accelerator */
+               ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
+                               | NETIF_F_RXCSUM);
+               ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
+                               | NETIF_F_RXCSUM);
+               fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
+       }
 
        fec_restart(ndev, 0);
 
index 4989481c19f01b6dad9b560b535b6127da416eee..d300a0c0eafc0521a4e86688abd7e54afd0ce58e 100644 (file)
@@ -359,10 +359,26 @@ static int emac_reset(struct emac_instance *dev)
        }
 
 #ifdef CONFIG_PPC_DCR_NATIVE
-       /* Enable internal clock source */
-       if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX))
-               dcri_clrset(SDR0, SDR0_ETH_CFG,
-                           0, SDR0_ETH_CFG_ECS << dev->cell_index);
+       /*
+        * PPC460EX/GT Embedded Processor Advanced User's Manual
+        * section 28.10.1 Mode Register 0 (EMACx_MR0) states:
+        * Note: The PHY must provide a TX Clk in order to perform a soft reset
+        * of the EMAC. If none is present, select the internal clock
+        * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).
+        * After a soft reset, select the external clock.
+        */
+       if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
+               if (dev->phy_address == 0xffffffff &&
+                   dev->phy_map == 0xffffffff) {
+                       /* No PHY: select internal loop clock before reset */
+                       dcri_clrset(SDR0, SDR0_ETH_CFG,
+                                   0, SDR0_ETH_CFG_ECS << dev->cell_index);
+               } else {
+                       /* PHY present: select external clock before reset */
+                       dcri_clrset(SDR0, SDR0_ETH_CFG,
+                                   SDR0_ETH_CFG_ECS << dev->cell_index, 0);
+               }
+       }
 #endif
 
        out_be32(&p->mr0, EMAC_MR0_SRST);
@@ -370,10 +386,14 @@ static int emac_reset(struct emac_instance *dev)
                --n;
 
 #ifdef CONFIG_PPC_DCR_NATIVE
-        /* Enable external clock source */
-       if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX))
-               dcri_clrset(SDR0, SDR0_ETH_CFG,
-                           SDR0_ETH_CFG_ECS << dev->cell_index, 0);
+       if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
+               if (dev->phy_address == 0xffffffff &&
+                   dev->phy_map == 0xffffffff) {
+                       /* No PHY: restore external clock source after reset */
+                       dcri_clrset(SDR0, SDR0_ETH_CFG,
+                                   SDR0_ETH_CFG_ECS << dev->cell_index, 0);
+               }
+       }
 #endif
 
        if (n) {
index 91f2b2c43c12669f796ddf0327baa18c33025891..d3f508697a3dd664f65a687c81964f30fee04a93 100644 (file)
@@ -60,7 +60,7 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
        context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6;
        if (user_prio >= 0) {
                context->pri_path.sched_queue |= user_prio << 3;
-               context->pri_path.feup = 1 << 6;
+               context->pri_path.feup = MLX4_FEUP_FORCE_ETH_UP;
        }
        context->pri_path.counter_index = 0xff;
        context->cqn_send = cpu_to_be32(cqn);
index b147bdd40768802df3c11d935b1ed607b3e127c9..58a8e535d69833edd7c66f68a64b4e13b259d86c 100644 (file)
@@ -131,7 +131,9 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
                [2] = "RSS XOR Hash Function support",
                [3] = "Device manage flow steering support",
                [4] = "Automatic MAC reassignment support",
-               [5] = "Time stamping support"
+               [5] = "Time stamping support",
+               [6] = "VST (control vlan insertion/stripping) support",
+               [7] = "FSM (MAC anti-spoofing) support"
        };
        int i;
 
index e12e0d2e0ee00c3fad03c1c012707c55d6f21a88..1157f028a90f341a50c300c40ba8e967d9fb2e01 100644 (file)
@@ -372,24 +372,29 @@ static int update_vport_qp_param(struct mlx4_dev *dev,
                if (MLX4_QP_ST_RC == qp_type)
                        return -EINVAL;
 
+               /* force strip vlan by clear vsd */
+               qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN);
+               if (0 != vp_oper->state.default_vlan) {
+                       qpc->pri_path.vlan_control =
+                               MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
+                               MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
+                               MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
+               } else { /* priority tagged */
+                       qpc->pri_path.vlan_control =
+                               MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
+                               MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
+               }
+
+               qpc->pri_path.fvl_rx |= MLX4_FVL_RX_FORCE_ETH_VLAN;
                qpc->pri_path.vlan_index = vp_oper->vlan_idx;
-               qpc->pri_path.fl = (1 << 6) | (1 << 2); /* set cv bit and hide_cqe_vlan bit*/
-               qpc->pri_path.feup |= 1 << 3; /* set fvl bit */
+               qpc->pri_path.fl |= MLX4_FL_CV | MLX4_FL_ETH_HIDE_CQE_VLAN;
+               qpc->pri_path.feup |= MLX4_FEUP_FORCE_ETH_UP | MLX4_FVL_FORCE_ETH_VLAN;
                qpc->pri_path.sched_queue &= 0xC7;
                qpc->pri_path.sched_queue |= (vp_oper->state.default_qos) << 3;
-               mlx4_dbg(dev, "qp %d  port %d Q 0x%x set vlan to %d vidx %d feup %x fl %x\n",
-                        be32_to_cpu(qpc->local_qpn) & 0xffffff, port,
-                        (int)(qpc->pri_path.sched_queue), vp_oper->state.default_vlan,
-                        vp_oper->vlan_idx, (int)(qpc->pri_path.feup),
-                        (int)(qpc->pri_path.fl));
        }
        if (vp_oper->state.spoofchk) {
-               qpc->pri_path.feup |= 1 << 5; /* set fsm bit */;
+               qpc->pri_path.feup |= MLX4_FSM_FORCE_ETH_SRC_MAC;
                qpc->pri_path.grh_mylmc = (0x80 & qpc->pri_path.grh_mylmc) + vp_oper->mac_idx;
-               mlx4_dbg(dev, "spoof qp %d  port %d feup  0x%x, myLmc 0x%x mindx %d\n",
-                        be32_to_cpu(qpc->local_qpn) & 0xffffff, port,
-                        (int)qpc->pri_path.feup, (int)qpc->pri_path.grh_mylmc,
-                        vp_oper->mac_idx);
        }
        return 0;
 }
index 90c253b145eff8b9ae622877933f101cdf70b633..019c5f78732ead011ca07edecee78ac435368ff1 100644 (file)
@@ -429,6 +429,7 @@ struct qlcnic_hardware_context {
 
        u16 port_type;
        u16 board_type;
+       u16 supported_type;
 
        u16 link_speed;
        u16 link_duplex;
@@ -1514,6 +1515,7 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter);
 void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter);
 void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter);
 void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter);
+int qlcnic_82xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
 
 int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
 int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
index ea790a93ee7c0e79acedd062a1d1795fb413e8c4..b4ff1e35a11de24863966e1b8cdae2898cda8c6a 100644 (file)
@@ -696,15 +696,14 @@ u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
        return 1;
 }
 
-u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter)
+u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time)
 {
        u32 data;
-       unsigned long wait_time = 0;
        struct qlcnic_hardware_context *ahw = adapter->ahw;
        /* wait for mailbox completion */
        do {
                data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
-               if (++wait_time > QLCNIC_MBX_TIMEOUT) {
+               if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) {
                        data = QLCNIC_RCODE_TIMEOUT;
                        break;
                }
@@ -720,8 +719,8 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
        u16 opcode;
        u8 mbx_err_code;
        unsigned long flags;
-       u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
        struct qlcnic_hardware_context *ahw = adapter->ahw;
+       u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0;
 
        opcode = LSW(cmd->req.arg[0]);
        if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
@@ -754,15 +753,13 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
        /* Signal FW about the impending command */
        QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
 poll:
-       rsp = qlcnic_83xx_mbx_poll(adapter);
+       rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
        if (rsp != QLCNIC_RCODE_TIMEOUT) {
                /* Get the FW response data */
                fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
                if (fw_data &  QLCNIC_MBX_ASYNC_EVENT) {
                        __qlcnic_83xx_process_aen(adapter);
-                       mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
-                       if (mbx_val)
-                               goto poll;
+                       goto poll;
                }
                mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
                rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
@@ -1276,11 +1273,13 @@ out:
        return err;
 }
 
-static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test)
+static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
+                                     int num_sds_ring)
 {
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
        struct qlcnic_host_sds_ring *sds_ring;
        struct qlcnic_host_rds_ring *rds_ring;
+       u16 adapter_state = adapter->is_up;
        u8 ring;
        int ret;
 
@@ -1304,6 +1303,10 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test)
        ret = qlcnic_fw_create_ctx(adapter);
        if (ret) {
                qlcnic_detach(adapter);
+               if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
+                       adapter->max_sds_rings = num_sds_ring;
+                       qlcnic_attach(adapter);
+               }
                netif_device_attach(netdev);
                return ret;
        }
@@ -1596,7 +1599,8 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
                return -EBUSY;
 
-       ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
+       ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
+                                        max_sds_rings);
        if (ret)
                goto fail_diag_alloc;
 
@@ -2830,6 +2834,23 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
                        break;
                }
                config = cmd.rsp.arg[3];
+               if (QLC_83XX_SFP_PRESENT(config)) {
+                       switch (ahw->module_type) {
+                       case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
+                       case LINKEVENT_MODULE_OPTICAL_SRLR:
+                       case LINKEVENT_MODULE_OPTICAL_LRM:
+                       case LINKEVENT_MODULE_OPTICAL_SFP_1G:
+                               ahw->supported_type = PORT_FIBRE;
+                               break;
+                       case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
+                       case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
+                       case LINKEVENT_MODULE_TWINAX:
+                               ahw->supported_type = PORT_TP;
+                               break;
+                       default:
+                               ahw->supported_type = PORT_OTHER;
+                       }
+               }
                if (config & 1)
                        err = 1;
        }
@@ -2838,7 +2859,8 @@ out:
        return config;
 }
 
-int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter)
+int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
+                            struct ethtool_cmd *ecmd)
 {
        u32 config = 0;
        int status = 0;
@@ -2851,6 +2873,54 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter)
        ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
        /* hard code until there is a way to get it from flash */
        ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
+
+       if (netif_running(adapter->netdev) && ahw->has_link_events) {
+               ethtool_cmd_speed_set(ecmd, ahw->link_speed);
+               ecmd->duplex = ahw->link_duplex;
+               ecmd->autoneg = ahw->link_autoneg;
+       } else {
+               ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+               ecmd->duplex = DUPLEX_UNKNOWN;
+               ecmd->autoneg = AUTONEG_DISABLE;
+       }
+
+       if (ahw->port_type == QLCNIC_XGBE) {
+               ecmd->supported = SUPPORTED_1000baseT_Full;
+               ecmd->advertising = ADVERTISED_1000baseT_Full;
+       } else {
+               ecmd->supported = (SUPPORTED_10baseT_Half |
+                                  SUPPORTED_10baseT_Full |
+                                  SUPPORTED_100baseT_Half |
+                                  SUPPORTED_100baseT_Full |
+                                  SUPPORTED_1000baseT_Half |
+                                  SUPPORTED_1000baseT_Full);
+               ecmd->advertising = (ADVERTISED_100baseT_Half |
+                                    ADVERTISED_100baseT_Full |
+                                    ADVERTISED_1000baseT_Half |
+                                    ADVERTISED_1000baseT_Full);
+       }
+
+       switch (ahw->supported_type) {
+       case PORT_FIBRE:
+               ecmd->supported |= SUPPORTED_FIBRE;
+               ecmd->advertising |= ADVERTISED_FIBRE;
+               ecmd->port = PORT_FIBRE;
+               ecmd->transceiver = XCVR_EXTERNAL;
+               break;
+       case PORT_TP:
+               ecmd->supported |= SUPPORTED_TP;
+               ecmd->advertising |= ADVERTISED_TP;
+               ecmd->port = PORT_TP;
+               ecmd->transceiver = XCVR_INTERNAL;
+               break;
+       default:
+               ecmd->supported |= SUPPORTED_FIBRE;
+               ecmd->advertising |= ADVERTISED_FIBRE;
+               ecmd->port = PORT_OTHER;
+               ecmd->transceiver = XCVR_EXTERNAL;
+               break;
+       }
+       ecmd->phy_address = ahw->physical_port;
        return status;
 }
 
@@ -3046,7 +3116,8 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)
        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
                return -EIO;
 
-       ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
+       ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
+                                        max_sds_rings);
        if (ret)
                goto fail_diag_irq;
 
index 1f1d85e6f2afd1e4cb1581f03088333b034726a3..f5db67fc9f55a0dd319112462b0952af932f3ffe 100644 (file)
@@ -603,7 +603,7 @@ int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
 
 void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
 void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
-int qlcnic_83xx_get_settings(struct qlcnic_adapter *);
+int qlcnic_83xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
 int qlcnic_83xx_set_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
 void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *,
                                struct ethtool_pauseparam *);
@@ -620,7 +620,7 @@ int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
 int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
 int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
 u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *);
-u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *);
+u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *);
 void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
 void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
 #endif
index ab1d8d99cbd530d59727a4e131789f3eb210a9bb..c67d1eb35e8f7deab13803f74eb0e79dbce71c90 100644 (file)
@@ -435,10 +435,6 @@ static void qlcnic_83xx_idc_attach_driver(struct qlcnic_adapter *adapter)
        }
 done:
        netif_device_attach(netdev);
-       if (netif_running(netdev)) {
-               netif_carrier_on(netdev);
-               netif_wake_queue(netdev);
-       }
 }
 
 static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter,
@@ -642,15 +638,21 @@ static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
 
 static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
 {
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+
        qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1);
-       clear_bit(__QLCNIC_RESETTING, &adapter->state);
        set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
        qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
        set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
-       adapter->ahw->idc.quiesce_req = 0;
-       adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
-       adapter->ahw->idc.err_code = 0;
-       adapter->ahw->idc.collect_dump = 0;
+
+       ahw->idc.quiesce_req = 0;
+       ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
+       ahw->idc.err_code = 0;
+       ahw->idc.collect_dump = 0;
+       ahw->reset_context = 0;
+       adapter->tx_timeo_cnt = 0;
+
+       clear_bit(__QLCNIC_RESETTING, &adapter->state);
 }
 
 /**
@@ -851,6 +853,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
        /* Check for soft reset request */
        if (ahw->reset_context &&
            !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
+               adapter->ahw->reset_context = 0;
                qlcnic_83xx_idc_tx_soft_reset(adapter);
                return ret;
        }
@@ -914,6 +917,7 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter)
 static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter)
 {
        dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__);
+       clear_bit(__QLCNIC_RESETTING, &adapter->state);
        adapter->ahw->idc.err_code = -EIO;
 
        return 0;
index 08efb463500723a268923617157b4864a4345878..f67652de5a63ca4736794d01c794ce44f1a6e382 100644 (file)
@@ -131,12 +131,13 @@ static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
        "ctx_lro_pkt_cnt",
        "ctx_ip_csum_error",
        "ctx_rx_pkts_wo_ctx",
-       "ctx_rx_pkts_dropped_wo_sts",
+       "ctx_rx_pkts_drop_wo_sds_on_card",
+       "ctx_rx_pkts_drop_wo_sds_on_host",
        "ctx_rx_osized_pkts",
        "ctx_rx_pkts_dropped_wo_rds",
        "ctx_rx_unexpected_mcast_pkts",
        "ctx_invalid_mac_address",
-       "ctx_rx_rds_ring_prim_attemoted",
+       "ctx_rx_rds_ring_prim_attempted",
        "ctx_rx_rds_ring_prim_success",
        "ctx_num_lro_flows_added",
        "ctx_num_lro_flows_removed",
@@ -251,6 +252,18 @@ static int
 qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+       if (qlcnic_82xx_check(adapter))
+               return qlcnic_82xx_get_settings(adapter, ecmd);
+       else if (qlcnic_83xx_check(adapter))
+               return qlcnic_83xx_get_settings(adapter, ecmd);
+
+       return -EIO;
+}
+
+int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter,
+                            struct ethtool_cmd *ecmd)
+{
        struct qlcnic_hardware_context *ahw = adapter->ahw;
        u32 speed, reg;
        int check_sfp_module = 0;
@@ -276,10 +289,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
        } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
                u32 val = 0;
-               if (qlcnic_83xx_check(adapter))
-                       qlcnic_83xx_get_settings(adapter);
-               else
-                       val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
+               val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
 
                if (val == QLCNIC_PORT_MODE_802_3_AP) {
                        ecmd->supported = SUPPORTED_1000baseT_Full;
@@ -289,16 +299,13 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                        ecmd->advertising = ADVERTISED_10000baseT_Full;
                }
 
-               if (netif_running(dev) && adapter->ahw->has_link_events) {
-                       if (qlcnic_82xx_check(adapter)) {
-                               reg = QLCRD32(adapter,
-                                             P3P_LINK_SPEED_REG(pcifn));
-                               speed = P3P_LINK_SPEED_VAL(pcifn, reg);
-                               ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
-                       }
-                       ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed);
-                       ecmd->autoneg = adapter->ahw->link_autoneg;
-                       ecmd->duplex = adapter->ahw->link_duplex;
+               if (netif_running(adapter->netdev) && ahw->has_link_events) {
+                       reg = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
+                       speed = P3P_LINK_SPEED_VAL(pcifn, reg);
+                       ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
+                       ethtool_cmd_speed_set(ecmd, ahw->link_speed);
+                       ecmd->autoneg = ahw->link_autoneg;
+                       ecmd->duplex = ahw->link_duplex;
                        goto skip;
                }
 
@@ -340,8 +347,8 @@ skip:
        case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
                ecmd->advertising |= ADVERTISED_TP;
                ecmd->supported |= SUPPORTED_TP;
-               check_sfp_module = netif_running(dev) &&
-                                  adapter->ahw->has_link_events;
+               check_sfp_module = netif_running(adapter->netdev) &&
+                                  ahw->has_link_events;
        case QLCNIC_BRDTYPE_P3P_10G_XFP:
                ecmd->supported |= SUPPORTED_FIBRE;
                ecmd->advertising |= ADVERTISED_FIBRE;
@@ -355,8 +362,8 @@ skip:
                        ecmd->advertising |=
                                (ADVERTISED_FIBRE | ADVERTISED_TP);
                        ecmd->port = PORT_FIBRE;
-                       check_sfp_module = netif_running(dev) &&
-                                          adapter->ahw->has_link_events;
+                       check_sfp_module = netif_running(adapter->netdev) &&
+                                          ahw->has_link_events;
                } else {
                        ecmd->autoneg = AUTONEG_ENABLE;
                        ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
@@ -365,13 +372,6 @@ skip:
                        ecmd->port = PORT_TP;
                }
                break;
-       case QLCNIC_BRDTYPE_83XX_10G:
-               ecmd->autoneg = AUTONEG_DISABLE;
-               ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
-               ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP);
-               ecmd->port = PORT_FIBRE;
-               check_sfp_module = netif_running(dev) && ahw->has_link_events;
-               break;
        default:
                dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
                        adapter->ahw->board_type);
index 95b1b57328385dac93c0268fb6bae262ae20a793..b6818f4356b905de891ed09660a7be62b3262e56 100644 (file)
@@ -134,7 +134,7 @@ struct qlcnic_mailbox_metadata {
 
 #define QLCNIC_SET_OWNER        1
 #define QLCNIC_CLR_OWNER        0
-#define QLCNIC_MBX_TIMEOUT      10000
+#define QLCNIC_MBX_TIMEOUT      5000
 
 #define QLCNIC_MBX_RSP_OK      1
 #define QLCNIC_MBX_PORT_RSP_OK 0x1a
index 264d5a4f81538a23653c370a7d85df18617c09be..8fb836d4129f964de07bd964405754a5b0cb74fb 100644 (file)
@@ -37,24 +37,24 @@ MODULE_PARM_DESC(qlcnic_mac_learn,
                 "Mac Filter (0=learning is disabled, 1=Driver learning is enabled, 2=FDB learning is enabled)");
 
 int qlcnic_use_msi = 1;
-MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled");
+MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled)");
 module_param_named(use_msi, qlcnic_use_msi, int, 0444);
 
 int qlcnic_use_msi_x = 1;
-MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled");
+MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled)");
 module_param_named(use_msi_x, qlcnic_use_msi_x, int, 0444);
 
 int qlcnic_auto_fw_reset = 1;
-MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled");
+MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled)");
 module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644);
 
 int qlcnic_load_fw_file;
-MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file");
+MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file)");
 module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444);
 
 int qlcnic_config_npars;
 module_param(qlcnic_config_npars, int, 0444);
-MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled");
+MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled)");
 
 static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void qlcnic_remove(struct pci_dev *pdev);
@@ -308,6 +308,23 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
        return 0;
 }
 
+static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter)
+{
+       struct qlcnic_mac_list_s *cur;
+       struct list_head *head;
+
+       list_for_each(head, &adapter->mac_list) {
+               cur = list_entry(head, struct qlcnic_mac_list_s, list);
+               if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) {
+                       qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
+                                                 0, QLCNIC_MAC_DEL);
+                       list_del(&cur->list);
+                       kfree(cur);
+                       return;
+               }
+       }
+}
+
 static int qlcnic_set_mac(struct net_device *netdev, void *p)
 {
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -322,11 +339,15 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EINVAL;
 
+       if (!memcmp(adapter->mac_addr, addr->sa_data, ETH_ALEN))
+               return 0;
+
        if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
                netif_device_detach(netdev);
                qlcnic_napi_disable(adapter);
        }
 
+       qlcnic_delete_adapter_mac(adapter);
        memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
        qlcnic_set_multi(adapter->netdev);
@@ -2481,12 +2502,17 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
        if (test_bit(__QLCNIC_RESETTING, &adapter->state))
                return;
 
-       dev_err(&netdev->dev, "transmit timeout, resetting.\n");
-
-       if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS)
-               adapter->need_fw_reset = 1;
-       else
+       if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) {
+               netdev_info(netdev, "Tx timeout, reset the adapter.\n");
+               if (qlcnic_82xx_check(adapter))
+                       adapter->need_fw_reset = 1;
+               else if (qlcnic_83xx_check(adapter))
+                       qlcnic_83xx_idc_request_reset(adapter,
+                                                     QLCNIC_FORCE_FW_DUMP_KEY);
+       } else {
+               netdev_info(netdev, "Tx timeout, reset adapter context.\n");
                adapter->ahw->reset_context = 1;
+       }
 }
 
 static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
index 44d547d78b84927db40201cfa03d6aea49bf37cd..3869c3864deb469ef1e4d43d8cb8ed28c7af204a 100644 (file)
@@ -280,9 +280,9 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
 static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
                                    u32 *pay, u8 pci_func, u8 size)
 {
+       u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val, wait_time = 0;
        struct qlcnic_hardware_context *ahw = adapter->ahw;
        unsigned long flags;
-       u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val;
        u16 opcode;
        u8 mbx_err_code;
        int i, j;
@@ -330,15 +330,13 @@ static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
         * assume something is wrong.
         */
 poll:
-       rsp = qlcnic_83xx_mbx_poll(adapter);
+       rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
        if (rsp != QLCNIC_RCODE_TIMEOUT) {
                /* Get the FW response data */
                fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
                if (fw_data &  QLCNIC_MBX_ASYNC_EVENT) {
                        __qlcnic_83xx_process_aen(adapter);
-                       mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
-                       if (mbx_val)
-                               goto poll;
+                       goto poll;
                }
                mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
                rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
index c81be2da119bdc4b9aef1d3f770f3d76d4074b56..1a66ccded235e202616be03ae9bdb08c6bad9155 100644 (file)
@@ -1133,9 +1133,6 @@ static int qlcnic_sriov_validate_linkevent(struct qlcnic_vf_info *vf,
        if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
                return -EINVAL;
 
-       if (!(cmd->req.arg[1] & BIT_8))
-               return -EINVAL;
-
        return 0;
 }
 
index 87463bc701a653781371feb05599aad2b45d224a..50235d2015925b4d70737b59e8268b107ed5d5c4 100644 (file)
@@ -1106,6 +1106,7 @@ static int ql_get_next_chunk(struct ql_adapter *qdev, struct rx_ring *rx_ring,
                if (pci_dma_mapping_error(qdev->pdev, map)) {
                        __free_pages(rx_ring->pg_chunk.page,
                                        qdev->lbq_buf_order);
+                       rx_ring->pg_chunk.page = NULL;
                        netif_err(qdev, drv, qdev->ndev,
                                  "PCI mapping failed.\n");
                        return -ENOMEM;
@@ -2777,6 +2778,12 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
                        curr_idx = 0;
 
        }
+       if (rx_ring->pg_chunk.page) {
+               pci_unmap_page(qdev->pdev, rx_ring->pg_chunk.map,
+                       ql_lbq_block_size(qdev), PCI_DMA_FROMDEVICE);
+               put_page(rx_ring->pg_chunk.page);
+               rx_ring->pg_chunk.page = NULL;
+       }
 }
 
 static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring)
index 33dc6f2418f2968e23a383e2c0395ed41d832132..42e9dd05c936df55e2bc62754259e1ff6e81785d 100644 (file)
@@ -2745,11 +2745,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        if (mdp->cd->tsu) {
                struct resource *rtsu;
                rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-               if (!rtsu) {
-                       dev_err(&pdev->dev, "Not found TSU resource\n");
-                       ret = -ENODEV;
-                       goto out_release;
-               }
                mdp->tsu_addr = devm_ioremap_resource(&pdev->dev, rtsu);
                if (IS_ERR(mdp->tsu_addr)) {
                        ret = PTR_ERR(mdp->tsu_addr);
index f695a50bac47d99cdc141a3cf059dff340e54dc3..43c1f32233220e17a27936572fa27de9d31219ee 100644 (file)
@@ -1,6 +1,6 @@
 config STMMAC_ETH
        tristate "STMicroelectronics 10/100/1000 Ethernet driver"
-       depends on HAS_IOMEM
+       depends on HAS_IOMEM && HAS_DMA
        select NET_CORE
        select MII
        select PHYLIB
index d5a141c7c4e786b06746c73668407c110e74611e..1c502bb0c916ff549ab10400af5d24b7f61c4866 100644 (file)
@@ -229,7 +229,8 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
        }
 
        if (port->passthru)
-               vlan = list_first_entry(&port->vlans, struct macvlan_dev, list);
+               vlan = list_first_or_null_rcu(&port->vlans,
+                                             struct macvlan_dev, list);
        else
                vlan = macvlan_hash_lookup(port, eth->h_dest);
        if (vlan == NULL)
@@ -814,7 +815,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
        if (err < 0)
                goto upper_dev_unlink;
 
-       list_add_tail(&vlan->list, &port->vlans);
+       list_add_tail_rcu(&vlan->list, &port->vlans);
        netif_stacked_transfer_operstate(lowerdev, dev);
 
        return 0;
@@ -842,7 +843,7 @@ void macvlan_dellink(struct net_device *dev, struct list_head *head)
 {
        struct macvlan_dev *vlan = netdev_priv(dev);
 
-       list_del(&vlan->list);
+       list_del_rcu(&vlan->list);
        unregister_netdevice_queue(dev, head);
        netdev_upper_dev_unlink(vlan->lowerdev, dev);
 }
index ed947dd76fbd1ded245f3e649dcf920cbe86320f..f3cdf64997d60dd6937ba8885dab3c72525b1f2b 100644 (file)
@@ -375,6 +375,8 @@ static void ntb_netdev_remove(struct pci_dev *pdev)
        if (dev == NULL)
                return;
 
+       list_del(&dev->list);
+
        ndev = dev->ndev;
 
        unregister_netdev(ndev);
index f95cb032394bb03f05b7ae2605b7b9585e8e3c67..06ee82f557d45ba31b4847c187f57771ae2c73d2 100644 (file)
@@ -1477,7 +1477,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
        /* usbnet already took usb runtime pm, so have to enable the feature
         * for usb interface, otherwise usb_autopm_get_interface may return
-        * failure if USB_SUSPEND(RUNTIME_PM) is enabled.
+        * failure if RUNTIME_PM is enabled.
         */
        if (!driver->supports_autosuspend) {
                driver->supports_autosuspend = 1;
index 3c23fdc27bf0798085361a64d6262cdaed34c66b..655bb25eed2b6e208baf2acb8b15a5f55d76f4a9 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/slab.h>
 #include <linux/cpu.h>
 
-static int napi_weight = 128;
+static int napi_weight = NAPI_POLL_WEIGHT;
 module_param(napi_weight, int, 0444);
 
 static bool csum = true, gso = true;
index 9b20d9ee2719d0ddc78c799ecb24307882f1b503..7f702fe3ecc2c68f5a3300cfa7182d00ad84fe38 100644 (file)
@@ -2369,6 +2369,9 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
        int i;
        bool needreset = false;
 
+       if (!test_bit(ATH_STAT_STARTED, ah->status))
+               return;
+
        mutex_lock(&ah->lock);
 
        for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) {
@@ -2676,6 +2679,7 @@ done:
        mmiowb();
        mutex_unlock(&ah->lock);
 
+       set_bit(ATH_STAT_STARTED, ah->status);
        ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work,
                        msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
 
@@ -2737,6 +2741,7 @@ void ath5k_stop(struct ieee80211_hw *hw)
 
        ath5k_stop_tasklets(ah);
 
+       clear_bit(ATH_STAT_STARTED, ah->status);
        cancel_delayed_work_sync(&ah->tx_complete_work);
 
        if (!ath5k_modparam_no_hw_rfkill_switch)
index 17507dc8a1e717ea637ba9dee75b633eddde37b7..f3dc124c60c775577a322f6e0a6b7adc471fa88d 100644 (file)
@@ -17,7 +17,7 @@ config ATH9K_BTCOEX_SUPPORT
 
 config ATH9K
        tristate "Atheros 802.11n wireless cards support"
-       depends on MAC80211
+       depends on MAC80211 && HAS_DMA
        select ATH9K_HW
        select MAC80211_LEDS
        select LEDS_CLASS
index 0c2ac0c6dc892f31a84be30f7332a6eb4267a9f2..e85a8b076c223e5bd3fbc4549789519c296b7761 100644 (file)
@@ -233,9 +233,9 @@ static const u32 ar9565_1p0_baseband_core[][2] = {
        {0x00009d10, 0x01834061},
        {0x00009d14, 0x00c00400},
        {0x00009d18, 0x00000000},
-       {0x00009e08, 0x0078230c},
-       {0x00009e24, 0x990bb515},
-       {0x00009e28, 0x126f0000},
+       {0x00009e08, 0x0038230c},
+       {0x00009e24, 0x9907b515},
+       {0x00009e28, 0x126f0600},
        {0x00009e30, 0x06336f77},
        {0x00009e34, 0x6af6532f},
        {0x00009e38, 0x0cc80c00},
@@ -337,7 +337,7 @@ static const u32 ar9565_1p0_baseband_core[][2] = {
 
 static const u32 ar9565_1p0_baseband_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a800d},
+       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8009},
        {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae},
        {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
        {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x09143c81},
@@ -345,9 +345,9 @@ static const u32 ar9565_1p0_baseband_postamble[][5] = {
        {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
        {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
        {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
-       {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
-       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8},
-       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
+       {0x00009e04, 0x00802020, 0x00802020, 0x00142020, 0x00142020},
+       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
        {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
        {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
@@ -450,6 +450,8 @@ static const u32 ar9565_1p0_soc_postamble[][5] = {
 
 static const u32 ar9565_1p0_Common_rx_gain_table[][2] = {
        /* Addr      allmodes  */
+       {0x00004050, 0x00300300},
+       {0x0000406c, 0x00100000},
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
        {0x0000a008, 0x00050004},
@@ -498,27 +500,27 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = {
        {0x0000a0b4, 0x00000000},
        {0x0000a0b8, 0x00000000},
        {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
+       {0x0000a0c0, 0x00bf00a0},
+       {0x0000a0c4, 0x11a011a1},
+       {0x0000a0c8, 0x11be11bf},
+       {0x0000a0cc, 0x11bc11bd},
+       {0x0000a0d0, 0x22632264},
+       {0x0000a0d4, 0x22612262},
+       {0x0000a0d8, 0x227f2260},
+       {0x0000a0dc, 0x4322227e},
+       {0x0000a0e0, 0x43204321},
+       {0x0000a0e4, 0x433e433f},
+       {0x0000a0e8, 0x4462433d},
+       {0x0000a0ec, 0x44604461},
+       {0x0000a0f0, 0x447e447f},
+       {0x0000a0f4, 0x5582447d},
+       {0x0000a0f8, 0x55805581},
+       {0x0000a0fc, 0x559e559f},
+       {0x0000a100, 0x66816682},
+       {0x0000a104, 0x669f6680},
+       {0x0000a108, 0x669d669e},
+       {0x0000a10c, 0x77627763},
+       {0x0000a110, 0x77607761},
        {0x0000a114, 0x00000000},
        {0x0000a118, 0x00000000},
        {0x0000a11c, 0x00000000},
@@ -530,27 +532,27 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = {
        {0x0000a134, 0x00000000},
        {0x0000a138, 0x00000000},
        {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
+       {0x0000a140, 0x00bf00a0},
+       {0x0000a144, 0x11a011a1},
+       {0x0000a148, 0x11be11bf},
+       {0x0000a14c, 0x11bc11bd},
+       {0x0000a150, 0x22632264},
+       {0x0000a154, 0x22612262},
+       {0x0000a158, 0x227f2260},
+       {0x0000a15c, 0x4322227e},
+       {0x0000a160, 0x43204321},
+       {0x0000a164, 0x433e433f},
+       {0x0000a168, 0x4462433d},
+       {0x0000a16c, 0x44604461},
+       {0x0000a170, 0x447e447f},
+       {0x0000a174, 0x5582447d},
+       {0x0000a178, 0x55805581},
+       {0x0000a17c, 0x559e559f},
+       {0x0000a180, 0x66816682},
+       {0x0000a184, 0x669f6680},
+       {0x0000a188, 0x669d669e},
+       {0x0000a18c, 0x77e677e7},
+       {0x0000a190, 0x77e477e5},
        {0x0000a194, 0x00000000},
        {0x0000a198, 0x00000000},
        {0x0000a19c, 0x00000000},
@@ -770,7 +772,7 @@ static const u32 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = {
 
 static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = {
        /* Addr      allmodes  */
-       {0x00018c00, 0x18213ede},
+       {0x00018c00, 0x18212ede},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0003780c},
 };
@@ -889,8 +891,8 @@ static const u32 ar9565_1p0_common_wo_xlna_rx_gain_table[][2] = {
        {0x0000a180, 0x66816682},
        {0x0000a184, 0x669f6680},
        {0x0000a188, 0x669d669e},
-       {0x0000a18c, 0x77627763},
-       {0x0000a190, 0x77607761},
+       {0x0000a18c, 0x77e677e7},
+       {0x0000a190, 0x77e477e5},
        {0x0000a194, 0x00000000},
        {0x0000a198, 0x00000000},
        {0x0000a19c, 0x00000000},
@@ -1114,7 +1116,7 @@ static const u32 ar9565_1p0_modes_high_ob_db_tx_gain_table[][5] = {
        {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84},
        {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000},
        {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000},
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050df, 0x000050df},
        {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
        {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
        {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004},
@@ -1140,13 +1142,13 @@ static const u32 ar9565_1p0_modes_high_ob_db_tx_gain_table[][5] = {
        {0x0000a558, 0x69027f56, 0x69027f56, 0x53001ce5, 0x53001ce5},
        {0x0000a55c, 0x6d029f56, 0x6d029f56, 0x57001ce9, 0x57001ce9},
        {0x0000a560, 0x73049f56, 0x73049f56, 0x5b001ceb, 0x5b001ceb},
-       {0x0000a564, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec},
-       {0x0000a568, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec},
-       {0x0000a56c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec},
-       {0x0000a570, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec},
-       {0x0000a574, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec},
-       {0x0000a578, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec},
-       {0x0000a57c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec},
+       {0x0000a564, 0x7804ff56, 0x7804ff56, 0x60001cf0, 0x60001cf0},
+       {0x0000a568, 0x7804ff56, 0x7804ff56, 0x61001cf1, 0x61001cf1},
+       {0x0000a56c, 0x7804ff56, 0x7804ff56, 0x62001cf2, 0x62001cf2},
+       {0x0000a570, 0x7804ff56, 0x7804ff56, 0x63001cf3, 0x63001cf3},
+       {0x0000a574, 0x7804ff56, 0x7804ff56, 0x64001cf4, 0x64001cf4},
+       {0x0000a578, 0x7804ff56, 0x7804ff56, 0x66001ff6, 0x66001ff6},
+       {0x0000a57c, 0x7804ff56, 0x7804ff56, 0x66001ff6, 0x66001ff6},
        {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -1174,7 +1176,7 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = {
        {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84},
        {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000},
        {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000},
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050df, 0x000050df},
        {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
        {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
        {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
@@ -1200,13 +1202,13 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = {
        {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
        {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
        {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
-       {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
-       {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
+       {0x0000a564, 0x7504ff56, 0x7504ff56, 0x59001cf0, 0x59001cf0},
+       {0x0000a568, 0x7504ff56, 0x7504ff56, 0x5a001cf1, 0x5a001cf1},
+       {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x5b001cf2, 0x5b001cf2},
+       {0x0000a570, 0x7504ff56, 0x7504ff56, 0x5c001cf3, 0x5c001cf3},
+       {0x0000a574, 0x7504ff56, 0x7504ff56, 0x5d001cf4, 0x5d001cf4},
+       {0x0000a578, 0x7504ff56, 0x7504ff56, 0x5f001ff6, 0x5f001ff6},
+       {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x5f001ff6, 0x5f001ff6},
        {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
index 6963862a187275601b11a8270e3ecd7e6d2b995a..a18414b5948b513ec1ccddf795fbfd8aeca17fb2 100644 (file)
@@ -227,13 +227,13 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
                if (!test_bit(SC_OP_BEACONS, &sc->sc_flags))
                        goto work;
 
-               ath9k_set_beacon(sc);
-
                if (ah->opmode == NL80211_IFTYPE_STATION &&
                    test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
                        spin_lock_irqsave(&sc->sc_pm_lock, flags);
                        sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
                        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+               } else {
+                       ath9k_set_beacon(sc);
                }
        work:
                ath_restart_work(sc);
@@ -1332,6 +1332,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_node *an = (struct ath_node *) sta->drv_priv;
        struct ieee80211_key_conf ps_key = { };
+       int key;
 
        ath_node_attach(sc, sta, vif);
 
@@ -1339,7 +1340,9 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
            vif->type != NL80211_IFTYPE_AP_VLAN)
                return 0;
 
-       an->ps_key = ath_key_config(common, vif, sta, &ps_key);
+       key = ath_key_config(common, vif, sta, &ps_key);
+       if (key > 0)
+               an->ps_key = key;
 
        return 0;
 }
@@ -1356,6 +1359,7 @@ static void ath9k_del_ps_key(struct ath_softc *sc,
            return;
 
        ath_key_delete(common, &ps_key);
+       an->ps_key = 0;
 }
 
 static int ath9k_sta_remove(struct ieee80211_hw *hw,
index 523355b876597f5d0db6e003f9230367c6777a86..f7c70b3a6ea978883f67f1abe0983cf51a476ada 100644 (file)
@@ -1728,6 +1728,25 @@ drop_recycle_buffer:
        sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
 }
 
+void b43_dma_handle_rx_overflow(struct b43_dmaring *ring)
+{
+       int current_slot, previous_slot;
+
+       B43_WARN_ON(ring->tx);
+
+       /* Device has filled all buffers, drop all packets and let TCP
+        * decrease speed.
+        * Decrement RX index by one will let the device to see all slots
+        * as free again
+        */
+       /*
+       *TODO: How to increase rx_drop in mac80211?
+       */
+       current_slot = ring->ops->get_current_rxslot(ring);
+       previous_slot = prev_slot(ring, current_slot);
+       ring->ops->set_current_rxslot(ring, previous_slot);
+}
+
 void b43_dma_rx(struct b43_dmaring *ring)
 {
        const struct b43_dma_ops *ops = ring->ops;
index 9fdd1983079cb4ba0d9e6d09ee10722662d70b92..df8c8cdcbdb53d614766f7f5a7aa8239bd269271 100644 (file)
@@ -9,7 +9,7 @@
 /* DMA-Interrupt reasons. */
 #define B43_DMAIRQ_FATALMASK   ((1 << 10) | (1 << 11) | (1 << 12) \
                                         | (1 << 14) | (1 << 15))
-#define B43_DMAIRQ_NONFATALMASK        (1 << 13)
+#define B43_DMAIRQ_RDESC_UFLOW         (1 << 13)
 #define B43_DMAIRQ_RX_DONE             (1 << 16)
 
 /*** 32-bit DMA Engine. ***/
@@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev,
 void b43_dma_handle_txstatus(struct b43_wldev *dev,
                             const struct b43_txstatus *status);
 
+void b43_dma_handle_rx_overflow(struct b43_dmaring *ring);
+
 void b43_dma_rx(struct b43_dmaring *ring);
 
 void b43_dma_direct_fifo_rx(struct b43_wldev *dev,
index d377f77d30b536de0ddaeb1ed9cef382619ccfa6..6dd07e2ec595e851a13190fc43bc980c09a08617 100644 (file)
@@ -1902,30 +1902,18 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
                }
        }
 
-       if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK |
-                                         B43_DMAIRQ_NONFATALMASK))) {
-               if (merged_dma_reason & B43_DMAIRQ_FATALMASK) {
-                       b43err(dev->wl, "Fatal DMA error: "
-                              "0x%08X, 0x%08X, 0x%08X, "
-                              "0x%08X, 0x%08X, 0x%08X\n",
-                              dma_reason[0], dma_reason[1],
-                              dma_reason[2], dma_reason[3],
-                              dma_reason[4], dma_reason[5]);
-                       b43err(dev->wl, "This device does not support DMA "
+       if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) {
+               b43err(dev->wl,
+                       "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+                       dma_reason[0], dma_reason[1],
+                       dma_reason[2], dma_reason[3],
+                       dma_reason[4], dma_reason[5]);
+               b43err(dev->wl, "This device does not support DMA "
                               "on your system. It will now be switched to PIO.\n");
-                       /* Fall back to PIO transfers if we get fatal DMA errors! */
-                       dev->use_pio = true;
-                       b43_controller_restart(dev, "DMA error");
-                       return;
-               }
-               if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
-                       b43err(dev->wl, "DMA error: "
-                              "0x%08X, 0x%08X, 0x%08X, "
-                              "0x%08X, 0x%08X, 0x%08X\n",
-                              dma_reason[0], dma_reason[1],
-                              dma_reason[2], dma_reason[3],
-                              dma_reason[4], dma_reason[5]);
-               }
+               /* Fall back to PIO transfers if we get fatal DMA errors! */
+               dev->use_pio = true;
+               b43_controller_restart(dev, "DMA error");
+               return;
        }
 
        if (unlikely(reason & B43_IRQ_UCODE_DEBUG))
@@ -1944,6 +1932,11 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
                handle_irq_noise(dev);
 
        /* Check the DMA reason registers for received data. */
+       if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) {
+               if (B43_DEBUG)
+                       b43warn(dev->wl, "RX descriptor underrun\n");
+               b43_dma_handle_rx_overflow(dev->dma.rx_ring);
+       }
        if (dma_reason[0] & B43_DMAIRQ_RX_DONE) {
                if (b43_using_pio_transfers(dev))
                        b43_pio_rx(dev->pio.rx_queue);
@@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
                return IRQ_NONE;
 
        dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
-           & 0x0001DC00;
+           & 0x0001FC00;
        dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON)
            & 0x0000DC00;
        dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON)
@@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev)
                b43_write32(dev, 0x018C, 0x02000000);
        }
        b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000);
-       b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
+       b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00);
        b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
        b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
        b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
index b8f82e688c722457812840ed6cafb921da484980..9a95045c97b6b4fe6041f457a1999ecfb7926d12 100644 (file)
@@ -5741,8 +5741,7 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
        hw->flags =
            IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION |
            IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT |
-           IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS |
-           IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+           IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
        if (il->cfg->sku & IL_SKU_N)
                hw->flags |=
                    IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
index d3c8ece980d8aa2394439f84348af73ce7ab94ff..e42b266a023a2c0df18e7cd85fd7dbbb3cf07d45 100644 (file)
@@ -2234,9 +2234,6 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
        if (wdev->netdev->reg_state == NETREG_REGISTERED)
                unregister_netdevice(wdev->netdev);
 
-       if (wdev->netdev->reg_state == NETREG_UNREGISTERED)
-               free_netdev(wdev->netdev);
-
        /* Clear the priv in adapter */
        priv->netdev = NULL;
 
index 74db0d24a5790a9ee29b37408092a3cda859c97a..26755d9acb556d20e735aa334032e66fb4c0be52 100644 (file)
@@ -1191,6 +1191,7 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
        adapter->if_ops.wakeup(adapter);
        adapter->hs_activated = false;
        adapter->is_hs_configured = false;
+       adapter->is_suspended = false;
        mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
                                                    MWIFIEX_BSS_ROLE_ANY),
                                   false);
index 121443a0f2a13ed91522241cfe6fc11abad613af..2eb88ea9acf7f66f51e8e7544f52642586fe627e 100644 (file)
@@ -655,6 +655,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
                                                struct net_device *dev)
 {
        dev->netdev_ops = &mwifiex_netdev_ops;
+       dev->destructor = free_netdev;
        /* Initialize private structure */
        priv->current_key_index = 0;
        priv->media_connected = false;
index 311d0b26b81c0508177e3dc1297a4da967644ae1..1a8a19dbd635df7b6b012533605cdde724c0d000 100644 (file)
@@ -96,7 +96,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
        } else {
                /* Multicast */
                priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
-               if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) {
+               if (mcast_list->mode == MWIFIEX_ALL_MULTI_MODE) {
                        dev_dbg(priv->adapter->dev,
                                "info: Enabling All Multicast!\n");
                        priv->curr_pkt_filter |=
@@ -108,20 +108,11 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
                                dev_dbg(priv->adapter->dev,
                                        "info: Set multicast list=%d\n",
                                       mcast_list->num_multicast_addr);
-                               /* Set multicast addresses to firmware */
-                               if (old_pkt_filter == priv->curr_pkt_filter) {
-                                       /* Send request to firmware */
-                                       ret = mwifiex_send_cmd_async(priv,
-                                               HostCmd_CMD_MAC_MULTICAST_ADR,
-                                               HostCmd_ACT_GEN_SET, 0,
-                                               mcast_list);
-                               } else {
-                                       /* Send request to firmware */
-                                       ret = mwifiex_send_cmd_async(priv,
-                                               HostCmd_CMD_MAC_MULTICAST_ADR,
-                                               HostCmd_ACT_GEN_SET, 0,
-                                               mcast_list);
-                               }
+                               /* Send multicast addresses to firmware */
+                               ret = mwifiex_send_cmd_async(priv,
+                                       HostCmd_CMD_MAC_MULTICAST_ADR,
+                                       HostCmd_ACT_GEN_SET, 0,
+                                       mcast_list);
                        }
                }
        }
index f802e7c923561d2bd331402b192c99aac6da9ff1..2dacd19e1b8a15c5a7c8d66db2eb7cb2793a58ed 100644 (file)
@@ -345,7 +345,7 @@ int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val)
  */
 void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw)
 {
-       if (mw > NTB_NUM_MW)
+       if (mw >= NTB_NUM_MW)
                return NULL;
 
        return ndev->mw[mw].vbase;
@@ -362,7 +362,7 @@ void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw)
  */
 resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw)
 {
-       if (mw > NTB_NUM_MW)
+       if (mw >= NTB_NUM_MW)
                return 0;
 
        return ndev->mw[mw].bar_sz;
@@ -380,7 +380,7 @@ resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw)
  */
 void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr)
 {
-       if (mw > NTB_NUM_MW)
+       if (mw >= NTB_NUM_MW)
                return;
 
        dev_dbg(&ndev->pdev->dev, "Writing addr %Lx to BAR %d\n", addr,
@@ -1027,8 +1027,8 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                ndev->mw[i].vbase =
                    ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)),
                               ndev->mw[i].bar_sz);
-               dev_info(&pdev->dev, "MW %d size %d\n", i,
-                        (u32) pci_resource_len(pdev, MW_TO_BAR(i)));
+               dev_info(&pdev->dev, "MW %d size %llu\n", i,
+                        pci_resource_len(pdev, MW_TO_BAR(i)));
                if (!ndev->mw[i].vbase) {
                        dev_warn(&pdev->dev, "Cannot remap BAR %d\n",
                                 MW_TO_BAR(i));
index e0bdfd7f9930aab4b42984b468ff87fac2868f44..f8d7081ee3014322e90c767fd766456f5410d311 100644 (file)
@@ -58,7 +58,7 @@
 #include <linux/ntb.h>
 #include "ntb_hw.h"
 
-#define NTB_TRANSPORT_VERSION  2
+#define NTB_TRANSPORT_VERSION  3
 
 static unsigned int transport_mtu = 0x401E;
 module_param(transport_mtu, uint, 0644);
@@ -173,10 +173,13 @@ struct ntb_payload_header {
 
 enum {
        VERSION = 0,
-       MW0_SZ,
-       MW1_SZ,
-       NUM_QPS,
        QP_LINKS,
+       NUM_QPS,
+       NUM_MWS,
+       MW0_SZ_HIGH,
+       MW0_SZ_LOW,
+       MW1_SZ_HIGH,
+       MW1_SZ_LOW,
        MAX_SPAD,
 };
 
@@ -297,7 +300,7 @@ int ntb_register_client_dev(char *device_name)
 {
        struct ntb_transport_client_dev *client_dev;
        struct ntb_transport *nt;
-       int rc;
+       int rc, i = 0;
 
        if (list_empty(&ntb_transport_list))
                return -ENODEV;
@@ -315,7 +318,7 @@ int ntb_register_client_dev(char *device_name)
                dev = &client_dev->dev;
 
                /* setup and register client devices */
-               dev_set_name(dev, "%s", device_name);
+               dev_set_name(dev, "%s%d", device_name, i);
                dev->bus = &ntb_bus_type;
                dev->release = ntb_client_release;
                dev->parent = &ntb_query_pdev(nt->ndev)->dev;
@@ -327,6 +330,7 @@ int ntb_register_client_dev(char *device_name)
                }
 
                list_add_tail(&client_dev->entry, &nt->client_devs);
+               i++;
        }
 
        return 0;
@@ -486,12 +490,13 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt,
                             (qp_num / NTB_NUM_MW * rx_size);
        rx_size -= sizeof(struct ntb_rx_info);
 
-       qp->rx_buff = qp->remote_rx_info + sizeof(struct ntb_rx_info);
-       qp->rx_max_frame = min(transport_mtu, rx_size);
+       qp->rx_buff = qp->remote_rx_info + 1;
+       /* Due to housekeeping, there must be atleast 2 buffs */
+       qp->rx_max_frame = min(transport_mtu, rx_size / 2);
        qp->rx_max_entry = rx_size / qp->rx_max_frame;
        qp->rx_index = 0;
 
-       qp->remote_rx_info->entry = qp->rx_max_entry;
+       qp->remote_rx_info->entry = qp->rx_max_entry - 1;
 
        /* setup the hdr offsets with 0's */
        for (i = 0; i < qp->rx_max_entry; i++) {
@@ -502,6 +507,19 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt,
 
        qp->rx_pkts = 0;
        qp->tx_pkts = 0;
+       qp->tx_index = 0;
+}
+
+static void ntb_free_mw(struct ntb_transport *nt, int num_mw)
+{
+       struct ntb_transport_mw *mw = &nt->mw[num_mw];
+       struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
+
+       if (!mw->virt_addr)
+               return;
+
+       dma_free_coherent(&pdev->dev, mw->size, mw->virt_addr, mw->dma_addr);
+       mw->virt_addr = NULL;
 }
 
 static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
@@ -509,12 +527,20 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
        struct ntb_transport_mw *mw = &nt->mw[num_mw];
        struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
 
+       /* No need to re-setup */
+       if (mw->size == ALIGN(size, 4096))
+               return 0;
+
+       if (mw->size != 0)
+               ntb_free_mw(nt, num_mw);
+
        /* Alloc memory for receiving data.  Must be 4k aligned */
        mw->size = ALIGN(size, 4096);
 
        mw->virt_addr = dma_alloc_coherent(&pdev->dev, mw->size, &mw->dma_addr,
                                           GFP_KERNEL);
        if (!mw->virt_addr) {
+               mw->size = 0;
                dev_err(&pdev->dev, "Unable to allocate MW buffer of size %d\n",
                       (int) mw->size);
                return -ENOMEM;
@@ -604,25 +630,31 @@ static void ntb_transport_link_work(struct work_struct *work)
        u32 val;
        int rc, i;
 
-       /* send the local info */
-       rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION);
-       if (rc) {
-               dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
-                       0, VERSION);
-               goto out;
-       }
+       /* send the local info, in the opposite order of the way we read it */
+       for (i = 0; i < NTB_NUM_MW; i++) {
+               rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2),
+                                          ntb_get_mw_size(ndev, i) >> 32);
+               if (rc) {
+                       dev_err(&pdev->dev, "Error writing %u to remote spad %d\n",
+                               (u32)(ntb_get_mw_size(ndev, i) >> 32),
+                               MW0_SZ_HIGH + (i * 2));
+                       goto out;
+               }
 
-       rc = ntb_write_remote_spad(ndev, MW0_SZ, ntb_get_mw_size(ndev, 0));
-       if (rc) {
-               dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
-                       (u32) ntb_get_mw_size(ndev, 0), MW0_SZ);
-               goto out;
+               rc = ntb_write_remote_spad(ndev, MW0_SZ_LOW + (i * 2),
+                                          (u32) ntb_get_mw_size(ndev, i));
+               if (rc) {
+                       dev_err(&pdev->dev, "Error writing %u to remote spad %d\n",
+                               (u32) ntb_get_mw_size(ndev, i),
+                               MW0_SZ_LOW + (i * 2));
+                       goto out;
+               }
        }
 
-       rc = ntb_write_remote_spad(ndev, MW1_SZ, ntb_get_mw_size(ndev, 1));
+       rc = ntb_write_remote_spad(ndev, NUM_MWS, NTB_NUM_MW);
        if (rc) {
                dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
-                       (u32) ntb_get_mw_size(ndev, 1), MW1_SZ);
+                       NTB_NUM_MW, NUM_MWS);
                goto out;
        }
 
@@ -633,16 +665,10 @@ static void ntb_transport_link_work(struct work_struct *work)
                goto out;
        }
 
-       rc = ntb_read_local_spad(nt->ndev, QP_LINKS, &val);
-       if (rc) {
-               dev_err(&pdev->dev, "Error reading spad %d\n", QP_LINKS);
-               goto out;
-       }
-
-       rc = ntb_write_remote_spad(ndev, QP_LINKS, val);
+       rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION);
        if (rc) {
                dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
-                       val, QP_LINKS);
+                       NTB_TRANSPORT_VERSION, VERSION);
                goto out;
        }
 
@@ -667,33 +693,43 @@ static void ntb_transport_link_work(struct work_struct *work)
                goto out;
        dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val);
 
-       rc = ntb_read_remote_spad(ndev, MW0_SZ, &val);
+       rc = ntb_read_remote_spad(ndev, NUM_MWS, &val);
        if (rc) {
-               dev_err(&pdev->dev, "Error reading remote spad %d\n", MW0_SZ);
+               dev_err(&pdev->dev, "Error reading remote spad %d\n", NUM_MWS);
                goto out;
        }
 
-       if (!val)
+       if (val != NTB_NUM_MW)
                goto out;
-       dev_dbg(&pdev->dev, "Remote MW0 size = %d\n", val);
+       dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val);
 
-       rc = ntb_set_mw(nt, 0, val);
-       if (rc)
-               goto out;
+       for (i = 0; i < NTB_NUM_MW; i++) {
+               u64 val64;
 
-       rc = ntb_read_remote_spad(ndev, MW1_SZ, &val);
-       if (rc) {
-               dev_err(&pdev->dev, "Error reading remote spad %d\n", MW1_SZ);
-               goto out;
-       }
+               rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val);
+               if (rc) {
+                       dev_err(&pdev->dev, "Error reading remote spad %d\n",
+                               MW0_SZ_HIGH + (i * 2));
+                       goto out1;
+               }
 
-       if (!val)
-               goto out;
-       dev_dbg(&pdev->dev, "Remote MW1 size = %d\n", val);
+               val64 = (u64) val << 32;
 
-       rc = ntb_set_mw(nt, 1, val);
-       if (rc)
-               goto out;
+               rc = ntb_read_remote_spad(ndev, MW0_SZ_LOW + (i * 2), &val);
+               if (rc) {
+                       dev_err(&pdev->dev, "Error reading remote spad %d\n",
+                               MW0_SZ_LOW + (i * 2));
+                       goto out1;
+               }
+
+               val64 |= val;
+
+               dev_dbg(&pdev->dev, "Remote MW%d size = %llu\n", i, val64);
+
+               rc = ntb_set_mw(nt, i, val64);
+               if (rc)
+                       goto out1;
+       }
 
        nt->transport_link = NTB_LINK_UP;
 
@@ -708,6 +744,9 @@ static void ntb_transport_link_work(struct work_struct *work)
 
        return;
 
+out1:
+       for (i = 0; i < NTB_NUM_MW; i++)
+               ntb_free_mw(nt, i);
 out:
        if (ntb_hw_link_status(ndev))
                schedule_delayed_work(&nt->link_work,
@@ -780,10 +819,10 @@ static void ntb_transport_init_queue(struct ntb_transport *nt,
                      (qp_num / NTB_NUM_MW * tx_size);
        tx_size -= sizeof(struct ntb_rx_info);
 
-       qp->tx_mw = qp->rx_info + sizeof(struct ntb_rx_info);
-       qp->tx_max_frame = min(transport_mtu, tx_size);
+       qp->tx_mw = qp->rx_info + 1;
+       /* Due to housekeeping, there must be atleast 2 buffs */
+       qp->tx_max_frame = min(transport_mtu, tx_size / 2);
        qp->tx_max_entry = tx_size / qp->tx_max_frame;
-       qp->tx_index = 0;
 
        if (nt->debugfs_dir) {
                char debugfs_name[4];
@@ -897,10 +936,7 @@ void ntb_transport_free(void *transport)
        pdev = ntb_query_pdev(nt->ndev);
 
        for (i = 0; i < NTB_NUM_MW; i++)
-               if (nt->mw[i].virt_addr)
-                       dma_free_coherent(&pdev->dev, nt->mw[i].size,
-                                         nt->mw[i].virt_addr,
-                                         nt->mw[i].dma_addr);
+               ntb_free_mw(nt, i);
 
        kfree(nt->qps);
        ntb_unregister_transport(nt->ndev);
@@ -999,11 +1035,16 @@ out:
 static void ntb_transport_rx(unsigned long data)
 {
        struct ntb_transport_qp *qp = (struct ntb_transport_qp *)data;
-       int rc;
+       int rc, i;
 
-       do {
+       /* Limit the number of packets processed in a single interrupt to
+        * provide fairness to others
+        */
+       for (i = 0; i < qp->rx_max_entry; i++) {
                rc = ntb_process_rxc(qp);
-       } while (!rc);
+               if (rc)
+                       break;
+       }
 }
 
 static void ntb_transport_rxc_db(void *data, int db_num)
@@ -1210,12 +1251,14 @@ EXPORT_SYMBOL_GPL(ntb_transport_create_queue);
  */
 void ntb_transport_free_queue(struct ntb_transport_qp *qp)
 {
-       struct pci_dev *pdev = ntb_query_pdev(qp->ndev);
+       struct pci_dev *pdev;
        struct ntb_queue_entry *entry;
 
        if (!qp)
                return;
 
+       pdev = ntb_query_pdev(qp->ndev);
+
        cancel_delayed_work_sync(&qp->link_work);
 
        ntb_unregister_db_callback(qp->ndev, qp->qp_num);
@@ -1371,12 +1414,13 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_up);
  */
 void ntb_transport_link_down(struct ntb_transport_qp *qp)
 {
-       struct pci_dev *pdev = ntb_query_pdev(qp->ndev);
+       struct pci_dev *pdev;
        int rc, val;
 
        if (!qp)
                return;
 
+       pdev = ntb_query_pdev(qp->ndev);
        qp->client_ready = NTB_LINK_DOWN;
 
        rc = ntb_read_local_spad(qp->ndev, QP_LINKS, &val);
@@ -1408,6 +1452,9 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_down);
  */
 bool ntb_transport_link_query(struct ntb_transport_qp *qp)
 {
+       if (!qp)
+               return false;
+
        return qp->qp_link == NTB_LINK_UP;
 }
 EXPORT_SYMBOL_GPL(ntb_transport_link_query);
@@ -1422,6 +1469,9 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_query);
  */
 unsigned char ntb_transport_qp_num(struct ntb_transport_qp *qp)
 {
+       if (!qp)
+               return 0;
+
        return qp->qp_num;
 }
 EXPORT_SYMBOL_GPL(ntb_transport_qp_num);
@@ -1436,6 +1486,9 @@ EXPORT_SYMBOL_GPL(ntb_transport_qp_num);
  */
 unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp)
 {
+       if (!qp)
+               return 0;
+
        return qp->tx_max_frame - sizeof(struct ntb_payload_header);
 }
 EXPORT_SYMBOL_GPL(ntb_transport_max_size);
index c76d16c972cc6cfaf6ce08fd56ebe89020508032..f53b992f060a1eaa50fb9de6afda8edb6bf49e69 100644 (file)
@@ -1208,11 +1208,11 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
                                out_args->args_count = count;
                                for (i = 0; i < count; i++)
                                        out_args->args[i] = be32_to_cpup(list++);
+                       } else {
+                               of_node_put(node);
                        }
 
                        /* Found it! return success */
-                       if (node)
-                               of_node_put(node);
                        return 0;
                }
 
index aa17f7580f617b05d7469c372656922f229a9803..6d4532702f809b5cc52629fbdc7ad238412153f3 100644 (file)
@@ -851,23 +851,12 @@ static int abx500_gpio_probe(struct platform_device *pdev)
 
        if (abx500_pdata)
                pdata = abx500_pdata->gpio;
-       if (!pdata) {
-               if (np) {
-                       const struct of_device_id *match;
 
-                       match = of_match_device(abx500_gpio_match, &pdev->dev);
-                       if (!match)
-                               return -ENODEV;
-                       id = (unsigned long)match->data;
-               } else {
-                       dev_err(&pdev->dev, "gpio dt and platform data missing\n");
-                       return -ENODEV;
-               }
+       if (!(pdata || np)) {
+               dev_err(&pdev->dev, "gpio dt and platform data missing\n");
+               return -ENODEV;
        }
 
-       if (platid)
-               id = platid->driver_data;
-
        pct = devm_kzalloc(&pdev->dev, sizeof(struct abx500_pinctrl),
                                   GFP_KERNEL);
        if (pct == NULL) {
@@ -882,6 +871,16 @@ static int abx500_gpio_probe(struct platform_device *pdev)
        pct->chip.dev = &pdev->dev;
        pct->chip.base = (np) ? -1 : pdata->gpio_base;
 
+       if (platid)
+               id = platid->driver_data;
+       else if (np) {
+               const struct of_device_id *match;
+
+               match = of_match_device(abx500_gpio_match, &pdev->dev);
+               if (match)
+                       id = (unsigned long)match->data;
+       }
+
        /* initialize the lock */
        mutex_init(&pct->lock);
 
@@ -900,8 +899,7 @@ static int abx500_gpio_probe(struct platform_device *pdev)
                abx500_pinctrl_ab8505_init(&pct->soc);
                break;
        default:
-               dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n",
-                               (int) platid->driver_data);
+               dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n", id);
                mutex_destroy(&pct->lock);
                return -EINVAL;
        }
index edde3acc41864b5d9770be7696e553558d428902..a67af419f5317b3ddd7ad4d777bcc49d30142dec 100644 (file)
@@ -713,11 +713,6 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
        gpio->dev = &pdev->dev;
 
        memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!memres) {
-               dev_err(gpio->dev, "could not get GPIO memory resource\n");
-               return -ENODEV;
-       }
-
        gpio->base = devm_ioremap_resource(&pdev->dev, memres);
        if (IS_ERR(gpio->base))
                return PTR_ERR(gpio->base);
index 6038503ed929cc5c9332e7f4903412cf2d1d3611..32a48f44f574264f5c1b320e00db8065f1ba0616 100644 (file)
@@ -1000,11 +1000,6 @@ static int exynos5440_pinctrl_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "cannot find IO resource\n");
-               return -ENOENT;
-       }
-
        priv->reg_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(priv->reg_base))
                return PTR_ERR(priv->reg_base);
index 615c5002b757e1515187a1a87278a69d9a980d8f..d22ca252b80d41b6b1d10b59f83d9e33e9f9b1ef 100644 (file)
@@ -52,7 +52,8 @@ static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
        int i;
 
        for (i = 0; i < num_maps; i++)
-               if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+               if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN ||
+                   map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
                        kfree(map[i].data.configs.configs);
        kfree(map);
 }
index 976366899f68831f6765f1422ce996a1c8dec3b8..055d0162098ba3da211fcee48f7d334c4def092c 100644 (file)
@@ -932,11 +932,6 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
        drvdata->dev = dev;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "cannot find IO resource\n");
-               return -ENOENT;
-       }
-
        drvdata->virt_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(drvdata->virt_base))
                return PTR_ERR(drvdata->virt_base);
index 5f2d2bfd356e92c6bfac0ff54dde45fb472f7fbe..b9fa046186011bb0e3c781bbc6b0b7787b272c97 100644 (file)
@@ -1166,7 +1166,8 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
        (*map)->data.mux.function = np->name;
 
        if (pcs->is_pinconf) {
-               if (pcs_parse_pinconf(pcs, np, function, map))
+               res = pcs_parse_pinconf(pcs, np, function, map);
+               if (res)
                        goto free_pingroups;
                *num_maps = 2;
        } else {
index f2977cff8366f4b89f88987f1080039a39f2f110..e92132c76a6b56cf02415f18b890c259f377c404 100644 (file)
@@ -716,10 +716,6 @@ static int pinmux_xway_probe(struct platform_device *pdev)
 
        /* get and remap our register range */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Failed to get resource\n");
-               return -ENOENT;
-       }
        xway_info.membase[0] = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(xway_info.membase[0]))
                return PTR_ERR(xway_info.membase[0]);
index b964cc5505681c9a590de10852e6187a2b558d79..de43262398db483cfd9b21cc3cabb22bc4903011 100644 (file)
@@ -53,7 +53,7 @@ static const struct wmt_pinctrl_bank_registers wm8750_banks[] = {
 #define WMT_PIN_EXTGPIO6       WMT_PIN(0, 6)
 #define WMT_PIN_EXTGPIO7       WMT_PIN(0, 7)
 #define WMT_PIN_WAKEUP0                WMT_PIN(0, 16)
-#define WMT_PIN_WAKEUP1                WMT_PIN(0, 16)
+#define WMT_PIN_WAKEUP1                WMT_PIN(0, 17)
 #define WMT_PIN_SD0CD          WMT_PIN(0, 28)
 #define WMT_PIN_VDOUT0         WMT_PIN(1, 0)
 #define WMT_PIN_VDOUT1         WMT_PIN(1, 1)
index ec287989eafc56b89d509e48b3f8ad8999fdc0a7..c938bae18812ea5768e77b48ee2b0f1a6e39b24f 100644 (file)
@@ -265,11 +265,6 @@ static int imx_pwm_probe(struct platform_device *pdev)
        imx->chip.npwm = 1;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               return -ENODEV;
-       }
-
        imx->mmio_base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(imx->mmio_base))
                return PTR_ERR(imx->mmio_base);
index d1eb499fb15d2a3bbf3fec0198a3de7c9451e43b..ed6007b27585a9512d5c2470248343b3e80882d4 100644 (file)
@@ -117,11 +117,6 @@ static int pwm_probe(struct platform_device *pdev)
                return PTR_ERR(puv3->clk);
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               return -ENODEV;
-       }
-
        puv3->base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(puv3->base))
                return PTR_ERR(puv3->base);
index dee6ab552a0a9439c968c695574e14e001a67339..dc9717551d395be96800008bdee1f2379b04759a 100644 (file)
@@ -147,11 +147,6 @@ static int pwm_probe(struct platform_device *pdev)
        pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               return -ENODEV;
-       }
-
        pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(pwm->mmio_base))
                return PTR_ERR(pwm->mmio_base);
index 3d75f4a88f982395a148aca6906dd1fbf27c87cf..a5402933001f9cf446192d79b1ddf204e748e2a1 100644 (file)
@@ -181,11 +181,6 @@ static int tegra_pwm_probe(struct platform_device *pdev)
        pwm->dev = &pdev->dev;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r) {
-               dev_err(&pdev->dev, "no memory resources defined\n");
-               return -ENODEV;
-       }
-
        pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(pwm->mmio_base))
                return PTR_ERR(pwm->mmio_base);
index 0d65fb2e02c7897348862bebe2ac27be8449c432..72ca42dfa733312e408f155db136d81eb1822ace 100644 (file)
@@ -240,11 +240,6 @@ static int ecap_pwm_probe(struct platform_device *pdev)
        pc->chip.npwm = 1;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               return -ENODEV;
-       }
-
        pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(pc->mmio_base))
                return PTR_ERR(pc->mmio_base);
index 6a217596942f0d6badeeff620b50d182459554a5..48a485c2e4224a334b49dda3f1a8848aaecb2bfa 100644 (file)
@@ -471,11 +471,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
        pc->chip.npwm = NUM_PWM_CHANNEL;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               return -ENODEV;
-       }
-
        pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(pc->mmio_base))
                return PTR_ERR(pc->mmio_base);
index c9c3d3a1e0eb2693ac9b1fad89f620c077323bca..3b119bc2c3c606f3c9ca697d9fa1dc5e66144e59 100644 (file)
@@ -70,11 +70,6 @@ static int pwmss_probe(struct platform_device *pdev)
        mutex_init(&info->pwmss_lock);
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               return -ENODEV;
-       }
-
        info->mmio_base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(info->mmio_base))
                return PTR_ERR(info->mmio_base);
index 69effd19afc700144ad35ab4fce44ccf991f8dae..323125abf3f4ddae2d6f2c48abe956c8b497b40e 100644 (file)
@@ -230,11 +230,6 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
        }
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               return -ENODEV;
-       }
-
        chip->base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(chip->base))
                return PTR_ERR(chip->base);
index 0c81915b19975278daa15f99dea370bced46333c..b9838130a7b0da42a3bc0f35724c9b53b553096f 100644 (file)
@@ -20,7 +20,6 @@ if RTC_CLASS
 config RTC_HCTOSYS
        bool "Set system time from RTC on startup and resume"
        default y
-       depends on !ALWAYS_USE_PERSISTENT_CLOCK
        help
          If you say yes here, the system time (wall clock) will be set using
          the value read from a specified RTC device. This is useful to avoid
@@ -29,7 +28,6 @@ config RTC_HCTOSYS
 config RTC_SYSTOHC
        bool "Set the RTC time based on NTP synchronization"
        default y
-       depends on !ALWAYS_USE_PERSISTENT_CLOCK
        help
          If you say yes here, the system time (wall clock) will be stored
          in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11
index f5dfb6e5e7d9b927e69e52cd3bce2ae801c1171e..d592e2fe43f7a7fd29be1592080c03d854ed22d3 100644 (file)
@@ -234,11 +234,6 @@ static int __init nuc900_rtc_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "platform_get_resource failed\n");
-               return -ENXIO;
-       }
-
        nuc900_rtc->rtc_reg = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(nuc900_rtc->rtc_reg))
                return PTR_ERR(nuc900_rtc->rtc_reg);
index 4e1bdb832e37cc9f50018343b22628ca8c364e83..b0ba3fc991ea2352de71d1839480f967ef8a52b0 100644 (file)
@@ -347,11 +347,6 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               pr_debug("%s: RTC resource data missing\n", pdev->name);
-               return -ENOENT;
-       }
-
        rtc_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(rtc_base))
                return PTR_ERR(rtc_base);
index 14040b22888de32607eef344e31efe574cec5250..0b495e8b8e66958d0781086264b7c8653b3d0eed 100644 (file)
@@ -477,11 +477,6 @@ static int s3c_rtc_probe(struct platform_device *pdev)
        /* get the memory region */
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "failed to get memory region resource\n");
-               return -ENOENT;
-       }
-
        s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(s3c_rtc_base))
                return PTR_ERR(s3c_rtc_base);
index a34315d25478131c00ef1b308bb91f4152f25cae..76af92ad5a8ac418fa846e91935a0ae80fdbfc72 100644 (file)
@@ -322,12 +322,6 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev,
-                       "Unable to allocate resources for device.\n");
-               return -EBUSY;
-       }
-
        info->rtc_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(info->rtc_base))
                return PTR_ERR(info->rtc_base);
index 690c3338a8ae5a6e4a9b9a5ee3fbedb0b1ec8c82..464dd29d06c07dcbeb1e6ee96a439dbb037a25a9 100644 (file)
@@ -343,6 +343,7 @@ static int __init xpram_setup_blkdev(void)
                        put_disk(xpram_disks[i]);
                        goto out;
                }
+               queue_flag_set_unlocked(QUEUE_FLAG_NONROT, xpram_queues[i]);
                blk_queue_make_request(xpram_queues[i], xpram_make_request);
                blk_queue_logical_block_size(xpram_queues[i], 4096);
        }
index 21fabc6d5a9c83bac80fda8d78495c26f9febe64..6c440d4349d4f69506fc2615074d6989d37a7c3b 100644 (file)
@@ -352,12 +352,48 @@ static ssize_t chp_shared_show(struct device *dev,
 
 static DEVICE_ATTR(shared, 0444, chp_shared_show, NULL);
 
+static ssize_t chp_chid_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       struct channel_path *chp = to_channelpath(dev);
+       ssize_t rc;
+
+       mutex_lock(&chp->lock);
+       if (chp->desc_fmt1.flags & 0x10)
+               rc = sprintf(buf, "%04x\n", chp->desc_fmt1.chid);
+       else
+               rc = 0;
+       mutex_unlock(&chp->lock);
+
+       return rc;
+}
+static DEVICE_ATTR(chid, 0444, chp_chid_show, NULL);
+
+static ssize_t chp_chid_external_show(struct device *dev,
+                                     struct device_attribute *attr, char *buf)
+{
+       struct channel_path *chp = to_channelpath(dev);
+       ssize_t rc;
+
+       mutex_lock(&chp->lock);
+       if (chp->desc_fmt1.flags & 0x10)
+               rc = sprintf(buf, "%x\n", chp->desc_fmt1.flags & 0x8 ? 1 : 0);
+       else
+               rc = 0;
+       mutex_unlock(&chp->lock);
+
+       return rc;
+}
+static DEVICE_ATTR(chid_external, 0444, chp_chid_external_show, NULL);
+
 static struct attribute *chp_attrs[] = {
        &dev_attr_status.attr,
        &dev_attr_configure.attr,
        &dev_attr_type.attr,
        &dev_attr_cmg.attr,
        &dev_attr_shared.attr,
+       &dev_attr_chid.attr,
+       &dev_attr_chid_external.attr,
        NULL,
 };
 static struct attribute_group chp_attr_group = {
index 349d5fc471963a20d7f1dd4fec393ef44877d6a6..e7ef2a683b8fbc617368ad855f4f18d6832b3eb6 100644 (file)
@@ -43,7 +43,9 @@ struct channel_path_desc_fmt1 {
        u8 chpid;
        u32:24;
        u8 chpp;
-       u32 unused[3];
+       u32 unused[2];
+       u16 chid;
+       u32:16;
        u16 mdc;
        u16:13;
        u8 r:1;
index 787bd2c22bca44043b615d8b3b4d70663a3d36a9..380387a47b1d86fe4e6a8a7ef22a537bfb85517a 100644 (file)
@@ -526,13 +526,17 @@ static void atmel_spi_next_xfer_pio(struct spi_master *master,
        }
 
        if (xfer->tx_buf)
-               spi_writel(as, TDR, *(u8 *)(xfer->tx_buf));
+               if (xfer->bits_per_word > 8)
+                       spi_writel(as, TDR, *(u16 *)(xfer->tx_buf));
+               else
+                       spi_writel(as, TDR, *(u8 *)(xfer->tx_buf));
        else
                spi_writel(as, TDR, 0);
 
        dev_dbg(master->dev.parent,
-               "  start pio xfer %p: len %u tx %p rx %p\n",
-               xfer, xfer->len, xfer->tx_buf, xfer->rx_buf);
+               "  start pio xfer %p: len %u tx %p rx %p bitpw %d\n",
+               xfer, xfer->len, xfer->tx_buf, xfer->rx_buf,
+               xfer->bits_per_word);
 
        /* Enable relevant interrupts */
        spi_writel(as, IER, SPI_BIT(RDRF) | SPI_BIT(OVRES));
@@ -950,21 +954,39 @@ atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer)
 {
        u8              *txp;
        u8              *rxp;
+       u16             *txp16;
+       u16             *rxp16;
        unsigned long   xfer_pos = xfer->len - as->current_remaining_bytes;
 
        if (xfer->rx_buf) {
-               rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
-               *rxp = spi_readl(as, RDR);
+               if (xfer->bits_per_word > 8) {
+                       rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos);
+                       *rxp16 = spi_readl(as, RDR);
+               } else {
+                       rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
+                       *rxp = spi_readl(as, RDR);
+               }
        } else {
                spi_readl(as, RDR);
        }
-
-       as->current_remaining_bytes--;
+       if (xfer->bits_per_word > 8) {
+               as->current_remaining_bytes -= 2;
+               if (as->current_remaining_bytes < 0)
+                       as->current_remaining_bytes = 0;
+       } else {
+               as->current_remaining_bytes--;
+       }
 
        if (as->current_remaining_bytes) {
                if (xfer->tx_buf) {
-                       txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1;
-                       spi_writel(as, TDR, *txp);
+                       if (xfer->bits_per_word > 8) {
+                               txp16 = (u16 *)(((u8 *)xfer->tx_buf)
+                                                       + xfer_pos + 2);
+                               spi_writel(as, TDR, *txp16);
+                       } else {
+                               txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1;
+                               spi_writel(as, TDR, *txp);
+                       }
                } else {
                        spi_writel(as, TDR, 0);
                }
@@ -1378,9 +1400,16 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
                        }
                }
 
+               if (xfer->bits_per_word > 8) {
+                       if (xfer->len % 2) {
+                               dev_dbg(&spi->dev, "buffer len should be 16 bits aligned\n");
+                               return -EINVAL;
+                       }
+               }
+
                /* FIXME implement these protocol options!! */
-               if (xfer->speed_hz) {
-                       dev_dbg(&spi->dev, "no protocol options yet\n");
+               if (xfer->speed_hz < spi->max_speed_hz) {
+                       dev_dbg(&spi->dev, "can't change speed in transfer\n");
                        return -ENOPROTOOPT;
                }
 
index 2e8f24a1fb952cbfd86b161ad50ac3e315d0850b..50b13c9b1ab691fd5defcae44b98dc4bfccb5557 100644 (file)
@@ -784,7 +784,7 @@ static const struct of_device_id davinci_spi_of_match[] = {
        },
        { },
 };
-MODULE_DEVICE_TABLE(of, davini_spi_of_match);
+MODULE_DEVICE_TABLE(of, davinci_spi_of_match);
 
 /**
  * spi_davinci_get_pdata - Get platform data from DTS binding
index d65c000efe3530c1997e996c406eb5880f4df5a4..09df8e22dba0a146c540248cea5374fa0fb13c92 100644 (file)
@@ -489,11 +489,6 @@ static int tegra_sflash_probe(struct platform_device *pdev)
        tegra_sflash_parse_dt(tsd);
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r) {
-               dev_err(&pdev->dev, "No IO memory resource\n");
-               ret = -ENODEV;
-               goto exit_free_master;
-       }
        tsd->base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(tsd->base)) {
                ret = PTR_ERR(tsd->base);
index 163fd802b7aced2217494397297de76862056ea5..32b7bb111eb6b53d9e96808f7bd5fd0982cffd9d 100644 (file)
@@ -334,7 +334,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master)
        spi->dev.parent = &master->dev;
        spi->dev.bus = &spi_bus_type;
        spi->dev.release = spidev_release;
-       spi->cs_gpio = -EINVAL;
+       spi->cs_gpio = -ENOENT;
        device_initialize(&spi->dev);
        return spi;
 }
@@ -1067,8 +1067,11 @@ static int of_spi_register_master(struct spi_master *master)
        nb = of_gpio_named_count(np, "cs-gpios");
        master->num_chipselect = max(nb, (int)master->num_chipselect);
 
-       if (nb < 1)
+       /* Return error only for an incorrectly formed cs-gpios property */
+       if (nb == 0 || nb == -ENOENT)
                return 0;
+       else if (nb < 0)
+               return nb;
 
        cs = devm_kzalloc(&master->dev,
                          sizeof(int) * master->num_chipselect,
@@ -1079,7 +1082,7 @@ static int of_spi_register_master(struct spi_master *master)
                return -ENOMEM;
 
        for (i = 0; i < master->num_chipselect; i++)
-               cs[i] = -EINVAL;
+               cs[i] = -ENOENT;
 
        for (i = 0; i < nb; i++)
                cs[i] = of_get_named_gpio(np, "cs-gpios", i);
index 609d35c19c3561b34401b571008653c8808185e0..d15d9d58e5ac2a3022c92e9843f7de7b64685f1f 100644 (file)
@@ -2,7 +2,6 @@ config USB_DWC2
        tristate "DesignWare USB2 DRD Core Support"
        depends on USB
        depends on VIRT_TO_BUS
-       select USB_OTG_UTILS
        help
          Say Y or M here if your system has a Dual Role HighSpeed
          USB controller based on the DesignWare HSOTG IP Core.
index afc515bd8233baedb7ace47d45ee991bdd479a78..44cce2fa6361194a36ac72dff5825575fd324bf5 100644 (file)
@@ -110,11 +110,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
        }
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&dev->dev, "missing memory base resource\n");
-               return -EINVAL;
-       }
-
        hsotg->regs = devm_ioremap_resource(&dev->dev, res);
        if (IS_ERR(hsotg->regs))
                return PTR_ERR(hsotg->regs);
index 3c18efe3136575ab20559923881ad44da9bd0835..69059138de4ab334b96f44b63599be2ddceed7e9 100644 (file)
@@ -39,7 +39,7 @@ if WIMAX_GDM72XX_USB
 
 config WIMAX_GDM72XX_USB_PM
        bool "Enable power managerment support"
-       depends on USB_SUSPEND
+       depends on PM_RUNTIME
 
 endif # WIMAX_GDM72XX_USB
 
index 0e34679916b8d165b05c7e49c1d2c431f8d230a4..197c393c4ca752a9f50062e2852afd2bb8be89a3 100644 (file)
@@ -814,11 +814,6 @@ static int tegra_nvec_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "no mem resource?\n");
-               return -ENODEV;
-       }
-
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base))
                return PTR_ERR(base);
index ffbc6a94be522abd396a50b90ccb47e9c202a76f..262ef1f23b3819ea8211ea782637c596a9665873 100644 (file)
@@ -1250,7 +1250,7 @@ static u32 iscsit_do_crypto_hash_sg(
 
 static void iscsit_do_crypto_hash_buf(
        struct hash_desc *hash,
-       unsigned char *buf,
+       const void *buf,
        u32 payload_length,
        u32 padding,
        u8 *pad_bytes,
@@ -2524,9 +2524,8 @@ static int iscsit_send_conn_drop_async_message(
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)hdr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                cmd->tx_size += ISCSI_CRC_LEN;
                pr_debug("Attaching CRC32C HeaderDigest to"
@@ -2662,9 +2661,8 @@ static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)cmd->pdu, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                iov[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -2841,9 +2839,8 @@ iscsit_send_logout(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)&cmd->pdu[0], ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, &cmd->pdu[0],
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                iov[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -2900,9 +2897,8 @@ static int iscsit_send_unsolicited_nopin(
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)hdr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                tx_size += ISCSI_CRC_LEN;
                pr_debug("Attaching CRC32C HeaderDigest to"
@@ -2949,9 +2945,8 @@ iscsit_send_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)hdr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                iov[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -3040,9 +3035,8 @@ static int iscsit_send_r2t(
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)hdr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -3256,9 +3250,8 @@ static int iscsit_send_response(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)cmd->pdu, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                iov[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -3329,9 +3322,8 @@ iscsit_send_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)hdr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -3504,9 +3496,8 @@ static int iscsit_send_text_rsp(
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)hdr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                iov[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -3557,11 +3548,11 @@ static int iscsit_send_reject(
        struct iscsi_cmd *cmd,
        struct iscsi_conn *conn)
 {
-       u32 iov_count = 0, tx_size = 0;
-       struct iscsi_reject *hdr;
+       struct iscsi_reject *hdr = (struct iscsi_reject *)&cmd->pdu[0];
        struct kvec *iov;
+       u32 iov_count = 0, tx_size;
 
-       iscsit_build_reject(cmd, conn, (struct iscsi_reject *)&cmd->pdu[0]);
+       iscsit_build_reject(cmd, conn, hdr);
 
        iov = &cmd->iov_misc[0];
        iov[iov_count].iov_base = cmd->pdu;
@@ -3574,9 +3565,8 @@ static int iscsit_send_reject(
        if (conn->conn_ops->HeaderDigest) {
                u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)hdr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)header_digest);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
 
                iov[0].iov_len += ISCSI_CRC_LEN;
                tx_size += ISCSI_CRC_LEN;
@@ -3585,9 +3575,8 @@ static int iscsit_send_reject(
        }
 
        if (conn->conn_ops->DataDigest) {
-               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-                               (unsigned char *)cmd->buf_ptr, ISCSI_HDR_LEN,
-                               0, NULL, (u8 *)&cmd->data_crc);
+               iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->buf_ptr,
+                               ISCSI_HDR_LEN, 0, NULL, (u8 *)&cmd->data_crc);
 
                iov[iov_count].iov_base = &cmd->data_crc;
                iov[iov_count++].iov_len  = ISCSI_CRC_LEN;
index 7816af6cdd1209f7e09ac31adc027ab80b3663de..40d9dbca987b25a811ca0fb75c9c0277f65933a8 100644 (file)
@@ -823,7 +823,7 @@ static int iscsit_attach_ooo_cmdsn(
                /*
                 * CmdSN is greater than the tail of the list.
                 */
-               if (ooo_tail->cmdsn < ooo_cmdsn->cmdsn)
+               if (iscsi_sna_lt(ooo_tail->cmdsn, ooo_cmdsn->cmdsn))
                        list_add_tail(&ooo_cmdsn->ooo_list,
                                        &sess->sess_ooo_cmdsn_list);
                else {
@@ -833,11 +833,12 @@ static int iscsit_attach_ooo_cmdsn(
                         */
                        list_for_each_entry(ooo_tmp, &sess->sess_ooo_cmdsn_list,
                                                ooo_list) {
-                               if (ooo_tmp->cmdsn < ooo_cmdsn->cmdsn)
+                               if (iscsi_sna_lt(ooo_tmp->cmdsn, ooo_cmdsn->cmdsn))
                                        continue;
 
+                               /* Insert before this entry */
                                list_add(&ooo_cmdsn->ooo_list,
-                                       &ooo_tmp->ooo_list);
+                                       ooo_tmp->ooo_list.prev);
                                break;
                        }
                }
index f690be9e5293f0872667188a84df5a7e1998032e..c2185fc31136839500ef198dbbfaef5792fe561d 100644 (file)
@@ -436,7 +436,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
        /*
         * Extra parameters for ISER from RFC-5046
         */
-       param = iscsi_set_default_param(pl, RDMAEXTENTIONS, INITIAL_RDMAEXTENTIONS,
+       param = iscsi_set_default_param(pl, RDMAEXTENSIONS, INITIAL_RDMAEXTENSIONS,
                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
                        TYPERANGE_BOOL_AND, USE_LEADING_ONLY);
        if (!param)
@@ -529,7 +529,7 @@ int iscsi_set_keys_to_negotiate(
                        SET_PSTATE_NEGOTIATE(param);
                } else if (!strcmp(param->name, OFMARKINT)) {
                        SET_PSTATE_NEGOTIATE(param);
-               } else if (!strcmp(param->name, RDMAEXTENTIONS)) {
+               } else if (!strcmp(param->name, RDMAEXTENSIONS)) {
                        if (iser == true)
                                SET_PSTATE_NEGOTIATE(param);
                } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
@@ -580,7 +580,7 @@ int iscsi_set_keys_irrelevant_for_discovery(
                        param->state &= ~PSTATE_NEGOTIATE;
                else if (!strcmp(param->name, OFMARKINT))
                        param->state &= ~PSTATE_NEGOTIATE;
-               else if (!strcmp(param->name, RDMAEXTENTIONS))
+               else if (!strcmp(param->name, RDMAEXTENSIONS))
                        param->state &= ~PSTATE_NEGOTIATE;
                else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH))
                        param->state &= ~PSTATE_NEGOTIATE;
@@ -1977,7 +1977,7 @@ void iscsi_set_session_parameters(
                        ops->SessionType = !strcmp(param->value, DISCOVERY);
                        pr_debug("SessionType:                  %s\n",
                                param->value);
-               } else if (!strcmp(param->name, RDMAEXTENTIONS)) {
+               } else if (!strcmp(param->name, RDMAEXTENSIONS)) {
                        ops->RDMAExtensions = !strcmp(param->value, YES);
                        pr_debug("RDMAExtensions:               %s\n",
                                param->value);
index f31b9c4b83f26ca6db4cd4fa5fd357ca414c0bfa..915b067985059b3483ca1fbf106c446b09f66742 100644 (file)
@@ -91,7 +91,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
 /*
  * Parameter names of iSCSI Extentions for RDMA (iSER).  See RFC-5046
  */
-#define RDMAEXTENTIONS                 "RDMAExtensions"
+#define RDMAEXTENSIONS                 "RDMAExtensions"
 #define INITIATORRECVDATASEGMENTLENGTH "InitiatorRecvDataSegmentLength"
 #define TARGETRECVDATASEGMENTLENGTH    "TargetRecvDataSegmentLength"
 
@@ -142,7 +142,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
 /*
  * Initial values for iSER parameters following RFC-5046 Section 6
  */
-#define INITIAL_RDMAEXTENTIONS                 NO
+#define INITIAL_RDMAEXTENSIONS                 NO
 #define INITIAL_INITIATORRECVDATASEGMENTLENGTH "262144"
 #define INITIAL_TARGETRECVDATASEGMENTLENGTH    "8192"
 
index 43b7ac6c5b1c80e5132bb793d4a447abf11f443c..4a8bd36d39588b24d8de02f495e4ca166c022795 100644 (file)
@@ -1584,6 +1584,13 @@ static struct target_core_configfs_attribute target_core_attr_dev_udev_path = {
        .store  = target_core_store_dev_udev_path,
 };
 
+static ssize_t target_core_show_dev_enable(void *p, char *page)
+{
+       struct se_device *dev = p;
+
+       return snprintf(page, PAGE_SIZE, "%d\n", !!(dev->dev_flags & DF_CONFIGURED));
+}
+
 static ssize_t target_core_store_dev_enable(
        void *p,
        const char *page,
@@ -1609,8 +1616,8 @@ static ssize_t target_core_store_dev_enable(
 static struct target_core_configfs_attribute target_core_attr_dev_enable = {
        .attr   = { .ca_owner = THIS_MODULE,
                    .ca_name = "enable",
-                   .ca_mode = S_IWUSR },
-       .show   = NULL,
+                   .ca_mode =  S_IRUGO | S_IWUSR },
+       .show   = target_core_show_dev_enable,
        .store  = target_core_store_dev_enable,
 };
 
index 2e4d655471bc0f994c5d24df4b0c43f61fefac34..4630481b60438db290caf48ed8fc60c7f224938c 100644 (file)
@@ -68,7 +68,6 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
                struct se_dev_entry *deve = se_cmd->se_deve;
 
                deve->total_cmds++;
-               deve->total_bytes += se_cmd->data_length;
 
                if ((se_cmd->data_direction == DMA_TO_DEVICE) &&
                    (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) {
@@ -85,8 +84,6 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
                else if (se_cmd->data_direction == DMA_FROM_DEVICE)
                        deve->read_bytes += se_cmd->data_length;
 
-               deve->deve_cmds++;
-
                se_lun = deve->se_lun;
                se_cmd->se_lun = deve->se_lun;
                se_cmd->pr_res_key = deve->pr_res_key;
@@ -275,17 +272,6 @@ int core_free_device_list_for_node(
        return 0;
 }
 
-void core_dec_lacl_count(struct se_node_acl *se_nacl, struct se_cmd *se_cmd)
-{
-       struct se_dev_entry *deve;
-       unsigned long flags;
-
-       spin_lock_irqsave(&se_nacl->device_list_lock, flags);
-       deve = se_nacl->device_list[se_cmd->orig_fe_lun];
-       deve->deve_cmds--;
-       spin_unlock_irqrestore(&se_nacl->device_list_lock, flags);
-}
-
 void core_update_device_list_access(
        u32 mapped_lun,
        u32 lun_access,
index 58ed683e04aefc942b7456fae4b9c6ba10f05a00..1b1d544e927aeb18cfacce70b486dde9703770ab 100644 (file)
@@ -153,10 +153,6 @@ static int fd_configure_device(struct se_device *dev)
                struct request_queue *q = bdev_get_queue(inode->i_bdev);
                unsigned long long dev_size;
 
-               dev->dev_attrib.hw_block_size =
-                       bdev_logical_block_size(inode->i_bdev);
-               dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
-
                /*
                 * Determine the number of bytes from i_size_read() minus
                 * one (1) logical sector from underlying struct block_device
@@ -203,9 +199,6 @@ static int fd_configure_device(struct se_device *dev)
                        goto fail;
                }
 
-               dev->dev_attrib.hw_block_size = FD_BLOCKSIZE;
-               dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS;
-
                /*
                 * Limit UNMAP emulation to 8k Number of LBAs (NoLB)
                 */
@@ -226,6 +219,8 @@ static int fd_configure_device(struct se_device *dev)
 
        fd_dev->fd_block_size = dev->dev_attrib.hw_block_size;
 
+       dev->dev_attrib.hw_block_size = FD_BLOCKSIZE;
+       dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS;
        dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
 
        if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
index 07f5f94634bb63ea217250d90e37d7030da93136..aa1620abec6dc0b1ccb5a78305ca2ed41800ac5d 100644 (file)
@@ -615,6 +615,8 @@ iblock_execute_rw(struct se_cmd *cmd)
                                rw = WRITE_FUA;
                        else if (!(q->flush_flags & REQ_FLUSH))
                                rw = WRITE_FUA;
+                       else
+                               rw = WRITE;
                } else {
                        rw = WRITE;
                }
index 853bab60e362ebd8371f50d7a52504ec25fb9fa4..18d49df4d0ac59435c9b50ef87fb61723415c1c5 100644 (file)
@@ -8,7 +8,6 @@ extern struct t10_alua_lu_gp *default_lu_gp;
 struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16);
 int    core_free_device_list_for_node(struct se_node_acl *,
                struct se_portal_group *);
-void   core_dec_lacl_count(struct se_node_acl *, struct se_cmd *);
 void   core_update_device_list_access(u32, u32, struct se_node_acl *);
 int    core_enable_device_list_for_node(struct se_lun *, struct se_lun_acl *,
                u32, u32, struct se_node_acl *, struct se_portal_group *);
index e0b3c379aa148c75d4364dccbb47720c0db1b731..0921a64b555028997691fb28ad7ab84294b10a0d 100644 (file)
@@ -291,6 +291,11 @@ rd_execute_rw(struct se_cmd *cmd)
        u32 src_len;
        u64 tmp;
 
+       if (dev->rd_flags & RDF_NULLIO) {
+               target_complete_cmd(cmd, SAM_STAT_GOOD);
+               return 0;
+       }
+
        tmp = cmd->t_task_lba * se_dev->dev_attrib.block_size;
        rd_offset = do_div(tmp, PAGE_SIZE);
        rd_page = tmp;
@@ -373,11 +378,12 @@ rd_execute_rw(struct se_cmd *cmd)
 }
 
 enum {
-       Opt_rd_pages, Opt_err
+       Opt_rd_pages, Opt_rd_nullio, Opt_err
 };
 
 static match_table_t tokens = {
        {Opt_rd_pages, "rd_pages=%d"},
+       {Opt_rd_nullio, "rd_nullio=%d"},
        {Opt_err, NULL}
 };
 
@@ -408,6 +414,14 @@ static ssize_t rd_set_configfs_dev_params(struct se_device *dev,
                                " Count: %u\n", rd_dev->rd_page_count);
                        rd_dev->rd_flags |= RDF_HAS_PAGE_COUNT;
                        break;
+               case Opt_rd_nullio:
+                       match_int(args, &arg);
+                       if (arg != 1)
+                               break;
+
+                       pr_debug("RAMDISK: Setting NULLIO flag: %d\n", arg);
+                       rd_dev->rd_flags |= RDF_NULLIO;
+                       break;
                default:
                        break;
                }
@@ -424,8 +438,9 @@ static ssize_t rd_show_configfs_dev_params(struct se_device *dev, char *b)
        ssize_t bl = sprintf(b, "TCM RamDisk ID: %u  RamDisk Makeup: rd_mcp\n",
                        rd_dev->rd_dev_id);
        bl += sprintf(b + bl, "        PAGES/PAGE_SIZE: %u*%lu"
-                       "  SG_table_count: %u\n", rd_dev->rd_page_count,
-                       PAGE_SIZE, rd_dev->sg_table_count);
+                       "  SG_table_count: %u  nullio: %d\n", rd_dev->rd_page_count,
+                       PAGE_SIZE, rd_dev->sg_table_count,
+                       !!(rd_dev->rd_flags & RDF_NULLIO));
        return bl;
 }
 
index 933b38b6e56373f282c96a2d3af5677dd6ba8eca..1789d1e14395e0c631d56485972a5ad65b5799a1 100644 (file)
@@ -22,6 +22,7 @@ struct rd_dev_sg_table {
 } ____cacheline_aligned;
 
 #define RDF_HAS_PAGE_COUNT     0x01
+#define RDF_NULLIO             0x02
 
 struct rd_dev {
        struct se_device dev;
index f8388b4024aafa56e647c3e90bc99895df6c5e2c..4a793362309d7204f69596c3e7d0ed0aee625307 100644 (file)
@@ -2163,8 +2163,6 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
                if (wait_for_tasks)
                        transport_wait_for_tasks(cmd);
 
-               core_dec_lacl_count(cmd->se_sess->se_node_acl, cmd);
-
                if (cmd->se_lun)
                        transport_lun_remove_cmd(cmd);
 
@@ -2213,21 +2211,19 @@ static void target_release_cmd_kref(struct kref *kref)
 {
        struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
        struct se_session *se_sess = se_cmd->se_sess;
-       unsigned long flags;
 
-       spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
        if (list_empty(&se_cmd->se_cmd_list)) {
-               spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+               spin_unlock(&se_sess->sess_cmd_lock);
                se_cmd->se_tfo->release_cmd(se_cmd);
                return;
        }
        if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
-               spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+               spin_unlock(&se_sess->sess_cmd_lock);
                complete(&se_cmd->cmd_wait_comp);
                return;
        }
        list_del(&se_cmd->se_cmd_list);
-       spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+       spin_unlock(&se_sess->sess_cmd_lock);
 
        se_cmd->se_tfo->release_cmd(se_cmd);
 }
@@ -2238,7 +2234,8 @@ static void target_release_cmd_kref(struct kref *kref)
  */
 int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
 {
-       return kref_put(&se_cmd->cmd_kref, target_release_cmd_kref);
+       return kref_put_spinlock_irqsave(&se_cmd->cmd_kref, target_release_cmd_kref,
+                       &se_sess->sess_cmd_lock);
 }
 EXPORT_SYMBOL(target_put_sess_cmd);
 
index 5b4d75fd7b49f3f857e39dacc04488977c3d448b..54ffd64ca3f7560a3b9563bf4087c949a32cf2c6 100644 (file)
@@ -169,21 +169,11 @@ static int armada_thermal_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Failed to get platform resource\n");
-               return -ENODEV;
-       }
-
        priv->sensor = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(priv->sensor))
                return PTR_ERR(priv->sensor);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (!res) {
-               dev_err(&pdev->dev, "Failed to get platform resource\n");
-               return -ENODEV;
-       }
-
        priv->control = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(priv->control))
                return PTR_ERR(priv->control);
index 4b15a5f270dc71a021bde1b6e96e8656720d45bc..a088d1365ca5ef287e46db053ba3625b8c536473 100644 (file)
@@ -149,10 +149,6 @@ static int dove_thermal_probe(struct platform_device *pdev)
                return PTR_ERR(priv->sensor);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (!res) {
-               dev_err(&pdev->dev, "Failed to get platform resource\n");
-               return -ENODEV;
-       }
        priv->control = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(priv->control))
                return PTR_ERR(priv->control);
index d20ce9e614034ba4077d797b5584cfad4d994727..788b1ddcac6caa11709b0c383bc3d60295bdb8be 100644 (file)
@@ -925,11 +925,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
        INIT_WORK(&data->irq_work, exynos_tmu_work);
 
        data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!data->mem) {
-               dev_err(&pdev->dev, "Failed to get platform resource\n");
-               return -ENOENT;
-       }
-
        data->base = devm_ioremap_resource(&pdev->dev, data->mem);
        if (IS_ERR(data->base))
                return PTR_ERR(data->base);
index e92eeaf251fe33c8c12f693b54db8b75258643a2..5295be0342c1acc88f5698bbdc29a16268ad551a 100644 (file)
@@ -45,6 +45,7 @@ config UIO_PDRV_GENIRQ
 
 config UIO_DMEM_GENIRQ
        tristate "Userspace platform driver with generic irq and dynamic memory"
+       depends on HAS_DMA
        help
          Platform driver for Userspace I/O devices, including generic
          interrupt handling code. Shared interrupts are not supported.
index b7eb86ad6bf2c2538e1a5d08d358c9b29f432e76..8a7eb77233b4a7b275e042dfeb965be2f45393f8 100644 (file)
@@ -686,7 +686,8 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ
 {
        int ret, len;
        __le32 *buf;
-       int offb, offd;
+       int offb;
+       unsigned int offd;
        const int stride = CMD_PACKET_SIZE / (4 * 2) - 1;
        int buflen =  ((size - 1) / stride + 1 + size * 2) * 4;
 
index 608a2aeb400c929726c4a9581dfad1e09eeed179..b2df442eb3e5b9537772569cfd321e32e5ef2ce5 100644 (file)
@@ -20,7 +20,7 @@ config USB_CHIPIDEA_UDC
 config USB_CHIPIDEA_HOST
        bool "ChipIdea host controller"
        depends on USB=y || USB=USB_CHIPIDEA
-       depends on USB_EHCI_HCD
+       depends on USB_EHCI_HCD=y
        select USB_EHCI_ROOT_HUB_TT
        help
          Say Y here to enable host controller functionality of the
index 8faec9dbbb84326d436ffc568451b322eb95a1a3..73f9d5f15adb6706b30a48b4c34963027d2565a0 100644 (file)
@@ -173,17 +173,10 @@ static int ci13xxx_imx_probe(struct platform_device *pdev)
 
        ci13xxx_imx_platdata.phy = data->phy;
 
-       if (!pdev->dev.dma_mask) {
-               pdev->dev.dma_mask = devm_kzalloc(&pdev->dev,
-                                     sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
-               if (!pdev->dev.dma_mask) {
-                       ret = -ENOMEM;
-                       dev_err(&pdev->dev, "Failed to alloc dma_mask!\n");
-                       goto err;
-               }
-               *pdev->dev.dma_mask = DMA_BIT_MASK(32);
-               dma_set_coherent_mask(&pdev->dev, *pdev->dev.dma_mask);
-       }
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        if (usbmisc_ops && usbmisc_ops->init) {
                ret = usbmisc_ops->init(&pdev->dev);
index 450107e5f657a32a3b7d5b0fd1e310a99e77ec66..49b098bedf9b732ae5c99fdf3020903c24b261e4 100644 (file)
@@ -370,11 +370,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "missing resource\n");
-               return -ENODEV;
-       }
-
        base = devm_ioremap_resource(dev, res);
        if (IS_ERR(base))
                return PTR_ERR(base);
index 8772b3659296b90b2c009774fd3bba8c0498236e..db535b0aa172c85b3787a476b8fe3adeefbe3e6f 100644 (file)
@@ -51,7 +51,7 @@ config USB_DYNAMIC_MINORS
 
 config USB_OTG
        bool "OTG support"
-       depends on USB_SUSPEND
+       depends on PM_RUNTIME
        default n
        help
          The most notable feature of USB OTG is support for a
index ab5638d9c707c0524eb37a58fc1ce3e95d1a7ae9..a63598895077ff8c984c0ed473d5ee90afa52086 100644 (file)
@@ -88,6 +88,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Edirol SD-20 */
        { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Alcor Micro Corp. Hub */
+       { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* appletouch */
        { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
 
index ea5ee9c21c3514cc7a0fe87ff2f6d15bcc206eb2..757aa18027d05ca0eb198d97d92f1710e8e58def 100644 (file)
@@ -19,21 +19,21 @@ choice
 
 config USB_DWC3_HOST
        bool "Host only mode"
-       depends on USB
+       depends on USB=y || USB=USB_DWC3
        help
          Select this when you want to use DWC3 in host mode only,
          thereby the gadget feature will be regressed.
 
 config USB_DWC3_GADGET
        bool "Gadget only mode"
-       depends on USB_GADGET
+       depends on USB_GADGET=y || USB_GADGET=USB_DWC3
        help
          Select this when you want to use DWC3 in gadget mode only,
          thereby the host feature will be regressed.
 
 config USB_DWC3_DUAL_ROLE
        bool "Dual Role mode"
-       depends on (USB && USB_GADGET)
+       depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3))
        help
          This is the default mode of working of DWC3 controller where
          both host and gadget features are enabled.
index a8afe6e2662186e50e45cf578d967c901c9a7456..929e7dd6e58bf6ea4e3d1d6ca7984303f0bbe00d 100644 (file)
@@ -95,8 +95,6 @@ static int dwc3_exynos_remove_child(struct device *dev, void *unused)
        return 0;
 }
 
-static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
-
 static int dwc3_exynos_probe(struct platform_device *pdev)
 {
        struct dwc3_exynos      *exynos;
@@ -118,7 +116,9 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
         * Once we move to full device tree support this will vanish off.
         */
        if (!dev->dma_mask)
-               dev->dma_mask = &dwc3_exynos_dma_mask;
+               dev->dma_mask = &dev->coherent_dma_mask;
+       if (!dev->coherent_dma_mask)
+               dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
        platform_set_drvdata(pdev, exynos);
 
index 83300d94a8933ff97a52992466799874cdeacb20..f41aa0d0c414312163bf2076935fb96adccd7036 100644 (file)
@@ -146,7 +146,6 @@ config USB_LPC32XX
        depends on ARCH_LPC32XX
        depends on USB_PHY
        select USB_ISP1301
-       select USB_OTG_UTILS
        help
           This option selects the USB device controller in the LPC32xx SoC.
 
index f2a970f75bfa949b2c28db72c183e00790fea280..5a5128a226f737d2ec74915cde9f23d5d74e0470 100644 (file)
@@ -1992,8 +1992,6 @@ err_map_regs:
 err_get_hclk:
        clk_put(pclk);
 
-       platform_set_drvdata(pdev, NULL);
-
        return ret;
 }
 
index 6e6518264c42253b810bb41d93fbcd46da7a4906..fd24cb4540a49d6b0382b932ff99eae2dc9c309f 100644 (file)
@@ -2334,21 +2334,11 @@ static int bcm63xx_udc_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "error finding USBD resource\n");
-               return -ENXIO;
-       }
-
        udc->usbd_regs = devm_ioremap_resource(dev, res);
        if (IS_ERR(udc->usbd_regs))
                return PTR_ERR(udc->usbd_regs);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (!res) {
-               dev_err(dev, "error finding IUDMA resource\n");
-               return -ENXIO;
-       }
-
        udc->iudma_regs = devm_ioremap_resource(dev, res);
        if (IS_ERR(udc->iudma_regs))
                return PTR_ERR(udc->iudma_regs);
@@ -2420,7 +2410,6 @@ static int bcm63xx_udc_remove(struct platform_device *pdev)
        usb_del_gadget_udc(&udc->gadget);
        BUG_ON(udc->driver);
 
-       platform_set_drvdata(pdev, NULL);
        bcm63xx_uninit_udc_hw(udc);
 
        return 0;
index 3d5cfc9c2c78a51950701b68bb94bfbb25f2f25c..80e7f75a56c7efa43b33a752671eb8c263bb1bf9 100644 (file)
@@ -821,8 +821,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
                gi->gstrings[i] = NULL;
                s = usb_gstrings_attach(&gi->cdev, gi->gstrings,
                                USB_GADGET_FIRST_AVAIL_IDX);
-               if (IS_ERR(s))
+               if (IS_ERR(s)) {
+                       ret = PTR_ERR(s);
                        goto err_comp_cleanup;
+               }
 
                gi->cdev.desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
                gi->cdev.desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
@@ -847,8 +849,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
                        }
                        cfg->gstrings[i] = NULL;
                        s = usb_gstrings_attach(&gi->cdev, cfg->gstrings, 1);
-                       if (IS_ERR(s))
+                       if (IS_ERR(s)) {
+                               ret = PTR_ERR(s);
                                goto err_comp_cleanup;
+                       }
                        c->iConfiguration = s[0].id;
                }
 
index a792e322f4f1b84c58e20538b48d1e7beea4082f..c588e8e486e590843ed2714403f282a7b3748a68 100644 (file)
@@ -1001,7 +1001,6 @@ static int dummy_udc_remove(struct platform_device *pdev)
        struct dummy    *dum = platform_get_drvdata(pdev);
 
        usb_del_gadget_udc(&dum->gadget);
-       platform_set_drvdata(pdev, NULL);
        device_remove_file(&dum->gadget.dev, &dev_attr_function);
        return 0;
 }
@@ -2661,8 +2660,10 @@ static int __init init(void)
        }
        for (i = 0; i < mod_data.num; i++) {
                dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL);
-               if (!dum[i])
+               if (!dum[i]) {
+                       retval = -ENOMEM;
                        goto err_add_pdata;
+               }
                retval = platform_device_add_data(the_hcd_pdev[i], &dum[i],
                                sizeof(void *));
                if (retval)
index d893d69290794efa9c8d1e064fe1abd62077ff6a..abf8a31ae146028a89130835d600b4a7dfa00486 100644 (file)
@@ -816,6 +816,7 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
  * @c: the configuration to support the network link
  * @ethaddr: a buffer in which the ethernet address of the host side
  *     side of the link was recorded
+ * @dev: eth_dev structure
  * Context: single threaded during gadget setup
  *
  * Returns zero on success, else negative errno.
index 185d6f5e4e4d15a933aeaa5b5e8ab0edc2c642b5..7be04b3424941f73c96d7a6de51d53101efe0f92 100644 (file)
@@ -373,6 +373,7 @@ geth_unbind(struct usb_configuration *c, struct usb_function *f)
  * @c: the configuration to support the network link
  * @ethaddr: a buffer in which the ethernet address of the host side
  *     side of the link was recorded
+ * @dev: eth_dev structure
  * Context: single threaded during gadget setup
  *
  * Returns zero on success, else negative errno.
index c7468b6c07b0057041f63328da8cf075f6ada80b..03c1fb686644e02d34b5b0f4a9c8e847d6a6de27 100644 (file)
@@ -456,8 +456,6 @@ static int snd_uac2_remove(struct platform_device *pdev)
 {
        struct snd_card *card = platform_get_drvdata(pdev);
 
-       platform_set_drvdata(pdev, NULL);
-
        if (card)
                return snd_card_free(card);
 
index cec8871b77f9d9acd91b2c845175b6f9150e8571..b8632d40f8bffcd3f653a99c12f6d6b02a8cd11d 100644 (file)
@@ -1461,8 +1461,10 @@ static int __init fusb300_probe(struct platform_device *pdev)
 
        fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep,
                                GFP_KERNEL);
-       if (fusb300->ep0_req == NULL)
+       if (fusb300->ep0_req == NULL) {
+               ret = -ENOMEM;
                goto clean_up3;
+       }
 
        init_controller(fusb300);
        ret = usb_add_gadget_udc(&pdev->dev, &fusb300->gadget);
index b5cebd6b0d7af170128ede0f90754052b694aeb2..9b2d24e4c95f0c27f3e98c0d2dbf3aa6bfad4b83 100644 (file)
@@ -1511,8 +1511,6 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
        if (pdata->exit)
                pdata->exit(&pdev->dev);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 866ef09992478e18c114592305297efe640d225f..51cfe72da5bb88d6fb0a21a1d1d2753fa2e6c115 100644 (file)
@@ -1660,8 +1660,10 @@ static int __init m66592_probe(struct platform_device *pdev)
        m66592->epaddr2ep[0] = &m66592->ep[0];
 
        m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL);
-       if (m66592->ep0_req == NULL)
+       if (m66592->ep0_req == NULL) {
+               ret = -ENOMEM;
                goto clean_up3;
+       }
        m66592->ep0_req->complete = nop_completion;
 
        init_controller(m66592);
index ef47495dec8f5e638e97ee4171b0a54b22dc2ba4..95c531d5aa4fa2dd9fcf4d038c5426254cb16629 100644 (file)
@@ -2236,7 +2236,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
                dev->transceiver = NULL;
        }
 
-       platform_set_drvdata(pdev, NULL);
        the_controller = NULL;
        return 0;
 }
index 0b742d171843fc8579691930791d0926a7f3d958..7ff7d9cf2061d28ebcd2b4a2935678b0f1460144 100644 (file)
@@ -1977,8 +1977,10 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 
        r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep,
                                                        GFP_KERNEL);
-       if (r8a66597->ep0_req == NULL)
+       if (r8a66597->ep0_req == NULL) {
+               ret = -ENOMEM;
                goto clean_up3;
+       }
        r8a66597->ep0_req->complete = nop_completion;
 
        ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget);
index a3cdc32115d52c646f2ae2b89ded1fcf378a9d70..af22f24046b239dcc9dda8553c17377326c62ded 100644 (file)
@@ -437,7 +437,7 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg,
        if (hs_req->req.length == 0)
                return;
 
-       usb_gadget_unmap_request(&hsotg->gadget, hs_req, hs_ep->dir_in);
+       usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in);
 }
 
 /**
index d0e75e1b3ccb9323de0a29622586894710fd2679..09c4f70c93c4cb13639cf89ed7d423c2231df621 100644 (file)
@@ -1851,6 +1851,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
                irq = gpio_to_irq(udc_info->vbus_pin);
                if (irq < 0) {
                        dev_err(dev, "no irq for gpio vbus pin\n");
+                       retval = irq;
                        goto err_gpio_claim;
                }
 
@@ -1948,8 +1949,6 @@ static int s3c2410_udc_remove(struct platform_device *pdev)
        iounmap(base_addr);
        release_mem_region(rsrc_start, rsrc_len);
 
-       platform_set_drvdata(pdev, NULL);
-
        if (!IS_ERR(udc_clock) && udc_clock != NULL) {
                clk_disable(udc_clock);
                clk_put(udc_clock);
index 2cd6262e8b7149a23d8458e76e5ef6ef3b919f1c..0deb9d6cde26245fd1c52c0b541eecd100aedce6 100644 (file)
@@ -284,12 +284,16 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
        ss_opts->bulk_buflen = gzero_options.bulk_buflen;
 
        func_ss = usb_get_function(func_inst_ss);
-       if (IS_ERR(func_ss))
+       if (IS_ERR(func_ss)) {
+               status = PTR_ERR(func_ss);
                goto err_put_func_inst_ss;
+       }
 
        func_inst_lb = usb_get_function_instance("Loopback");
-       if (IS_ERR(func_inst_lb))
+       if (IS_ERR(func_inst_lb)) {
+               status = PTR_ERR(func_inst_lb);
                goto err_put_func_ss;
+       }
 
        lb_opts = container_of(func_inst_lb, struct f_lb_opts, func_inst);
        lb_opts->bulk_buflen = gzero_options.bulk_buflen;
index de94f2699063b12dd3c0cd1613a9cd2e37cd00c6..344d5e2f87d73a7234452a2b698f63b4959494e5 100644 (file)
@@ -507,7 +507,7 @@ endif # USB_OHCI_HCD
 
 config USB_UHCI_HCD
        tristate "UHCI HCD (most Intel and VIA) support"
-       depends on PCI || SPARC_LEON || ARCH_VT8500
+       depends on PCI || USB_UHCI_SUPPORT_NON_PCI_HC
        ---help---
          The Universal Host Controller Interface is a standard by Intel for
          accessing the USB hardware in the PC (which is also called the USB
@@ -524,26 +524,19 @@ config USB_UHCI_HCD
 
 config USB_UHCI_SUPPORT_NON_PCI_HC
        bool
-       depends on USB_UHCI_HCD
-       default y if (SPARC_LEON || ARCH_VT8500)
+       default y if (SPARC_LEON || USB_UHCI_PLATFORM)
 
 config USB_UHCI_PLATFORM
-       bool "Generic UHCI Platform Driver support"
-       depends on USB_UHCI_SUPPORT_NON_PCI_HC
+       bool
        default y if ARCH_VT8500
-       ---help---
-         Enable support for generic UHCI platform devices that require no
-         additional configuration.
 
 config USB_UHCI_BIG_ENDIAN_MMIO
        bool
-       depends on USB_UHCI_SUPPORT_NON_PCI_HC && SPARC_LEON
-       default y
+       default y if SPARC_LEON
 
 config USB_UHCI_BIG_ENDIAN_DESC
        bool
-       depends on USB_UHCI_SUPPORT_NON_PCI_HC && SPARC_LEON
-       default y
+       default y if SPARC_LEON
 
 config USB_FHCI_HCD
        tristate "Freescale QE USB Host Controller support"
index 66420097c24234eb3db9d09a656345cd80edcc9f..02f4611faa62c571a3a59ff4b33a35ead1966caf 100644 (file)
@@ -63,8 +63,6 @@ static void atmel_stop_ehci(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
-
 static int ehci_atmel_drv_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
@@ -93,7 +91,9 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &at91_ehci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
index 312fc10da3c7aade0225cd126f28e372f1906058..246e124e6ac55c3dc66ba822a9b3f8ba5bebdd6a 100644 (file)
@@ -1286,23 +1286,6 @@ MODULE_LICENSE ("GPL");
 #define        PLATFORM_DRIVER         ehci_hcd_sead3_driver
 #endif
 
-#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \
-       !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_ORION) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_SPEAR) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_S5P) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_HCD_AT91) && \
-       !IS_ENABLED(CONFIG_USB_EHCI_MSM) && \
-       !defined(PLATFORM_DRIVER) && \
-       !defined(PS3_SYSTEM_BUS_DRIVER) && \
-       !defined(OF_PLATFORM_DRIVER) && \
-       !defined(XILINX_OF_PLATFORM_DRIVER)
-#error "missing bus glue for ehci-hcd"
-#endif
-
 static int __init ehci_hcd_init(void)
 {
        int retval = 0;
index 3d1491b5f3605e68b0a72e1d5786233f5ad94d7b..16d7150e855722be6bc143c504d31120adf53f83 100644 (file)
@@ -90,8 +90,6 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = {
        .extra_priv_size = sizeof(struct omap_hcd),
 };
 
-static u64 omap_ehci_dma_mask = DMA_BIT_MASK(32);
-
 /**
  * ehci_hcd_omap_probe - initialize TI-based HCDs
  *
@@ -146,8 +144,10 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
         * Since shared usb code relies on it, set it here for now.
         * Once we have dma capability bindings this can go away.
         */
-       if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &omap_ehci_dma_mask;
+       if (!dev->dma_mask)
+               dev->dma_mask = &dev->coherent_dma_mask;
+       if (!dev->coherent_dma_mask)
+               dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(&ehci_omap_hc_driver, dev,
                        dev_name(dev));
index 54c57948515051867df3dc8d218699ba6806e5ff..efbc588b48c50acbc2225c6be3f63ce1b1f35ffd 100644 (file)
@@ -137,8 +137,6 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
        }
 }
 
-static u64 ehci_orion_dma_mask = DMA_BIT_MASK(32);
-
 static int ehci_orion_drv_probe(struct platform_device *pdev)
 {
        struct orion_ehci_data *pd = pdev->dev.platform_data;
@@ -183,7 +181,9 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
         * now. Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &ehci_orion_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        if (!request_mem_region(res->start, resource_size(res),
                                ehci_orion_hc_driver.description)) {
index 635775278c7fec525a1a3566fce05bb77f3ad77e..379037f51a2fc41b7e7aaaf112a759ce70615ac5 100644 (file)
@@ -71,8 +71,6 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev)
                dev_err(dev, "can't request ehci vbus gpio %d", gpio);
 }
 
-static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
-
 static int s5p_ehci_probe(struct platform_device *pdev)
 {
        struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
@@ -90,7 +88,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
         * Once we move to full device tree support this will vanish off.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &ehci_s5p_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
        if (!pdev->dev.coherent_dma_mask)
                pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
@@ -107,6 +105,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
        if (IS_ERR(phy)) {
                /* Fallback to pdata */
                if (!pdata) {
+                       usb_put_hcd(hcd);
                        dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
                        return -EPROBE_DEFER;
                } else {
index 61ecfb3d52f5d102f78d058fa5c032d37e0e7742..bd3e5cbc6240316dc5947f6f38dbc6a6c7492c51 100644 (file)
@@ -58,8 +58,6 @@ static int ehci_spear_drv_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
                ehci_spear_drv_resume);
 
-static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
-
 static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd ;
@@ -84,7 +82,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &spear_ehci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        usbh_clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(usbh_clk)) {
index e3eddc31ac83fd4f2065a5815967700fa6932ef7..59d111bf44a9d961b45fc85b99d659a8a67230b4 100644 (file)
@@ -637,8 +637,6 @@ static void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
        writel(val, base + TEGRA_USB_PORTSC1);
 }
 
-static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
-
 static int tegra_ehci_probe(struct platform_device *pdev)
 {
        struct resource *res;
@@ -661,7 +659,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &tegra_ehci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        setup_vbus_gpio(pdev, pdata);
 
index 125e261f5bfca15be3d658f4cd976434c58b4912..2facee53eab16103af0a3abc0d67712f8ecc991f 100644 (file)
@@ -1739,7 +1739,7 @@ static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf)
        int retval = 1;
        unsigned long flags;
 
-       /* if !USB_SUSPEND, root hub timers won't get shut down ... */
+       /* if !PM_RUNTIME, root hub timers won't get shut down ... */
        if (!HC_IS_RUNNING(hcd->state))
                return 0;
 
index bbb791bd7617d6db99e064713ea95c527a83bfbf..a13709ee4e5d933bf4514df16296d66c7700ef17 100644 (file)
@@ -373,8 +373,10 @@ static int isp1760_plat_probe(struct platform_device *pdev)
        irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (!irq_res) {
                pr_warning("isp1760: IRQ resource not available\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto cleanup;
        }
+
        irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
 
        if (priv) {
index a0cb44f0e72420ad2c777f09818229a2a3f7c3c6..2ee1496dbc1d37c1f778d847712f78437abe21a4 100644 (file)
@@ -504,8 +504,6 @@ static const struct of_device_id at91_ohci_dt_ids[] = {
 
 MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
 
-static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
-
 static int ohci_at91_of_init(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -522,7 +520,9 @@ static int ohci_at91_of_init(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &at91_ohci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
index 07592c00af26ba166ad75280296c5364b19af9f2..b0b542c14e3132a9f35eceb86ef1255b676e13ca 100644 (file)
@@ -98,8 +98,6 @@ static const struct hc_driver exynos_ohci_hc_driver = {
        .start_port_reset       = ohci_start_port_reset,
 };
 
-static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
        struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
@@ -117,7 +115,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
         * Once we move to full device tree support this will vanish off.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &ohci_exynos_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
        if (!pdev->dev.coherent_dma_mask)
                pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
index 9e6de9586ae4bf82afb01f4c70464ffbbcd01117..fc627fd5411670369d89ba4aec7428b55e2fdef0 100644 (file)
@@ -233,14 +233,14 @@ static int ohci_urb_enqueue (
                        urb->start_frame = frame;
                }
        } else if (ed->type == PIPE_ISOCHRONOUS) {
-               u16     next = ohci_frame_no(ohci) + 2;
+               u16     next = ohci_frame_no(ohci) + 1;
                u16     frame = ed->last_iso + ed->interval;
 
                /* Behind the scheduling threshold? */
                if (unlikely(tick_before(frame, next))) {
 
                        /* USB_ISO_ASAP: Round up to the first available slot */
-                       if (urb->transfer_flags & URB_ISO_ASAP)
+                       if (urb->transfer_flags & URB_ISO_ASAP) {
                                frame += (next - frame + ed->interval - 1) &
                                                -ed->interval;
 
@@ -248,21 +248,25 @@ static int ohci_urb_enqueue (
                         * Not ASAP: Use the next slot in the stream.  If
                         * the entire URB falls before the threshold, fail.
                         */
-                       else if (tick_before(frame + ed->interval *
+                       } else {
+                               if (tick_before(frame + ed->interval *
                                        (urb->number_of_packets - 1), next)) {
-                               retval = -EXDEV;
-                               usb_hcd_unlink_urb_from_ep(hcd, urb);
-                               goto fail;
-                       }
+                                       retval = -EXDEV;
+                                       usb_hcd_unlink_urb_from_ep(hcd, urb);
+                                       goto fail;
+                               }
 
-                       /*
-                        * Some OHCI hardware doesn't handle late TDs
-                        * correctly.  After retiring them it proceeds to
-                        * the next ED instead of the next TD.  Therefore
-                        * we have to omit the late TDs entirely.
-                        */
-                       urb_priv->td_cnt = DIV_ROUND_UP(next - frame,
-                                       ed->interval);
+                               /*
+                                * Some OHCI hardware doesn't handle late TDs
+                                * correctly.  After retiring them it proceeds
+                                * to the next ED instead of the next TD.
+                                * Therefore we have to omit the late TDs
+                                * entirely.
+                                */
+                               urb_priv->td_cnt = DIV_ROUND_UP(
+                                               (u16) (next - frame),
+                                               ed->interval);
+                       }
                }
                urb->start_frame = frame;
        }
index f4988fbe78e79988c59390b216f75b8c0ff8c8f7..5d7eb72c506403b6e3022f14b09aa47e2c8a97c1 100644 (file)
@@ -223,8 +223,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
 
        isp1301_i2c_client = isp1301_get_client(isp1301_node);
        if (!isp1301_i2c_client) {
-               ret = -EPROBE_DEFER;
-               goto out;
+               return -EPROBE_DEFER;
        }
 
        pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
@@ -234,7 +233,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (usb_disabled()) {
                dev_err(&pdev->dev, "USB is disabled\n");
                ret = -ENODEV;
-               goto out;
+               goto fail_disable;
        }
 
        /* Enable AHB slave USB clock, needed for further USB clock control */
@@ -245,19 +244,19 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (IS_ERR(usb_pll_clk)) {
                dev_err(&pdev->dev, "failed to acquire USB PLL\n");
                ret = PTR_ERR(usb_pll_clk);
-               goto out1;
+               goto fail_pll;
        }
 
        ret = clk_enable(usb_pll_clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to start USB PLL\n");
-               goto out2;
+               goto fail_pllen;
        }
 
        ret = clk_set_rate(usb_pll_clk, 48000);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to set USB clock rate\n");
-               goto out3;
+               goto fail_rate;
        }
 
        /* Enable USB device clock */
@@ -265,13 +264,13 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (IS_ERR(usb_dev_clk)) {
                dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
                ret = PTR_ERR(usb_dev_clk);
-               goto out4;
+               goto fail_dev;
        }
 
        ret = clk_enable(usb_dev_clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
-               goto out5;
+               goto fail_deven;
        }
 
        /* Enable USB otg clocks */
@@ -279,7 +278,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (IS_ERR(usb_otg_clk)) {
                dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
                ret = PTR_ERR(usb_otg_clk);
-               goto out6;
+               goto fail_otg;
        }
 
        __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
@@ -287,7 +286,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        ret = clk_enable(usb_otg_clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
-               goto out7;
+               goto fail_otgen;
        }
 
        isp1301_configure();
@@ -296,20 +295,14 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        if (!hcd) {
                dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
                ret = -ENOMEM;
-               goto out8;
+               goto fail_hcd;
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Failed to get MEM resource\n");
-               ret =  -ENOMEM;
-               goto out8;
-       }
-
        hcd->regs = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(hcd->regs)) {
                ret = PTR_ERR(hcd->regs);
-               goto out8;
+               goto fail_resource;
        }
        hcd->rsrc_start = res->start;
        hcd->rsrc_len = resource_size(res);
@@ -317,7 +310,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                ret = -ENXIO;
-               goto out8;
+               goto fail_resource;
        }
 
        nxp_start_hc();
@@ -331,23 +324,24 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
                return ret;
 
        nxp_stop_hc();
-out8:
+fail_resource:
        usb_put_hcd(hcd);
-out7:
+fail_hcd:
        clk_disable(usb_otg_clk);
-out6:
+fail_otgen:
        clk_put(usb_otg_clk);
-out5:
+fail_otg:
        clk_disable(usb_dev_clk);
-out4:
+fail_deven:
        clk_put(usb_dev_clk);
-out3:
+fail_dev:
+fail_rate:
        clk_disable(usb_pll_clk);
-out2:
+fail_pllen:
        clk_put(usb_pll_clk);
-out1:
+fail_pll:
+fail_disable:
        isp1301_i2c_client = NULL;
-out:
        return ret;
 }
 
index ddfc31427bc09e1fc95c63ea40f006ad00631e66..8663851c8d8eac79b5d358d9e6f81f6116d5fc41 100644 (file)
@@ -114,8 +114,6 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static u64 omap_ohci_dma_mask = DMA_BIT_MASK(32);
-
 /*
  * configure so an HC device and id are always provided
  * always called with process context; sleeping is OK
@@ -168,8 +166,10 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
         * Since shared usb code relies on it, set it here for now.
         * Once we have dma capability bindings this can go away.
         */
-       if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &omap_ohci_dma_mask;
+       if (!dev->dma_mask)
+               dev->dma_mask = &dev->coherent_dma_mask;
+       if (!dev->coherent_dma_mask)
+               dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev,
                        dev_name(dev));
index efe71f3ca4772068c557b3063f33cd247a0e19df..279b2ef1741149fe05deda764c09151763f56f1d 100644 (file)
@@ -282,8 +282,6 @@ static const struct of_device_id pxa_ohci_dt_ids[] = {
 
 MODULE_DEVICE_TABLE(of, pxa_ohci_dt_ids);
 
-static u64 pxa_ohci_dma_mask = DMA_BIT_MASK(32);
-
 static int ohci_pxa_of_init(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -298,7 +296,9 @@ static int ohci_pxa_of_init(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &pxa_ohci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
index 9020bf0e2eca13f8837aa46ab8c5ee55969c8b49..3e19e0170d1195711b4f235fd4be043fb234d65e 100644 (file)
@@ -91,8 +91,6 @@ static const struct hc_driver ohci_spear_hc_driver = {
        .start_port_reset       = ohci_start_port_reset,
 };
 
-static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
-
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
        const struct hc_driver *driver = &ohci_spear_hc_driver;
@@ -114,7 +112,9 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &spear_ohci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        usbh_clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(usbh_clk)) {
index 4f0f0339532f7e2729fe90f6972301ec32116041..0f401dbfaf073bb59f7faad445a19663bded3a0e 100644 (file)
@@ -3084,7 +3084,7 @@ static int oxu_hub_status_data(struct usb_hcd *hcd, char *buf)
        int ports, i, retval = 1;
        unsigned long flags;
 
-       /* if !USB_SUSPEND, root hub timers won't get shut down ... */
+       /* if !PM_RUNTIME, root hub timers won't get shut down ... */
        if (!HC_IS_RUNNING(hcd->state))
                return 0;
 
index ad4483efb6d602cad2a841d8747b5983c16fc33c..b2ec7fe758ddcf3dba22f922493ca6cebdeaea10 100644 (file)
@@ -22,7 +22,7 @@
  * and usb-storage.
  *
  * TODO:
- * - usb suspend/resume triggered by sl811 (with USB_SUSPEND)
+ * - usb suspend/resume triggered by sl811 (with PM_RUNTIME)
  * - various issues noted in the code
  * - performance work; use both register banks; ...
  * - use urb->iso_frame_desc[] with ISO transfers
index f87bee6d2789256fc8c8dcdde71a6e4510108397..9189bc984c98ce9804d51ec94c4aebe4147b8f3f 100644 (file)
@@ -225,7 +225,8 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
                /* auto-stop if nothing connected for 1 second */
                if (any_ports_active(uhci))
                        uhci->rh_state = UHCI_RH_RUNNING;
-               else if (time_after_eq(jiffies, uhci->auto_stop_time))
+               else if (time_after_eq(jiffies, uhci->auto_stop_time) &&
+                               !uhci->wait_for_hp)
                        suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
                break;
 
index 8c4dace4b14a5c0455a79b389347cdfab640bd05..f1db61ada6a84c435aedc3967f04f8aab76c1e55 100644 (file)
@@ -60,8 +60,6 @@ static const struct hc_driver uhci_platform_hc_driver = {
        .hub_control =          uhci_hub_control,
 };
 
-static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
-
 static int uhci_hcd_platform_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
@@ -78,7 +76,9 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
         * Once we have dma capability bindings this can go away.
         */
        if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &platform_uhci_dma_mask;
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
        hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
                        pdev->name);
index f0976d8190bc363b52d908540de8214fbeed43b8..041c6ddb695c8ec6fa17d371fe7904de2e47d5ab 100644 (file)
@@ -1287,7 +1287,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
                return -EINVAL;         /* Can't change the period */
 
        } else {
-               next = uhci->frame_number + 2;
+               next = uhci->frame_number + 1;
 
                /* Find the next unused frame */
                if (list_empty(&qh->queue)) {
index 965b539bc47410721c9021f41eb7bf051dcc8feb..2cfc465925bd9c8f67ddd8778957d86f6561a43a 100644 (file)
@@ -1423,15 +1423,17 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        ep_ctx->ep_info2 |= cpu_to_le32(xhci_get_endpoint_type(udev, ep));
 
        /* Set the max packet size and max burst */
+       max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
+       max_burst = 0;
        switch (udev->speed) {
        case USB_SPEED_SUPER:
-               max_packet = usb_endpoint_maxp(&ep->desc);
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
                /* dig out max burst from ep companion desc */
-               max_packet = ep->ss_ep_comp.bMaxBurst;
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet));
+               max_burst = ep->ss_ep_comp.bMaxBurst;
                break;
        case USB_SPEED_HIGH:
+               /* Some devices get this wrong */
+               if (usb_endpoint_xfer_bulk(&ep->desc))
+                       max_packet = 512;
                /* bits 11:12 specify the number of additional transaction
                 * opportunities per microframe (USB 2.0, section 9.6.6)
                 */
@@ -1439,17 +1441,16 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
                                usb_endpoint_xfer_int(&ep->desc)) {
                        max_burst = (usb_endpoint_maxp(&ep->desc)
                                     & 0x1800) >> 11;
-                       ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_burst));
                }
-               /* Fall through */
+               break;
        case USB_SPEED_FULL:
        case USB_SPEED_LOW:
-               max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
                break;
        default:
                BUG();
        }
+       ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) |
+                       MAX_BURST(max_burst));
        max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
        ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload));
 
index 3a18e44e9391850ab7f7ee7858cd6d134b59361e..e1b661d040217a3cdd0e76b325616f85adc04bd6 100644 (file)
@@ -560,6 +560,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
                if (!config) {
                        dev_err(&pdev->dev,
                                "failed to allocate musb hdrc config\n");
+                       ret = -ENOMEM;
                        goto err2;
                }
 
index 3551f1a30c655efdc2977556e9e4f6c540ea115a..628b93fe5cccf585d21759fa112086a345a2e92a 100644 (file)
@@ -549,7 +549,8 @@ static int omap2430_probe(struct platform_device *pdev)
                glue->control_otghs = omap_get_control_dev();
                if (IS_ERR(glue->control_otghs)) {
                        dev_vdbg(&pdev->dev, "Failed to get control device\n");
-                       return -ENODEV;
+                       ret = PTR_ERR(glue->control_otghs);
+                       goto err2;
                }
        } else {
                glue->control_otghs = ERR_PTR(-ENODEV);
index 371d0e74e9094132eb378366858dedd7e654d89f..7ef3eb8617a6c7adc7775bc76a5fb0fd3d699ef8 100644 (file)
@@ -25,7 +25,7 @@ config AB8500_USB
 
 config FSL_USB2_OTG
        bool "Freescale USB OTG Transceiver Driver"
-       depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_SUSPEND
+       depends on USB_EHCI_FSL && USB_FSL_USB2 && PM_RUNTIME
        select USB_OTG
        help
          Enable this to support Freescale USB OTG transceiver.
@@ -139,7 +139,6 @@ config USB_ISP1301
        tristate "NXP ISP1301 USB transceiver support"
        depends on USB || USB_GADGET
        depends on I2C
-       select USB_OTG_UTILS
        help
          Say Y here to add support for the NXP ISP1301 USB transceiver driver.
          This chip is typically used as USB transceiver for USB host, gadget
@@ -162,7 +161,7 @@ config USB_MSM_OTG
 
 config USB_MV_OTG
        tristate "Marvell USB OTG support"
-       depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND
+       depends on USB_EHCI_MV && USB_MV_UDC && PM_RUNTIME
        select USB_OTG
        help
          Say Y here if you want to build Marvell USB OTG transciever
index 4acef26a2ef5c2daa5b7a163e2afd297903e9642..e5eb1b5a04ebb815ffd46be5c1ab48b2fb8ed193 100644 (file)
@@ -892,8 +892,6 @@ static int ab8500_usb_remove(struct platform_device *pdev)
        else if (ab->mode == USB_PERIPHERAL)
                ab8500_usb_peri_phy_dis(ab);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 97b9308507c3dae718828645a79069c6af2de46e..e771bafb9f1da3375f9f0492493c973fe0862484 100644 (file)
@@ -799,6 +799,7 @@ static int fsl_otg_conf(struct platform_device *pdev)
 
        /* initialize the otg structure */
        fsl_otg_tc->phy.label = DRIVER_DESC;
+       fsl_otg_tc->phy.dev = &pdev->dev;
        fsl_otg_tc->phy.set_power = fsl_otg_set_power;
 
        fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy;
index 4c76074e518d56f60c192f560dfc7a3d049de301..8443335c2ea0260414ea183fe69c809b5b328d64 100644 (file)
@@ -266,6 +266,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, gpio_vbus);
        gpio_vbus->dev = &pdev->dev;
        gpio_vbus->phy.label = "gpio-vbus";
+       gpio_vbus->phy.dev = gpio_vbus->dev;
        gpio_vbus->phy.set_power = gpio_vbus_set_power;
        gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend;
        gpio_vbus->phy.state = OTG_STATE_UNDEFINED;
@@ -343,7 +344,6 @@ err_irq:
                gpio_free(pdata->gpio_pullup);
        gpio_free(pdata->gpio_vbus);
 err_gpio:
-       platform_set_drvdata(pdev, NULL);
        kfree(gpio_vbus->phy.otg);
        kfree(gpio_vbus);
        return err;
@@ -365,7 +365,6 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev)
        if (gpio_is_valid(pdata->gpio_pullup))
                gpio_free(pdata->gpio_pullup);
        gpio_free(gpio);
-       platform_set_drvdata(pdev, NULL);
        kfree(gpio_vbus->phy.otg);
        kfree(gpio_vbus);
 
index 225ae6c97eeb4758945cc08b558bdd27ddc7822d..8a55b37d1a024687f6be8078ef4f54f60cdc5111 100644 (file)
@@ -102,6 +102,7 @@ static int isp1301_probe(struct i2c_client *client,
        mutex_init(&isp->mutex);
 
        phy = &isp->phy;
+       phy->dev = &client->dev;
        phy->label = DRV_NAME;
        phy->init = isp1301_phy_init;
        phy->set_vbus = isp1301_phy_set_vbus;
index f7838a43347c64d855fe396c7da3ec2c81246a7b..1568ea63e3380766be04a0491f891e5471bf9ba9 100644 (file)
@@ -278,11 +278,6 @@ static int mv_u3d_phy_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "missing mem resource\n");
-               return -ENODEV;
-       }
-
        phy_base = devm_ioremap_resource(dev, res);
        if (IS_ERR(phy_base))
                return PTR_ERR(phy_base);
index c987bbe278519c04bfc2e390dd59dd0ba6a8be60..4a6b03c738765814adc2eefe6bbbdef6eba8bf0b 100644 (file)
@@ -667,7 +667,6 @@ int mv_otg_remove(struct platform_device *pdev)
        mv_otg_disable(mvotg);
 
        usb_remove_phy(&mvotg->phy);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
@@ -850,8 +849,6 @@ err_destroy_workqueue:
        flush_workqueue(mvotg->qwork);
        destroy_workqueue(mvotg->qwork);
 
-       platform_set_drvdata(pdev, NULL);
-
        return retval;
 }
 
index 9d4381e64d5126d086af1cbca806519e4813f602..bd601c537c8d434a3e33a7aa59d88d583472244f 100644 (file)
@@ -130,11 +130,6 @@ static int mxs_phy_probe(struct platform_device *pdev)
        int ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "can't get device resources\n");
-               return -ENOENT;
-       }
-
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base))
                return PTR_ERR(base);
@@ -160,6 +155,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
        mxs_phy->phy.set_suspend        = mxs_phy_suspend;
        mxs_phy->phy.notify_connect     = mxs_phy_on_connect;
        mxs_phy->phy.notify_disconnect  = mxs_phy_on_disconnect;
+       mxs_phy->phy.type               = USB_PHY_TYPE_USB2;
 
        ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier);
 
@@ -180,8 +176,6 @@ static int mxs_phy_remove(struct platform_device *pdev)
 
        usb_remove_phy(&mxs_phy->phy);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 2b10cc969bbb1f4457a463c2072508953a42fdc2..638cc5dade35227732e77e6c5ccb0d769eb47d8b 100644 (file)
@@ -254,8 +254,6 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev)
 
        usb_remove_phy(&nop->phy);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 45ffe036dacc5acc455b8d3b22de6df0dfe7bef7..9d5e273abcc7652f1b3dbe17992720a170124cdf 100644 (file)
@@ -363,11 +363,6 @@ static int samsung_usb2phy_probe(struct platform_device *pdev)
        int ret;
 
        phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!phy_mem) {
-               dev_err(dev, "%s: missing mem resource\n", __func__);
-               return -ENODEV;
-       }
-
        phy_base = devm_ioremap_resource(dev, phy_mem);
        if (IS_ERR(phy_base))
                return PTR_ERR(phy_base);
index 133f3d0c554f9e7ed8979c1198f854db08def9ef..5a9efcbcb532cc7ecf7d118b0767db0b970b7960 100644 (file)
@@ -239,11 +239,6 @@ static int samsung_usb3phy_probe(struct platform_device *pdev)
        int ret;
 
        phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!phy_mem) {
-               dev_err(dev, "%s: missing mem resource\n", __func__);
-               return -ENODEV;
-       }
-
        phy_base = devm_ioremap_resource(dev, phy_mem);
        if (IS_ERR(phy_base))
                return PTR_ERR(phy_base);
index 242b5776648ab31c1e820bcc82dad0a48c629775..7260ec66034715e7a065d0f5fe6441f49a37f6b4 100644 (file)
@@ -189,6 +189,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) },
        { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) },
+       { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_CC_PID) },
+       { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_AGP_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
        { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
@@ -924,8 +926,8 @@ static int  ftdi_tiocmset(struct tty_struct *tty,
 static int  ftdi_ioctl(struct tty_struct *tty,
                        unsigned int cmd, unsigned long arg);
 static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
-static int ftdi_chars_in_buffer(struct tty_struct *tty);
-static int ftdi_get_modem_status(struct tty_struct *tty,
+static bool ftdi_tx_empty(struct usb_serial_port *port);
+static int ftdi_get_modem_status(struct usb_serial_port *port,
                                                unsigned char status[2]);
 
 static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
@@ -961,7 +963,7 @@ static struct usb_serial_driver ftdi_sio_device = {
        .ioctl =                ftdi_ioctl,
        .set_termios =          ftdi_set_termios,
        .break_ctl =            ftdi_break_ctl,
-       .chars_in_buffer =      ftdi_chars_in_buffer,
+       .tx_empty =             ftdi_tx_empty,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -2056,27 +2058,18 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
 
 }
 
-static int ftdi_chars_in_buffer(struct tty_struct *tty)
+static bool ftdi_tx_empty(struct usb_serial_port *port)
 {
-       struct usb_serial_port *port = tty->driver_data;
-       int chars;
        unsigned char buf[2];
        int ret;
 
-       chars = usb_serial_generic_chars_in_buffer(tty);
-       if (chars)
-               goto out;
-
-       /* Check if hardware buffer is empty. */
-       ret = ftdi_get_modem_status(tty, buf);
+       ret = ftdi_get_modem_status(port, buf);
        if (ret == 2) {
                if (!(buf[1] & FTDI_RS_TEMT))
-                       chars = 1;
+                       return false;
        }
-out:
-       dev_dbg(&port->dev, "%s - %d\n", __func__, chars);
 
-       return chars;
+       return true;
 }
 
 /* old_termios contains the original termios settings and tty->termios contains
@@ -2268,10 +2261,9 @@ no_c_cflag_changes:
  * Returns the number of status bytes retrieved (device dependant), or
  * negative error code.
  */
-static int ftdi_get_modem_status(struct tty_struct *tty,
+static int ftdi_get_modem_status(struct usb_serial_port *port,
                                                unsigned char status[2])
 {
-       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        unsigned char *buf;
        int len;
@@ -2336,7 +2328,7 @@ static int ftdi_tiocmget(struct tty_struct *tty)
        unsigned char buf[2];
        int ret;
 
-       ret = ftdi_get_modem_status(tty, buf);
+       ret = ftdi_get_modem_status(port, buf);
        if (ret < 0)
                return ret;
 
index 98528270c43c21f5f8d66ccf594a269b32f0600f..6dd79253205dd7ec54278ddb078f08346cdbb4f8 100644 (file)
  */
 #define NEWPORT_VID                    0x104D
 #define NEWPORT_AGILIS_PID             0x3000
+#define NEWPORT_CONEX_CC_PID           0x3002
+#define NEWPORT_CONEX_AGP_PID          0x3006
 
 /* Interbiometrics USB I/O Board */
 /* Developed for Interbiometrics by Rudolf Gugler */
index 297665fdd16d31993a5e95cddd313626453be6c7..ba45170c78e5f601ec6b2c57f5f05600247803f4 100644 (file)
@@ -253,6 +253,37 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer);
 
+void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       unsigned int bps;
+       unsigned long period;
+       unsigned long expire;
+
+       bps = tty_get_baud_rate(tty);
+       if (!bps)
+               bps = 9600;     /* B0 */
+       /*
+        * Use a poll-period of roughly the time it takes to send one
+        * character or at least one jiffy.
+        */
+       period = max_t(unsigned long, (10 * HZ / bps), 1);
+       period = min_t(unsigned long, period, timeout);
+
+       dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n",
+                                       __func__, jiffies_to_msecs(timeout),
+                                       jiffies_to_msecs(period));
+       expire = jiffies + timeout;
+       while (!port->serial->type->tx_empty(port)) {
+               schedule_timeout_interruptible(period);
+               if (signal_pending(current))
+                       break;
+               if (time_after(jiffies, expire))
+                       break;
+       }
+}
+EXPORT_SYMBOL_GPL(usb_serial_generic_wait_until_sent);
+
 static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
                                                int index, gfp_t mem_flags)
 {
index 158bf4bc29cc2b6f60c7211ad0e9f8b75186bf04..1be6ba7bee27452ac55c08a06d98ff2394a2f7fb 100644 (file)
@@ -2019,8 +2019,6 @@ static int edge_chars_in_buffer(struct tty_struct *tty)
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
-       int ret;
-
        if (edge_port == NULL)
                return 0;
 
@@ -2028,16 +2026,22 @@ static int edge_chars_in_buffer(struct tty_struct *tty)
        chars = kfifo_len(&edge_port->write_fifo);
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
 
-       if (!chars) {
-               ret = tx_active(edge_port);
-               if (ret > 0)
-                       chars = ret;
-       }
-
        dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
        return chars;
 }
 
+static bool edge_tx_empty(struct usb_serial_port *port)
+{
+       struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+       int ret;
+
+       ret = tx_active(edge_port);
+       if (ret > 0)
+               return false;
+
+       return true;
+}
+
 static void edge_throttle(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
@@ -2557,6 +2561,7 @@ static struct usb_serial_driver edgeport_1port_device = {
        .write                  = edge_write,
        .write_room             = edge_write_room,
        .chars_in_buffer        = edge_chars_in_buffer,
+       .tx_empty               = edge_tx_empty,
        .break_ctl              = edge_break,
        .read_int_callback      = edge_interrupt_callback,
        .read_bulk_callback     = edge_bulk_in_callback,
@@ -2589,6 +2594,7 @@ static struct usb_serial_driver edgeport_2port_device = {
        .write                  = edge_write,
        .write_room             = edge_write_room,
        .chars_in_buffer        = edge_chars_in_buffer,
+       .tx_empty               = edge_tx_empty,
        .break_ctl              = edge_break,
        .read_int_callback      = edge_interrupt_callback,
        .read_bulk_callback     = edge_bulk_in_callback,
index 734372846abbb31b1381841f4f144a09a4f0b2a0..93d02bc4eb52f19dfa0a780e209be5aee84a885f 100644 (file)
@@ -196,6 +196,7 @@ static void option_instat_callback(struct urb *urb);
 
 #define DELL_PRODUCT_5800_MINICARD_VZW         0x8195  /* Novatel E362 */
 #define DELL_PRODUCT_5800_V2_MINICARD_VZW      0x8196  /* Novatel E362 */
+#define DELL_PRODUCT_5804_MINICARD_ATT         0x819b  /* Novatel E371 */
 
 #define KYOCERA_VENDOR_ID                      0x0c88
 #define KYOCERA_PRODUCT_KPC650                 0x17da
@@ -341,8 +342,8 @@ static void option_instat_callback(struct urb *urb);
 #define CINTERION_PRODUCT_EU3_E                        0x0051
 #define CINTERION_PRODUCT_EU3_P                        0x0052
 #define CINTERION_PRODUCT_PH8                  0x0053
-#define CINTERION_PRODUCT_AH                 0x0055
-#define CINTERION_PRODUCT_PLS8                 0x0060
+#define CINTERION_PRODUCT_AHXX                 0x0055
+#define CINTERION_PRODUCT_PLXX                 0x0060
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID                     0x0b3c
@@ -771,6 +772,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) },         /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
        { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5804_MINICARD_ATT, 0xff, 0xff, 0xff) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },   /* ADU-E100, ADU-310 */
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -966,6 +968,8 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
@@ -1264,8 +1268,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
-       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) },
-       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
+               .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
index cac47aef2918972ead4aeb01a43bd9166daec0ca..c92c5ed4e580ec6761d0acabc379cfe667faaeb1 100644 (file)
@@ -101,6 +101,7 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
                const unsigned char *data, int count);
 static int ti_write_room(struct tty_struct *tty);
 static int ti_chars_in_buffer(struct tty_struct *tty);
+static bool ti_tx_empty(struct usb_serial_port *port);
 static void ti_throttle(struct tty_struct *tty);
 static void ti_unthrottle(struct tty_struct *tty);
 static int ti_ioctl(struct tty_struct *tty,
@@ -222,6 +223,7 @@ static struct usb_serial_driver ti_1port_device = {
        .write                  = ti_write,
        .write_room             = ti_write_room,
        .chars_in_buffer        = ti_chars_in_buffer,
+       .tx_empty               = ti_tx_empty,
        .throttle               = ti_throttle,
        .unthrottle             = ti_unthrottle,
        .ioctl                  = ti_ioctl,
@@ -253,6 +255,7 @@ static struct usb_serial_driver ti_2port_device = {
        .write                  = ti_write,
        .write_room             = ti_write_room,
        .chars_in_buffer        = ti_chars_in_buffer,
+       .tx_empty               = ti_tx_empty,
        .throttle               = ti_throttle,
        .unthrottle             = ti_unthrottle,
        .ioctl                  = ti_ioctl,
@@ -684,8 +687,6 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
        struct ti_port *tport = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
-       int ret;
-       u8 lsr;
 
        if (tport == NULL)
                return 0;
@@ -694,16 +695,22 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
        chars = kfifo_len(&tport->write_fifo);
        spin_unlock_irqrestore(&tport->tp_lock, flags);
 
-       if (!chars) {
-               ret = ti_get_lsr(tport, &lsr);
-               if (!ret && !(lsr & TI_LSR_TX_EMPTY))
-                       chars = 1;
-       }
-
        dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
        return chars;
 }
 
+static bool ti_tx_empty(struct usb_serial_port *port)
+{
+       struct ti_port *tport = usb_get_serial_port_data(port);
+       int ret;
+       u8 lsr;
+
+       ret = ti_get_lsr(tport, &lsr);
+       if (!ret && !(lsr & TI_LSR_TX_EMPTY))
+               return false;
+
+       return true;
+}
 
 static void ti_throttle(struct tty_struct *tty)
 {
index cf75beb1251bc85b3c709b989e1ddd5220094c7c..4753c005cfb6f8fffc5ff45999d7e89348c7f96f 100644 (file)
@@ -359,20 +359,29 @@ static int serial_chars_in_buffer(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
-       int count = 0;
 
        dev_dbg(tty->dev, "%s\n", __func__);
 
-       mutex_lock(&serial->disc_mutex);
-       /* if the device was unplugged then any remaining characters
-          fell out of the connector ;) */
        if (serial->disconnected)
-               count = 0;
-       else
-               count = serial->type->chars_in_buffer(tty);
-       mutex_unlock(&serial->disc_mutex);
+               return 0;
+
+       return serial->type->chars_in_buffer(tty);
+}
+
+static void serial_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct usb_serial *serial = port->serial;
+
+       dev_dbg(tty->dev, "%s\n", __func__);
+
+       if (!port->serial->type->wait_until_sent)
+               return;
 
-       return count;
+       mutex_lock(&serial->disc_mutex);
+       if (!serial->disconnected)
+               port->serial->type->wait_until_sent(tty, timeout);
+       mutex_unlock(&serial->disc_mutex);
 }
 
 static void serial_throttle(struct tty_struct *tty)
@@ -1191,6 +1200,7 @@ static const struct tty_operations serial_ops = {
        .unthrottle =           serial_unthrottle,
        .break_ctl =            serial_break,
        .chars_in_buffer =      serial_chars_in_buffer,
+       .wait_until_sent =      serial_wait_until_sent,
        .tiocmget =             serial_tiocmget,
        .tiocmset =             serial_tiocmset,
        .get_icount =           serial_get_icount,
@@ -1316,6 +1326,8 @@ static void usb_serial_operations_init(struct usb_serial_driver *device)
        set_to_generic_if_null(device, close);
        set_to_generic_if_null(device, write_room);
        set_to_generic_if_null(device, chars_in_buffer);
+       if (device->tx_empty)
+               set_to_generic_if_null(device, wait_until_sent);
        set_to_generic_if_null(device, read_bulk_callback);
        set_to_generic_if_null(device, write_bulk_callback);
        set_to_generic_if_null(device, process_read_urb);
index 8623577bbbe70d608eb0866f18be56c20513a5bf..281be56d56485535eaef90e890bb2bfebb30ad00 100644 (file)
@@ -105,8 +105,9 @@ struct rts51x_chip {
        int status_len;
 
        u32 flag;
-#ifdef CONFIG_REALTEK_AUTOPM
        struct us_data *us;
+
+#ifdef CONFIG_REALTEK_AUTOPM
        struct timer_list rts51x_suspend_timer;
        unsigned long timer_expires;
        int pwr_state;
@@ -988,6 +989,7 @@ static int init_realtek_cr(struct us_data *us)
        us->extra = chip;
        us->extra_destructor = realtek_cr_destructor;
        us->max_lun = chip->max_lun = rts51x_get_max_lun(us);
+       chip->us = us;
 
        usb_stor_dbg(us, "chip->max_lun = %d\n", chip->max_lun);
 
@@ -1010,10 +1012,8 @@ static int init_realtek_cr(struct us_data *us)
                        SET_AUTO_DELINK(chip);
        }
 #ifdef CONFIG_REALTEK_AUTOPM
-       if (ss_en) {
-               chip->us = us;
+       if (ss_en)
                realtek_cr_autosuspend_setup(us);
-       }
 #endif
 
        usb_stor_dbg(us, "chip->flag = 0x%x\n", chip->flag);
index bff0775e258c9ce30b1615e38492fa123eb49f8a..5174ebac288d65e70f31c13867e44aa98cc18ff4 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Since these may be in userspace, we use (inline) accessors.
  */
+#include <linux/module.h>
 #include <linux/vringh.h>
 #include <linux/virtio_ring.h>
 #include <linux/kernel.h>
@@ -1005,3 +1006,5 @@ int vringh_need_notify_kern(struct vringh *vrh)
        return __vringh_need_notify(vrh, getu16_kern);
 }
 EXPORT_SYMBOL(vringh_need_notify_kern);
+
+MODULE_LICENSE("GPL");
index 17f4d55c621ca446afb7daed1cc08b6b1e6e2035..a109934c0478ea72808eb0205018d0a1253341f0 100644 (file)
@@ -1065,10 +1065,6 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
        mutex_init(&hdmi.ip_data.lock);
 
        res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               DSSERR("can't get IORESOURCE_MEM HDMI\n");
-               return -EINVAL;
-       }
 
        /* Base address taken from platform */
        hdmi.ip_data.base_wp = devm_ioremap_resource(&pdev->dev, res);
index 5261229c79afbef8afa4e80f24936f6dbb6e6f4e..f346b02eee1d84c2d8da77b15e3d64c72aa4fa17 100644 (file)
@@ -353,11 +353,6 @@ static int __init vrfb_probe(struct platform_device *pdev)
        /* first resource is the register res, the rest are vrfb contexts */
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem) {
-               dev_err(&pdev->dev, "can't get vrfb base address\n");
-               return -EINVAL;
-       }
-
        vrfb_base = devm_ioremap_resource(&pdev->dev, mem);
        if (IS_ERR(vrfb_base))
                return PTR_ERR(vrfb_base);
index db2390aed38781705deeb179790d8a540d9660eb..6e94d8dd3d00a31d696fc7e140329d9b4dc72c6b 100644 (file)
@@ -555,11 +555,6 @@ static int omap_hdq_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, hdq_data);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_dbg(&pdev->dev, "unable to get resource\n");
-               return -ENXIO;
-       }
-
        hdq_data->hdq_base = devm_ioremap_resource(dev, res);
        if (IS_ERR(hdq_data->hdq_base))
                return PTR_ERR(hdq_data->hdq_base);
index d184c48a0482b6a72fab3db591b5a8c425b531ab..37cb09b27b6328e85581955400cb94bf18b66f0e 100644 (file)
@@ -248,11 +248,6 @@ static int ath79_wdt_probe(struct platform_device *pdev)
                return -EBUSY;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "no memory resource found\n");
-               return -EINVAL;
-       }
-
        wdt_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(wdt_base))
                return PTR_ERR(wdt_base);
index 100d4fbfde2adf594203cd5a874dd72f20e06b03..bead7740c86a44da31d3b8dc876b20b51a62cd78 100644 (file)
@@ -217,11 +217,6 @@ static int davinci_wdt_probe(struct platform_device *pdev)
        dev_info(dev, "heartbeat %d sec\n", heartbeat);
 
        wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (wdt_mem == NULL) {
-               dev_err(dev, "failed to get memory region resource\n");
-               return -ENOENT;
-       }
-
        wdt_base = devm_ioremap_resource(dev, wdt_mem);
        if (IS_ERR(wdt_base))
                return PTR_ERR(wdt_base);
index ff908823688cf969e5fd420141827f0cc9a91a39..62946c2cb4f8b1d579f42cd18c5e72a6e4531434 100644 (file)
@@ -257,11 +257,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
        struct resource *res;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "can't get device resources\n");
-               return -ENODEV;
-       }
-
        imx2_wdt.base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(imx2_wdt.base))
                return PTR_ERR(imx2_wdt.base);
index f03bf501527f64785a3fbbec39963f979d70ad8a..9e02d60a364b00d271efb0b4d4eda046a25fbf08 100644 (file)
@@ -19,11 +19,10 @@ config XEN_SELFBALLOONING
          by the current usage of anonymous memory ("committed AS") and
          controlled by various sysfs-settable parameters.  Configuring
          FRONTSWAP is highly recommended; if it is not configured, self-
-         ballooning is disabled by default but can be enabled with the
-         'selfballooning' kernel boot parameter.  If FRONTSWAP is configured,
+         ballooning is disabled by default. If FRONTSWAP is configured,
          frontswap-selfshrinking is enabled by default but can be disabled
-         with the 'noselfshrink' kernel boot parameter; and self-ballooning
-         is enabled by default but can be disabled with the 'noselfballooning'
+         with the 'tmem.selfshrink=0' kernel boot parameter; and self-ballooning
+         is enabled by default but can be disabled with the 'tmem.selfballooning=0'
          kernel boot parameter.  Note that systems without a sufficiently
          large swap device should not enable self-ballooning.
 
index a56776dbe0958ece67b1c12a4a13b8be5bdb023c..930fb68179012355952c20d759111a6755b3acbe 100644 (file)
@@ -407,7 +407,8 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
                nr_pages = ARRAY_SIZE(frame_list);
 
        for (i = 0; i < nr_pages; i++) {
-               if ((page = alloc_page(gfp)) == NULL) {
+               page = alloc_page(gfp);
+               if (page == NULL) {
                        nr_pages = i;
                        state = BP_EAGAIN;
                        break;
index ca2b00e9d558c8fea579f4667106eaccee0adb84..2cfc24d76fc54d97d9e8106c5fdf108379b7ba9f 100644 (file)
@@ -504,7 +504,7 @@ static void privcmd_close(struct vm_area_struct *vma)
        struct page **pages = vma->vm_private_data;
        int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 
-       if (!xen_feature(XENFEAT_auto_translated_physmap || !numpgs || !pages))
+       if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages)
                return;
 
        xen_unmap_domain_mfn_range(vma, numpgs, pages);
index e3600be4e7fabe54660d5adb1d2f7446b482ff00..18e8bd8fa947994e46b5bd8fb9c09eda29918fa8 100644 (file)
 #include <linux/init.h>
 #include <linux/pagemap.h>
 #include <linux/cleancache.h>
-
-/* temporary ifdef until include/linux/frontswap.h is upstream */
-#ifdef CONFIG_FRONTSWAP
 #include <linux/frontswap.h>
-#endif
 
 #include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 #include <xen/tmem.h>
 
+#ifndef CONFIG_XEN_TMEM_MODULE
+bool __read_mostly tmem_enabled = false;
+
+static int __init enable_tmem(char *s)
+{
+       tmem_enabled = true;
+       return 1;
+}
+__setup("tmem", enable_tmem);
+#endif
+
+#ifdef CONFIG_CLEANCACHE
+static bool cleancache __read_mostly = true;
+module_param(cleancache, bool, S_IRUGO);
+static bool selfballooning __read_mostly = true;
+module_param(selfballooning, bool, S_IRUGO);
+#endif /* CONFIG_CLEANCACHE */
+
+#ifdef CONFIG_FRONTSWAP
+static bool frontswap __read_mostly = true;
+module_param(frontswap, bool, S_IRUGO);
+#endif /* CONFIG_FRONTSWAP */
+
+#ifdef CONFIG_XEN_SELFBALLOONING
+static bool selfshrinking __read_mostly = true;
+module_param(selfshrinking, bool, S_IRUGO);
+#endif /* CONFIG_XEN_SELFBALLOONING */
+
 #define TMEM_CONTROL               0
 #define TMEM_NEW_POOL              1
 #define TMEM_DESTROY_POOL          2
@@ -129,16 +153,6 @@ static int xen_tmem_flush_object(u32 pool_id, struct tmem_oid oid)
        return xen_tmem_op(TMEM_FLUSH_OBJECT, pool_id, oid, 0, 0, 0, 0, 0);
 }
 
-#ifndef CONFIG_XEN_TMEM_MODULE
-bool __read_mostly tmem_enabled = false;
-
-static int __init enable_tmem(char *s)
-{
-       tmem_enabled = true;
-       return 1;
-}
-__setup("tmem", enable_tmem);
-#endif
 
 #ifdef CONFIG_CLEANCACHE
 static int xen_tmem_destroy_pool(u32 pool_id)
@@ -230,20 +244,6 @@ static int tmem_cleancache_init_shared_fs(char *uuid, size_t pagesize)
        return xen_tmem_new_pool(shared_uuid, TMEM_POOL_SHARED, pagesize);
 }
 
-static bool disable_cleancache __read_mostly;
-static bool disable_selfballooning __read_mostly;
-#ifdef CONFIG_XEN_TMEM_MODULE
-module_param(disable_cleancache, bool, S_IRUGO);
-module_param(disable_selfballooning, bool, S_IRUGO);
-#else
-static int __init no_cleancache(char *s)
-{
-       disable_cleancache = true;
-       return 1;
-}
-__setup("nocleancache", no_cleancache);
-#endif
-
 static struct cleancache_ops tmem_cleancache_ops = {
        .put_page = tmem_cleancache_put_page,
        .get_page = tmem_cleancache_get_page,
@@ -361,20 +361,6 @@ static void tmem_frontswap_init(unsigned ignored)
                    xen_tmem_new_pool(private, TMEM_POOL_PERSIST, PAGE_SIZE);
 }
 
-static bool disable_frontswap __read_mostly;
-static bool disable_frontswap_selfshrinking __read_mostly;
-#ifdef CONFIG_XEN_TMEM_MODULE
-module_param(disable_frontswap, bool, S_IRUGO);
-module_param(disable_frontswap_selfshrinking, bool, S_IRUGO);
-#else
-static int __init no_frontswap(char *s)
-{
-       disable_frontswap = true;
-       return 1;
-}
-__setup("nofrontswap", no_frontswap);
-#endif
-
 static struct frontswap_ops tmem_frontswap_ops = {
        .store = tmem_frontswap_store,
        .load = tmem_frontswap_load,
@@ -382,8 +368,6 @@ static struct frontswap_ops tmem_frontswap_ops = {
        .invalidate_area = tmem_frontswap_flush_area,
        .init = tmem_frontswap_init
 };
-#else  /* CONFIG_FRONTSWAP */
-#define disable_frontswap_selfshrinking 1
 #endif
 
 static int xen_tmem_init(void)
@@ -391,7 +375,7 @@ static int xen_tmem_init(void)
        if (!xen_domain())
                return 0;
 #ifdef CONFIG_FRONTSWAP
-       if (tmem_enabled && !disable_frontswap) {
+       if (tmem_enabled && frontswap) {
                char *s = "";
                struct frontswap_ops *old_ops =
                        frontswap_register_ops(&tmem_frontswap_ops);
@@ -408,7 +392,7 @@ static int xen_tmem_init(void)
 #endif
 #ifdef CONFIG_CLEANCACHE
        BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid));
-       if (tmem_enabled && !disable_cleancache) {
+       if (tmem_enabled && cleancache) {
                char *s = "";
                struct cleancache_ops *old_ops =
                        cleancache_register_ops(&tmem_cleancache_ops);
@@ -419,8 +403,15 @@ static int xen_tmem_init(void)
        }
 #endif
 #ifdef CONFIG_XEN_SELFBALLOONING
-       xen_selfballoon_init(!disable_selfballooning,
-                               !disable_frontswap_selfshrinking);
+       /*
+        * There is no point of driving pages to the swap system if they
+        * aren't going anywhere in tmem universe.
+        */
+       if (!frontswap) {
+               selfshrinking = false;
+               selfballooning = false;
+       }
+       xen_selfballoon_init(selfballooning, selfshrinking);
 #endif
        return 0;
 }
index f2ef569c7cc147ad5865a3630eb4913a7164d262..f70984a892aa5c16a0e24deaee28acb2497dc9f6 100644 (file)
  * System configuration note: Selfballooning should not be enabled on
  * systems without a sufficiently large swap device configured; for best
  * results, it is recommended that total swap be increased by the size
- * of the guest memory.  Also, while technically not required to be
- * configured, it is highly recommended that frontswap also be configured
- * and enabled when selfballooning is running.  So, selfballooning
- * is disabled by default if frontswap is not configured and can only
- * be enabled with the "selfballooning" kernel boot option; similarly
- * selfballooning is enabled by default if frontswap is configured and
- * can be disabled with the "noselfballooning" kernel boot option.  Finally,
- * when frontswap is configured, frontswap-selfshrinking can be disabled
- * with the "noselfshrink" kernel boot option.
+ * of the guest memory. Note, that selfballooning should be disabled by default
+ * if frontswap is not configured.  Similarly selfballooning should be enabled
+ * by default if frontswap is configured and can be disabled with the
+ * "tmem.selfballooning=0" kernel boot option.  Finally, when frontswap is
+ * configured, frontswap-selfshrinking can be disabled  with the
+ * "tmem.selfshrink=0" kernel boot option.
  *
  * Selfballooning is disallowed in domain0 and force-disabled.
  *
@@ -120,9 +117,6 @@ static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process);
 /* Enable/disable with sysfs. */
 static bool frontswap_selfshrinking __read_mostly;
 
-/* Enable/disable with kernel boot option. */
-static bool use_frontswap_selfshrink = true;
-
 /*
  * The default values for the following parameters were deemed reasonable
  * by experimentation, may be workload-dependent, and can all be
@@ -176,35 +170,6 @@ static void frontswap_selfshrink(void)
        frontswap_shrink(tgt_frontswap_pages);
 }
 
-static int __init xen_nofrontswap_selfshrink_setup(char *s)
-{
-       use_frontswap_selfshrink = false;
-       return 1;
-}
-
-__setup("noselfshrink", xen_nofrontswap_selfshrink_setup);
-
-/* Disable with kernel boot option. */
-static bool use_selfballooning = true;
-
-static int __init xen_noselfballooning_setup(char *s)
-{
-       use_selfballooning = false;
-       return 1;
-}
-
-__setup("noselfballooning", xen_noselfballooning_setup);
-#else /* !CONFIG_FRONTSWAP */
-/* Enable with kernel boot option. */
-static bool use_selfballooning;
-
-static int __init xen_selfballooning_setup(char *s)
-{
-       use_selfballooning = true;
-       return 1;
-}
-
-__setup("selfballooning", xen_selfballooning_setup);
 #endif /* CONFIG_FRONTSWAP */
 
 #define MB2PAGES(mb)   ((mb) << (20 - PAGE_SHIFT))
index d730008007624b4227780457a96c77f8662c248e..a6f42fc01407e435c477862d380e8a1da55d6656 100644 (file)
@@ -70,22 +70,21 @@ static long xenbus_alloc(domid_t domid)
        return err;
 }
 
-static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, unsigned long data)
+static long xenbus_backend_ioctl(struct file *file, unsigned int cmd,
+                                unsigned long data)
 {
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
        switch (cmd) {
-               case IOCTL_XENBUS_BACKEND_EVTCHN:
-                       if (xen_store_evtchn > 0)
-                               return xen_store_evtchn;
-                       return -ENODEV;
-
-               case IOCTL_XENBUS_BACKEND_SETUP:
-                       return xenbus_alloc(data);
-
-               default:
-                       return -ENOTTY;
+       case IOCTL_XENBUS_BACKEND_EVTCHN:
+               if (xen_store_evtchn > 0)
+                       return xen_store_evtchn;
+               return -ENODEV;
+       case IOCTL_XENBUS_BACKEND_SETUP:
+               return xenbus_alloc(data);
+       default:
+               return -ENOTTY;
        }
 }
 
index b4fb41558111b75d461096d8acdfca34690b8728..290e347b6db3f925f414fd9be4e6ea394da6f887 100644 (file)
@@ -918,7 +918,8 @@ again:
                                                           ref->parent, bsz, 0);
                                if (!eb || !extent_buffer_uptodate(eb)) {
                                        free_extent_buffer(eb);
-                                       return -EIO;
+                                       ret = -EIO;
+                                       goto out;
                                }
                                ret = find_extent_in_eb(eb, bytenr,
                                                        *extent_item_pos, &eie);
index 18af6f48781a1f31e1d41c23bb08a2e1b6ea12a7..1431a696501704d3f9e0901c64de537b2b20183a 100644 (file)
@@ -1700,7 +1700,7 @@ static int btrfsic_read_block(struct btrfsic_state *state,
                unsigned int j;
                DECLARE_COMPLETION_ONSTACK(complete);
 
-               bio = bio_alloc(GFP_NOFS, num_pages - i);
+               bio = btrfs_io_bio_alloc(GFP_NOFS, num_pages - i);
                if (!bio) {
                        printk(KERN_INFO
                               "btrfsic: bio_alloc() for %u pages failed!\n",
index de6de8e60b46019f528b93505d3848adb8699191..02fae7f7e42cb417a14fe0243805bcad4270b592 100644 (file)
@@ -951,10 +951,12 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
                        BUG_ON(ret); /* -ENOMEM */
                }
                if (new_flags != 0) {
+                       int level = btrfs_header_level(buf);
+
                        ret = btrfs_set_disk_extent_flags(trans, root,
                                                          buf->start,
                                                          buf->len,
-                                                         new_flags, 0);
+                                                         new_flags, level, 0);
                        if (ret)
                                return ret;
                }
index 63c328a9ce956c716c8ed6e1a0131b5260bb022b..d6dd49b51ba8dfe27069a139ab42cfd88e58c117 100644 (file)
@@ -88,12 +88,12 @@ struct btrfs_ordered_sum;
 /* holds checksums of all the data extents */
 #define BTRFS_CSUM_TREE_OBJECTID 7ULL
 
-/* for storing balance parameters in the root tree */
-#define BTRFS_BALANCE_OBJECTID -4ULL
-
 /* holds quota configuration and tracking */
 #define BTRFS_QUOTA_TREE_OBJECTID 8ULL
 
+/* for storing balance parameters in the root tree */
+#define BTRFS_BALANCE_OBJECTID -4ULL
+
 /* orhpan objectid for tracking unlinked/truncated files */
 #define BTRFS_ORPHAN_OBJECTID -5ULL
 
@@ -3075,7 +3075,7 @@ int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root,
                                u64 bytenr, u64 num_bytes, u64 flags,
-                               int is_data);
+                               int level, int is_data);
 int btrfs_free_extent(struct btrfs_trans_handle *trans,
                      struct btrfs_root *root,
                      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
index f75fcaf79aebd11d54ebcc6df94d6f5b67c55dfe..70b962cc177d973688b0d2deb56965bffbc423ae 100644 (file)
@@ -60,6 +60,7 @@ struct btrfs_delayed_ref_node {
 struct btrfs_delayed_extent_op {
        struct btrfs_disk_key key;
        u64 flags_to_set;
+       int level;
        unsigned int update_key:1;
        unsigned int update_flags:1;
        unsigned int is_data:1;
index 7ba7b3900cb8eb749b82241cc4533b4fc978ef8a..65241f32d3f8aec282a80d443c7acc677f68726a 100644 (file)
@@ -313,6 +313,11 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
        struct btrfs_device *tgt_device = NULL;
        struct btrfs_device *src_device = NULL;
 
+       if (btrfs_fs_incompat(fs_info, RAID56)) {
+               pr_warn("btrfs: dev_replace cannot yet handle RAID5/RAID6\n");
+               return -EINVAL;
+       }
+
        switch (args->start.cont_reading_from_srcdev_mode) {
        case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS:
        case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID:
index 4e9ebe1f1827895712afdea8e0e8016bd20088ca..e7b3cb5286a5a699c4716a8a5dc2ae6a0e54f622 100644 (file)
@@ -152,7 +152,7 @@ static struct btrfs_lockdep_keyset {
        { .id = BTRFS_DEV_TREE_OBJECTID,        .name_stem = "dev"      },
        { .id = BTRFS_FS_TREE_OBJECTID,         .name_stem = "fs"       },
        { .id = BTRFS_CSUM_TREE_OBJECTID,       .name_stem = "csum"     },
-       { .id = BTRFS_ORPHAN_OBJECTID,          .name_stem = "orphan"   },
+       { .id = BTRFS_QUOTA_TREE_OBJECTID,      .name_stem = "quota"    },
        { .id = BTRFS_TREE_LOG_OBJECTID,        .name_stem = "log"      },
        { .id = BTRFS_TREE_RELOC_OBJECTID,      .name_stem = "treloc"   },
        { .id = BTRFS_DATA_RELOC_TREE_OBJECTID, .name_stem = "dreloc"   },
@@ -1513,7 +1513,6 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
        }
 
        root->commit_root = btrfs_root_node(root);
-       BUG_ON(!root->node); /* -ENOMEM */
 out:
        if (location->objectid != BTRFS_TREE_LOG_OBJECTID) {
                root->ref_cows = 1;
@@ -1988,30 +1987,33 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
 {
        free_extent_buffer(info->tree_root->node);
        free_extent_buffer(info->tree_root->commit_root);
-       free_extent_buffer(info->dev_root->node);
-       free_extent_buffer(info->dev_root->commit_root);
-       free_extent_buffer(info->extent_root->node);
-       free_extent_buffer(info->extent_root->commit_root);
-       free_extent_buffer(info->csum_root->node);
-       free_extent_buffer(info->csum_root->commit_root);
-       if (info->quota_root) {
-               free_extent_buffer(info->quota_root->node);
-               free_extent_buffer(info->quota_root->commit_root);
-       }
-
        info->tree_root->node = NULL;
        info->tree_root->commit_root = NULL;
-       info->dev_root->node = NULL;
-       info->dev_root->commit_root = NULL;
-       info->extent_root->node = NULL;
-       info->extent_root->commit_root = NULL;
-       info->csum_root->node = NULL;
-       info->csum_root->commit_root = NULL;
+
+       if (info->dev_root) {
+               free_extent_buffer(info->dev_root->node);
+               free_extent_buffer(info->dev_root->commit_root);
+               info->dev_root->node = NULL;
+               info->dev_root->commit_root = NULL;
+       }
+       if (info->extent_root) {
+               free_extent_buffer(info->extent_root->node);
+               free_extent_buffer(info->extent_root->commit_root);
+               info->extent_root->node = NULL;
+               info->extent_root->commit_root = NULL;
+       }
+       if (info->csum_root) {
+               free_extent_buffer(info->csum_root->node);
+               free_extent_buffer(info->csum_root->commit_root);
+               info->csum_root->node = NULL;
+               info->csum_root->commit_root = NULL;
+       }
        if (info->quota_root) {
+               free_extent_buffer(info->quota_root->node);
+               free_extent_buffer(info->quota_root->commit_root);
                info->quota_root->node = NULL;
                info->quota_root->commit_root = NULL;
        }
-
        if (chunk_root) {
                free_extent_buffer(info->chunk_root->node);
                free_extent_buffer(info->chunk_root->commit_root);
@@ -3128,7 +3130,7 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
         * caller
         */
        device->flush_bio = NULL;
-       bio = bio_alloc(GFP_NOFS, 0);
+       bio = btrfs_io_bio_alloc(GFP_NOFS, 0);
        if (!bio)
                return -ENOMEM;
 
@@ -3659,8 +3661,11 @@ static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t,
                                         ordered_operations);
 
                list_del_init(&btrfs_inode->ordered_operations);
+               spin_unlock(&root->fs_info->ordered_extent_lock);
 
                btrfs_invalidate_inodes(btrfs_inode->root);
+
+               spin_lock(&root->fs_info->ordered_extent_lock);
        }
 
        spin_unlock(&root->fs_info->ordered_extent_lock);
@@ -3782,8 +3787,11 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root)
                list_del_init(&btrfs_inode->delalloc_inodes);
                clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
                          &btrfs_inode->runtime_flags);
+               spin_unlock(&root->fs_info->delalloc_lock);
 
                btrfs_invalidate_inodes(btrfs_inode->root);
+
+               spin_lock(&root->fs_info->delalloc_lock);
        }
 
        spin_unlock(&root->fs_info->delalloc_lock);
@@ -3808,7 +3816,7 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root,
                while (start <= end) {
                        eb = btrfs_find_tree_block(root, start,
                                                   root->leafsize);
-                       start += eb->len;
+                       start += root->leafsize;
                        if (!eb)
                                continue;
                        wait_on_extent_buffer_writeback(eb);
index 2305b5c5cf0012d77de5dde14721ddc1cc0ccc5c..df472ab1b5acca7b411b05bcc414913bcebcc244 100644 (file)
@@ -2070,8 +2070,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
        u32 item_size;
        int ret;
        int err = 0;
-       int metadata = (node->type == BTRFS_TREE_BLOCK_REF_KEY ||
-                       node->type == BTRFS_SHARED_BLOCK_REF_KEY);
+       int metadata = !extent_op->is_data;
 
        if (trans->aborted)
                return 0;
@@ -2086,11 +2085,8 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
        key.objectid = node->bytenr;
 
        if (metadata) {
-               struct btrfs_delayed_tree_ref *tree_ref;
-
-               tree_ref = btrfs_delayed_node_to_tree_ref(node);
                key.type = BTRFS_METADATA_ITEM_KEY;
-               key.offset = tree_ref->level;
+               key.offset = extent_op->level;
        } else {
                key.type = BTRFS_EXTENT_ITEM_KEY;
                key.offset = node->num_bytes;
@@ -2719,7 +2715,7 @@ out:
 int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root,
                                u64 bytenr, u64 num_bytes, u64 flags,
-                               int is_data)
+                               int level, int is_data)
 {
        struct btrfs_delayed_extent_op *extent_op;
        int ret;
@@ -2732,6 +2728,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
        extent_op->update_flags = 1;
        extent_op->update_key = 0;
        extent_op->is_data = is_data ? 1 : 0;
+       extent_op->level = level;
 
        ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr,
                                          num_bytes, extent_op);
@@ -3109,6 +3106,11 @@ again:
        WARN_ON(ret);
 
        if (i_size_read(inode) > 0) {
+               ret = btrfs_check_trunc_cache_free_space(root,
+                                       &root->fs_info->global_block_rsv);
+               if (ret)
+                       goto out_put;
+
                ret = btrfs_truncate_free_space_cache(root, trans, path,
                                                      inode);
                if (ret)
@@ -4562,6 +4564,8 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info)
        fs_info->csum_root->block_rsv = &fs_info->global_block_rsv;
        fs_info->dev_root->block_rsv = &fs_info->global_block_rsv;
        fs_info->tree_root->block_rsv = &fs_info->global_block_rsv;
+       if (fs_info->quota_root)
+               fs_info->quota_root->block_rsv = &fs_info->global_block_rsv;
        fs_info->chunk_root->block_rsv = &fs_info->chunk_block_rsv;
 
        update_global_block_rsv(fs_info);
@@ -6651,51 +6655,51 @@ use_block_rsv(struct btrfs_trans_handle *trans,
        struct btrfs_block_rsv *block_rsv;
        struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
        int ret;
+       bool global_updated = false;
 
        block_rsv = get_block_rsv(trans, root);
 
-       if (block_rsv->size == 0) {
-               ret = reserve_metadata_bytes(root, block_rsv, blocksize,
-                                            BTRFS_RESERVE_NO_FLUSH);
-               /*
-                * If we couldn't reserve metadata bytes try and use some from
-                * the global reserve.
-                */
-               if (ret && block_rsv != global_rsv) {
-                       ret = block_rsv_use_bytes(global_rsv, blocksize);
-                       if (!ret)
-                               return global_rsv;
-                       return ERR_PTR(ret);
-               } else if (ret) {
-                       return ERR_PTR(ret);
-               }
+       if (unlikely(block_rsv->size == 0))
+               goto try_reserve;
+again:
+       ret = block_rsv_use_bytes(block_rsv, blocksize);
+       if (!ret)
                return block_rsv;
+
+       if (block_rsv->failfast)
+               return ERR_PTR(ret);
+
+       if (block_rsv->type == BTRFS_BLOCK_RSV_GLOBAL && !global_updated) {
+               global_updated = true;
+               update_global_block_rsv(root->fs_info);
+               goto again;
        }
 
-       ret = block_rsv_use_bytes(block_rsv, blocksize);
+       if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
+               static DEFINE_RATELIMIT_STATE(_rs,
+                               DEFAULT_RATELIMIT_INTERVAL * 10,
+                               /*DEFAULT_RATELIMIT_BURST*/ 1);
+               if (__ratelimit(&_rs))
+                       WARN(1, KERN_DEBUG
+                               "btrfs: block rsv returned %d\n", ret);
+       }
+try_reserve:
+       ret = reserve_metadata_bytes(root, block_rsv, blocksize,
+                                    BTRFS_RESERVE_NO_FLUSH);
        if (!ret)
                return block_rsv;
-       if (ret && !block_rsv->failfast) {
-               if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
-                       static DEFINE_RATELIMIT_STATE(_rs,
-                                       DEFAULT_RATELIMIT_INTERVAL * 10,
-                                       /*DEFAULT_RATELIMIT_BURST*/ 1);
-                       if (__ratelimit(&_rs))
-                               WARN(1, KERN_DEBUG
-                                       "btrfs: block rsv returned %d\n", ret);
-               }
-               ret = reserve_metadata_bytes(root, block_rsv, blocksize,
-                                            BTRFS_RESERVE_NO_FLUSH);
-               if (!ret) {
-                       return block_rsv;
-               } else if (ret && block_rsv != global_rsv) {
-                       ret = block_rsv_use_bytes(global_rsv, blocksize);
-                       if (!ret)
-                               return global_rsv;
-               }
+       /*
+        * If we couldn't reserve metadata bytes try and use some from
+        * the global reserve if its space type is the same as the global
+        * reservation.
+        */
+       if (block_rsv->type != BTRFS_BLOCK_RSV_GLOBAL &&
+           block_rsv->space_info == global_rsv->space_info) {
+               ret = block_rsv_use_bytes(global_rsv, blocksize);
+               if (!ret)
+                       return global_rsv;
        }
-
-       return ERR_PTR(-ENOSPC);
+       return ERR_PTR(ret);
 }
 
 static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
@@ -6763,6 +6767,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
                        extent_op->update_key = 1;
                extent_op->update_flags = 1;
                extent_op->is_data = 0;
+               extent_op->level = level;
 
                ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
                                        ins.objectid,
@@ -6934,7 +6939,8 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
                ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc);
                BUG_ON(ret); /* -ENOMEM */
                ret = btrfs_set_disk_extent_flags(trans, root, eb->start,
-                                                 eb->len, flag, 0);
+                                                 eb->len, flag,
+                                                 btrfs_header_level(eb), 0);
                BUG_ON(ret); /* -ENOMEM */
                wc->flags[level] |= flag;
        }
index 32d67a822e93c0cf53f5c0409bd73ff863bf90bc..e7e7afb4a87268211e8b0ef881a6eeac0068eefd 100644 (file)
@@ -23,6 +23,7 @@
 
 static struct kmem_cache *extent_state_cache;
 static struct kmem_cache *extent_buffer_cache;
+static struct bio_set *btrfs_bioset;
 
 #ifdef CONFIG_BTRFS_DEBUG
 static LIST_HEAD(buffers);
@@ -125,10 +126,20 @@ int __init extent_io_init(void)
                        SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
        if (!extent_buffer_cache)
                goto free_state_cache;
+
+       btrfs_bioset = bioset_create(BIO_POOL_SIZE,
+                                    offsetof(struct btrfs_io_bio, bio));
+       if (!btrfs_bioset)
+               goto free_buffer_cache;
        return 0;
 
+free_buffer_cache:
+       kmem_cache_destroy(extent_buffer_cache);
+       extent_buffer_cache = NULL;
+
 free_state_cache:
        kmem_cache_destroy(extent_state_cache);
+       extent_state_cache = NULL;
        return -ENOMEM;
 }
 
@@ -145,6 +156,8 @@ void extent_io_exit(void)
                kmem_cache_destroy(extent_state_cache);
        if (extent_buffer_cache)
                kmem_cache_destroy(extent_buffer_cache);
+       if (btrfs_bioset)
+               bioset_free(btrfs_bioset);
 }
 
 void extent_io_tree_init(struct extent_io_tree *tree,
@@ -1947,28 +1960,6 @@ static void check_page_uptodate(struct extent_io_tree *tree, struct page *page)
                SetPageUptodate(page);
 }
 
-/*
- * helper function to unlock a page if all the extents in the tree
- * for that page are unlocked
- */
-static void check_page_locked(struct extent_io_tree *tree, struct page *page)
-{
-       u64 start = page_offset(page);
-       u64 end = start + PAGE_CACHE_SIZE - 1;
-       if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL))
-               unlock_page(page);
-}
-
-/*
- * helper function to end page writeback if all the extents
- * in the tree for that page are done with writeback
- */
-static void check_page_writeback(struct extent_io_tree *tree,
-                                struct page *page)
-{
-       end_page_writeback(page);
-}
-
 /*
  * When IO fails, either with EIO or csum verification fails, we
  * try other mirrors that might have a good copy of the data.  This
@@ -2046,7 +2037,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start,
        if (btrfs_is_parity_mirror(map_tree, logical, length, mirror_num))
                return 0;
 
-       bio = bio_alloc(GFP_NOFS, 1);
+       bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
        if (!bio)
                return -EIO;
        bio->bi_private = &compl;
@@ -2336,7 +2327,7 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
                return -EIO;
        }
 
-       bio = bio_alloc(GFP_NOFS, 1);
+       bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
        if (!bio) {
                free_io_failure(inode, failrec, 0);
                return -EIO;
@@ -2398,19 +2389,24 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
        struct extent_io_tree *tree;
        u64 start;
        u64 end;
-       int whole_page;
 
        do {
                struct page *page = bvec->bv_page;
                tree = &BTRFS_I(page->mapping->host)->io_tree;
 
-               start = page_offset(page) + bvec->bv_offset;
-               end = start + bvec->bv_len - 1;
+               /* We always issue full-page reads, but if some block
+                * in a page fails to read, blk_update_request() will
+                * advance bv_offset and adjust bv_len to compensate.
+                * Print a warning for nonzero offsets, and an error
+                * if they don't add up to a full page.  */
+               if (bvec->bv_offset || bvec->bv_len != PAGE_CACHE_SIZE)
+                       printk("%s page write in btrfs with offset %u and length %u\n",
+                              bvec->bv_offset + bvec->bv_len != PAGE_CACHE_SIZE
+                              ? KERN_ERR "partial" : KERN_INFO "incomplete",
+                              bvec->bv_offset, bvec->bv_len);
 
-               if (bvec->bv_offset == 0 && bvec->bv_len == PAGE_CACHE_SIZE)
-                       whole_page = 1;
-               else
-                       whole_page = 0;
+               start = page_offset(page);
+               end = start + bvec->bv_offset + bvec->bv_len - 1;
 
                if (--bvec >= bio->bi_io_vec)
                        prefetchw(&bvec->bv_page->flags);
@@ -2418,10 +2414,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
                if (end_extent_writepage(page, err, start, end))
                        continue;
 
-               if (whole_page)
-                       end_page_writeback(page);
-               else
-                       check_page_writeback(tree, page);
+               end_page_writeback(page);
        } while (bvec >= bio->bi_io_vec);
 
        bio_put(bio);
@@ -2446,7 +2439,6 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
        struct extent_io_tree *tree;
        u64 start;
        u64 end;
-       int whole_page;
        int mirror;
        int ret;
 
@@ -2457,19 +2449,26 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                struct page *page = bvec->bv_page;
                struct extent_state *cached = NULL;
                struct extent_state *state;
+               struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
 
                pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
-                        "mirror=%ld\n", (u64)bio->bi_sector, err,
-                        (long int)bio->bi_bdev);
+                        "mirror=%lu\n", (u64)bio->bi_sector, err,
+                        io_bio->mirror_num);
                tree = &BTRFS_I(page->mapping->host)->io_tree;
 
-               start = page_offset(page) + bvec->bv_offset;
-               end = start + bvec->bv_len - 1;
+               /* We always issue full-page reads, but if some block
+                * in a page fails to read, blk_update_request() will
+                * advance bv_offset and adjust bv_len to compensate.
+                * Print a warning for nonzero offsets, and an error
+                * if they don't add up to a full page.  */
+               if (bvec->bv_offset || bvec->bv_len != PAGE_CACHE_SIZE)
+                       printk("%s page read in btrfs with offset %u and length %u\n",
+                              bvec->bv_offset + bvec->bv_len != PAGE_CACHE_SIZE
+                              ? KERN_ERR "partial" : KERN_INFO "incomplete",
+                              bvec->bv_offset, bvec->bv_len);
 
-               if (bvec->bv_offset == 0 && bvec->bv_len == PAGE_CACHE_SIZE)
-                       whole_page = 1;
-               else
-                       whole_page = 0;
+               start = page_offset(page);
+               end = start + bvec->bv_offset + bvec->bv_len - 1;
 
                if (++bvec <= bvec_end)
                        prefetchw(&bvec->bv_page->flags);
@@ -2485,7 +2484,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                }
                spin_unlock(&tree->lock);
 
-               mirror = (int)(unsigned long)bio->bi_bdev;
+               mirror = io_bio->mirror_num;
                if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {
                        ret = tree->ops->readpage_end_io_hook(page, start, end,
                                                              state, mirror);
@@ -2528,39 +2527,35 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                }
                unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC);
 
-               if (whole_page) {
-                       if (uptodate) {
-                               SetPageUptodate(page);
-                       } else {
-                               ClearPageUptodate(page);
-                               SetPageError(page);
-                       }
-                       unlock_page(page);
+               if (uptodate) {
+                       SetPageUptodate(page);
                } else {
-                       if (uptodate) {
-                               check_page_uptodate(tree, page);
-                       } else {
-                               ClearPageUptodate(page);
-                               SetPageError(page);
-                       }
-                       check_page_locked(tree, page);
+                       ClearPageUptodate(page);
+                       SetPageError(page);
                }
+               unlock_page(page);
        } while (bvec <= bvec_end);
 
        bio_put(bio);
 }
 
+/*
+ * this allocates from the btrfs_bioset.  We're returning a bio right now
+ * but you can call btrfs_io_bio for the appropriate container_of magic
+ */
 struct bio *
 btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
                gfp_t gfp_flags)
 {
        struct bio *bio;
 
-       bio = bio_alloc(gfp_flags, nr_vecs);
+       bio = bio_alloc_bioset(gfp_flags, nr_vecs, btrfs_bioset);
 
        if (bio == NULL && (current->flags & PF_MEMALLOC)) {
-               while (!bio && (nr_vecs /= 2))
-                       bio = bio_alloc(gfp_flags, nr_vecs);
+               while (!bio && (nr_vecs /= 2)) {
+                       bio = bio_alloc_bioset(gfp_flags,
+                                              nr_vecs, btrfs_bioset);
+               }
        }
 
        if (bio) {
@@ -2571,6 +2566,19 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
        return bio;
 }
 
+struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask)
+{
+       return bio_clone_bioset(bio, gfp_mask, btrfs_bioset);
+}
+
+
+/* this also allocates from the btrfs_bioset */
+struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
+{
+       return bio_alloc_bioset(gfp_mask, nr_iovecs, btrfs_bioset);
+}
+
+
 static int __must_check submit_one_bio(int rw, struct bio *bio,
                                       int mirror_num, unsigned long bio_flags)
 {
@@ -3988,7 +3996,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                last_for_get_extent = isize;
        }
 
-       lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
+       lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len - 1, 0,
                         &cached_state);
 
        em = get_extent_skip_holes(inode, start, last_for_get_extent,
@@ -4075,7 +4083,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 out_free:
        free_extent_map(em);
 out:
-       unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len,
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1,
                             &cached_state, GFP_NOFS);
        return ret;
 }
index a2c03a17500971f131b8a43051b1269e86bfc0af..41fb81e7ec53c3fda80caf28a039af7b4c1a0682 100644 (file)
@@ -336,6 +336,8 @@ int extent_clear_unlock_delalloc(struct inode *inode,
 struct bio *
 btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
                gfp_t gfp_flags);
+struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs);
+struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask);
 
 struct btrfs_fs_info;
 
index ecca6c7375a610dbee385a71781cece9082935e0..e53009657f0e5b91b638f3d31d5e4d2cbf919f62 100644 (file)
@@ -197,30 +197,32 @@ int create_free_space_inode(struct btrfs_root *root,
                                         block_group->key.objectid);
 }
 
-int btrfs_truncate_free_space_cache(struct btrfs_root *root,
-                                   struct btrfs_trans_handle *trans,
-                                   struct btrfs_path *path,
-                                   struct inode *inode)
+int btrfs_check_trunc_cache_free_space(struct btrfs_root *root,
+                                      struct btrfs_block_rsv *rsv)
 {
-       struct btrfs_block_rsv *rsv;
        u64 needed_bytes;
-       loff_t oldsize;
-       int ret = 0;
-
-       rsv = trans->block_rsv;
-       trans->block_rsv = &root->fs_info->global_block_rsv;
+       int ret;
 
        /* 1 for slack space, 1 for updating the inode */
        needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) +
                btrfs_calc_trans_metadata_size(root, 1);
 
-       spin_lock(&trans->block_rsv->lock);
-       if (trans->block_rsv->reserved < needed_bytes) {
-               spin_unlock(&trans->block_rsv->lock);
-               trans->block_rsv = rsv;
-               return -ENOSPC;
-       }
-       spin_unlock(&trans->block_rsv->lock);
+       spin_lock(&rsv->lock);
+       if (rsv->reserved < needed_bytes)
+               ret = -ENOSPC;
+       else
+               ret = 0;
+       spin_unlock(&rsv->lock);
+       return 0;
+}
+
+int btrfs_truncate_free_space_cache(struct btrfs_root *root,
+                                   struct btrfs_trans_handle *trans,
+                                   struct btrfs_path *path,
+                                   struct inode *inode)
+{
+       loff_t oldsize;
+       int ret = 0;
 
        oldsize = i_size_read(inode);
        btrfs_i_size_write(inode, 0);
@@ -232,9 +234,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
         */
        ret = btrfs_truncate_inode_items(trans, root, inode,
                                         0, BTRFS_EXTENT_DATA_KEY);
-
        if (ret) {
-               trans->block_rsv = rsv;
                btrfs_abort_transaction(trans, root, ret);
                return ret;
        }
@@ -242,7 +242,6 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
        ret = btrfs_update_inode(trans, root, inode);
        if (ret)
                btrfs_abort_transaction(trans, root, ret);
-       trans->block_rsv = rsv;
 
        return ret;
 }
@@ -920,10 +919,8 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
 
        /* Make sure we can fit our crcs into the first page */
        if (io_ctl.check_crcs &&
-           (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) {
-               WARN_ON(1);
+           (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE)
                goto out_nospc;
-       }
 
        io_ctl_set_generation(&io_ctl, trans->transid);
 
index 4dc17d8809c76d25cddb635e29bd8309b340f464..8b7f19f4496153886975547923cdcdc815940e96 100644 (file)
@@ -54,6 +54,8 @@ int create_free_space_inode(struct btrfs_root *root,
                            struct btrfs_block_group_cache *block_group,
                            struct btrfs_path *path);
 
+int btrfs_check_trunc_cache_free_space(struct btrfs_root *root,
+                                      struct btrfs_block_rsv *rsv);
 int btrfs_truncate_free_space_cache(struct btrfs_root *root,
                                    struct btrfs_trans_handle *trans,
                                    struct btrfs_path *path,
index d26f67a59e36f9caf3e91832fa1d4c943c8c9040..2c66ddbbe670e0ab80753dc41eb4054aacd00388 100644 (file)
@@ -429,11 +429,12 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
        num_bytes = trans->bytes_reserved;
        /*
         * 1 item for inode item insertion if need
-        * 3 items for inode item update (in the worst case)
+        * 4 items for inode item update (in the worst case)
+        * 1 items for slack space if we need do truncation
         * 1 item for free space object
         * 3 items for pre-allocation
         */
-       trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 8);
+       trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 10);
        ret = btrfs_block_rsv_add(root, trans->block_rsv,
                                  trans->bytes_reserved,
                                  BTRFS_RESERVE_NO_FLUSH);
@@ -468,7 +469,8 @@ again:
        if (i_size_read(inode) > 0) {
                ret = btrfs_truncate_free_space_cache(root, trans, path, inode);
                if (ret) {
-                       btrfs_abort_transaction(trans, root, ret);
+                       if (ret != -ENOSPC)
+                               btrfs_abort_transaction(trans, root, ret);
                        goto out_put;
                }
        }
index 9b31b3b091fceb6536612b30e64f2fd191d47e89..af978f7682b3441282b0f54e62a60b7534d51203 100644 (file)
@@ -715,8 +715,10 @@ retry:
                                        async_extent->ram_size - 1, 0);
 
                em = alloc_extent_map();
-               if (!em)
+               if (!em) {
+                       ret = -ENOMEM;
                        goto out_free_reserve;
+               }
                em->start = async_extent->start;
                em->len = async_extent->ram_size;
                em->orig_start = em->start;
@@ -923,8 +925,10 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
                }
 
                em = alloc_extent_map();
-               if (!em)
+               if (!em) {
+                       ret = -ENOMEM;
                        goto out_reserve;
+               }
                em->start = start;
                em->orig_start = em->start;
                ram_size = ins.offset;
@@ -4724,6 +4728,7 @@ void btrfs_evict_inode(struct inode *inode)
        btrfs_end_transaction(trans, root);
        btrfs_btree_balance_dirty(root);
 no_delete:
+       btrfs_remove_delayed_node(inode);
        clear_inode(inode);
        return;
 }
@@ -4839,14 +4844,13 @@ static void inode_tree_add(struct inode *inode)
        struct rb_node **p;
        struct rb_node *parent;
        u64 ino = btrfs_ino(inode);
-again:
-       p = &root->inode_tree.rb_node;
-       parent = NULL;
 
        if (inode_unhashed(inode))
                return;
-
+again:
+       parent = NULL;
        spin_lock(&root->inode_lock);
+       p = &root->inode_tree.rb_node;
        while (*p) {
                parent = *p;
                entry = rb_entry(parent, struct btrfs_inode, rb_node);
@@ -6928,7 +6932,11 @@ struct btrfs_dio_private {
        /* IO errors */
        int errors;
 
+       /* orig_bio is our btrfs_io_bio */
        struct bio *orig_bio;
+
+       /* dio_bio came from fs/direct-io.c */
+       struct bio *dio_bio;
 };
 
 static void btrfs_endio_direct_read(struct bio *bio, int err)
@@ -6938,6 +6946,7 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
        struct bio_vec *bvec = bio->bi_io_vec;
        struct inode *inode = dip->inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct bio *dio_bio;
        u64 start;
 
        start = dip->logical_offset;
@@ -6977,14 +6986,15 @@ failed:
 
        unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
                      dip->logical_offset + dip->bytes - 1);
-       bio->bi_private = dip->private;
+       dio_bio = dip->dio_bio;
 
        kfree(dip);
 
        /* If we had a csum failure make sure to clear the uptodate flag */
        if (err)
-               clear_bit(BIO_UPTODATE, &bio->bi_flags);
-       dio_end_io(bio, err);
+               clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
+       dio_end_io(dio_bio, err);
+       bio_put(bio);
 }
 
 static void btrfs_endio_direct_write(struct bio *bio, int err)
@@ -6995,6 +7005,7 @@ static void btrfs_endio_direct_write(struct bio *bio, int err)
        struct btrfs_ordered_extent *ordered = NULL;
        u64 ordered_offset = dip->logical_offset;
        u64 ordered_bytes = dip->bytes;
+       struct bio *dio_bio;
        int ret;
 
        if (err)
@@ -7022,14 +7033,15 @@ out_test:
                goto again;
        }
 out_done:
-       bio->bi_private = dip->private;
+       dio_bio = dip->dio_bio;
 
        kfree(dip);
 
        /* If we had an error make sure to clear the uptodate flag */
        if (err)
-               clear_bit(BIO_UPTODATE, &bio->bi_flags);
-       dio_end_io(bio, err);
+               clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
+       dio_end_io(dio_bio, err);
+       bio_put(bio);
 }
 
 static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw,
@@ -7065,10 +7077,10 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
        if (!atomic_dec_and_test(&dip->pending_bios))
                goto out;
 
-       if (dip->errors)
+       if (dip->errors) {
                bio_io_error(dip->orig_bio);
-       else {
-               set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags);
+       else {
+               set_bit(BIO_UPTODATE, &dip->dio_bio->bi_flags);
                bio_endio(dip->orig_bio, 0);
        }
 out:
@@ -7243,25 +7255,34 @@ out_err:
        return 0;
 }
 
-static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
-                               loff_t file_offset)
+static void btrfs_submit_direct(int rw, struct bio *dio_bio,
+                               struct inode *inode, loff_t file_offset)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_dio_private *dip;
-       struct bio_vec *bvec = bio->bi_io_vec;
+       struct bio_vec *bvec = dio_bio->bi_io_vec;
+       struct bio *io_bio;
        int skip_sum;
        int write = rw & REQ_WRITE;
        int ret = 0;
 
        skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
 
+       io_bio = btrfs_bio_clone(dio_bio, GFP_NOFS);
+
+       if (!io_bio) {
+               ret = -ENOMEM;
+               goto free_ordered;
+       }
+
        dip = kmalloc(sizeof(*dip), GFP_NOFS);
        if (!dip) {
                ret = -ENOMEM;
-               goto free_ordered;
+               goto free_io_bio;
        }
 
-       dip->private = bio->bi_private;
+       dip->private = dio_bio->bi_private;
+       io_bio->bi_private = dio_bio->bi_private;
        dip->inode = inode;
        dip->logical_offset = file_offset;
 
@@ -7269,22 +7290,27 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
        do {
                dip->bytes += bvec->bv_len;
                bvec++;
-       } while (bvec <= (bio->bi_io_vec + bio->bi_vcnt - 1));
+       } while (bvec <= (dio_bio->bi_io_vec + dio_bio->bi_vcnt - 1));
 
-       dip->disk_bytenr = (u64)bio->bi_sector << 9;
-       bio->bi_private = dip;
+       dip->disk_bytenr = (u64)dio_bio->bi_sector << 9;
+       io_bio->bi_private = dip;
        dip->errors = 0;
-       dip->orig_bio = bio;
+       dip->orig_bio = io_bio;
+       dip->dio_bio = dio_bio;
        atomic_set(&dip->pending_bios, 0);
 
        if (write)
-               bio->bi_end_io = btrfs_endio_direct_write;
+               io_bio->bi_end_io = btrfs_endio_direct_write;
        else
-               bio->bi_end_io = btrfs_endio_direct_read;
+               io_bio->bi_end_io = btrfs_endio_direct_read;
 
        ret = btrfs_submit_direct_hook(rw, dip, skip_sum);
        if (!ret)
                return;
+
+free_io_bio:
+       bio_put(io_bio);
+
 free_ordered:
        /*
         * If this is a write, we need to clean up the reserved space and kill
@@ -7300,7 +7326,7 @@ free_ordered:
                btrfs_put_ordered_extent(ordered);
                btrfs_put_ordered_extent(ordered);
        }
-       bio_endio(bio, ret);
+       bio_endio(dio_bio, ret);
 }
 
 static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb,
@@ -7979,7 +8005,6 @@ void btrfs_destroy_inode(struct inode *inode)
        inode_tree_del(inode);
        btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
 free:
-       btrfs_remove_delayed_node(inode);
        call_rcu(&inode->i_rcu, btrfs_i_callback);
 }
 
index 0de4a2fcfb24f1cdd2e8ae9574405bd4ce247526..0f81d67cdc8da651890df1a89c01df9188667d97 100644 (file)
@@ -1801,7 +1801,11 @@ static noinline int copy_to_sk(struct btrfs_root *root,
                item_off = btrfs_item_ptr_offset(leaf, i);
                item_len = btrfs_item_size_nr(leaf, i);
 
-               if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE)
+               btrfs_item_key_to_cpu(leaf, key, i);
+               if (!key_in_sk(key, sk))
+                       continue;
+
+               if (sizeof(sh) + item_len > BTRFS_SEARCH_ARGS_BUFSIZE)
                        item_len = 0;
 
                if (sizeof(sh) + item_len + *sk_offset >
@@ -1810,10 +1814,6 @@ static noinline int copy_to_sk(struct btrfs_root *root,
                        goto overflow;
                }
 
-               btrfs_item_key_to_cpu(leaf, key, i);
-               if (!key_in_sk(key, sk))
-                       continue;
-
                sh.objectid = key->objectid;
                sh.offset = key->offset;
                sh.type = key->type;
index 0740621daf6ca370498e78688922347c54e172df..0525e1389f5b16658ccea028da6408da812c974b 100644 (file)
@@ -1050,7 +1050,7 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
        }
 
        /* put a new bio on the list */
-       bio = bio_alloc(GFP_NOFS, bio_max_len >> PAGE_SHIFT?:1);
+       bio = btrfs_io_bio_alloc(GFP_NOFS, bio_max_len >> PAGE_SHIFT?:1);
        if (!bio)
                return -ENOMEM;
 
index 704a1b8d2a2bae870fcf678d27aa4601f6745011..395b82031a4286f2a8a1481bc87a684172468b96 100644 (file)
@@ -1773,7 +1773,7 @@ again:
                        if (!eb || !extent_buffer_uptodate(eb)) {
                                ret = (!eb) ? -ENOMEM : -EIO;
                                free_extent_buffer(eb);
-                               return ret;
+                               break;
                        }
                        btrfs_tree_lock(eb);
                        if (cow) {
@@ -3350,6 +3350,11 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info,
        }
 
 truncate:
+       ret = btrfs_check_trunc_cache_free_space(root,
+                                                &fs_info->global_block_rsv);
+       if (ret)
+               goto out;
+
        path = btrfs_alloc_path();
        if (!path) {
                ret = -ENOMEM;
index f489e24659a434fa2b67984a5a8a7cf9df2b06b6..79bd479317cb53cbea30a7021d81a891ed9ae20c 100644 (file)
@@ -1296,7 +1296,7 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
                }
 
                WARN_ON(!page->page);
-               bio = bio_alloc(GFP_NOFS, 1);
+               bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
                if (!bio) {
                        page->io_error = 1;
                        sblock->no_io_error_seen = 0;
@@ -1431,7 +1431,7 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
                        return -EIO;
                }
 
-               bio = bio_alloc(GFP_NOFS, 1);
+               bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
                if (!bio)
                        return -EIO;
                bio->bi_bdev = page_bad->dev->bdev;
@@ -1522,7 +1522,7 @@ again:
                sbio->dev = wr_ctx->tgtdev;
                bio = sbio->bio;
                if (!bio) {
-                       bio = bio_alloc(GFP_NOFS, wr_ctx->pages_per_wr_bio);
+                       bio = btrfs_io_bio_alloc(GFP_NOFS, wr_ctx->pages_per_wr_bio);
                        if (!bio) {
                                mutex_unlock(&wr_ctx->wr_lock);
                                return -ENOMEM;
@@ -1930,7 +1930,7 @@ again:
                sbio->dev = spage->dev;
                bio = sbio->bio;
                if (!bio) {
-                       bio = bio_alloc(GFP_NOFS, sctx->pages_per_rd_bio);
+                       bio = btrfs_io_bio_alloc(GFP_NOFS, sctx->pages_per_rd_bio);
                        if (!bio)
                                return -ENOMEM;
                        sbio->bio = bio;
@@ -3307,7 +3307,7 @@ static int write_page_nocow(struct scrub_ctx *sctx,
                        "btrfs: scrub write_page_nocow(bdev == NULL) is unexpected!\n");
                return -EIO;
        }
-       bio = bio_alloc(GFP_NOFS, 1);
+       bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
        if (!bio) {
                spin_lock(&sctx->stat_lock);
                sctx->stat.malloc_errors++;
index a4807ced23cc5791d500d28ee9f91fdc915f5df0..f0857e092a3cb1af485604850052440579a1bbf1 100644 (file)
@@ -1263,6 +1263,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 
                btrfs_dev_replace_suspend_for_unmount(fs_info);
                btrfs_scrub_cancel(fs_info);
+               btrfs_pause_balance(fs_info);
 
                ret = btrfs_commit_super(root);
                if (ret)
index 0e925ced971ba87bc0e356c6a2c7e3dbf1b5e91e..8bffb9174afba04d8375b96f754256b68ff9b4ef 100644 (file)
@@ -3120,14 +3120,13 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
        allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE;
        if (num_devices == 1)
                allowed |= BTRFS_BLOCK_GROUP_DUP;
-       else if (num_devices < 4)
+       else if (num_devices > 1)
                allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1);
-       else
-               allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
-                               BTRFS_BLOCK_GROUP_RAID10 |
-                               BTRFS_BLOCK_GROUP_RAID5 |
-                               BTRFS_BLOCK_GROUP_RAID6);
-
+       if (num_devices > 2)
+               allowed |= BTRFS_BLOCK_GROUP_RAID5;
+       if (num_devices > 3)
+               allowed |= (BTRFS_BLOCK_GROUP_RAID10 |
+                           BTRFS_BLOCK_GROUP_RAID6);
        if ((bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
            (!alloc_profile_is_valid(bctl->data.target, 1) ||
             (bctl->data.target & ~allowed))) {
@@ -5019,42 +5018,16 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
        return 0;
 }
 
-static void *merge_stripe_index_into_bio_private(void *bi_private,
-                                                unsigned int stripe_index)
-{
-       /*
-        * with single, dup, RAID0, RAID1 and RAID10, stripe_index is
-        * at most 1.
-        * The alternative solution (instead of stealing bits from the
-        * pointer) would be to allocate an intermediate structure
-        * that contains the old private pointer plus the stripe_index.
-        */
-       BUG_ON((((uintptr_t)bi_private) & 3) != 0);
-       BUG_ON(stripe_index > 3);
-       return (void *)(((uintptr_t)bi_private) | stripe_index);
-}
-
-static struct btrfs_bio *extract_bbio_from_bio_private(void *bi_private)
-{
-       return (struct btrfs_bio *)(((uintptr_t)bi_private) & ~((uintptr_t)3));
-}
-
-static unsigned int extract_stripe_index_from_bio_private(void *bi_private)
-{
-       return (unsigned int)((uintptr_t)bi_private) & 3;
-}
-
 static void btrfs_end_bio(struct bio *bio, int err)
 {
-       struct btrfs_bio *bbio = extract_bbio_from_bio_private(bio->bi_private);
+       struct btrfs_bio *bbio = bio->bi_private;
        int is_orig_bio = 0;
 
        if (err) {
                atomic_inc(&bbio->error);
                if (err == -EIO || err == -EREMOTEIO) {
                        unsigned int stripe_index =
-                               extract_stripe_index_from_bio_private(
-                                       bio->bi_private);
+                               btrfs_io_bio(bio)->stripe_index;
                        struct btrfs_device *dev;
 
                        BUG_ON(stripe_index >= bbio->num_stripes);
@@ -5084,8 +5057,7 @@ static void btrfs_end_bio(struct bio *bio, int err)
                }
                bio->bi_private = bbio->private;
                bio->bi_end_io = bbio->end_io;
-               bio->bi_bdev = (struct block_device *)
-                                       (unsigned long)bbio->mirror_num;
+               btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
                /* only send an error to the higher layers if it is
                 * beyond the tolerance of the btrfs bio
                 */
@@ -5211,8 +5183,7 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio,
        struct btrfs_device *dev = bbio->stripes[dev_nr].dev;
 
        bio->bi_private = bbio;
-       bio->bi_private = merge_stripe_index_into_bio_private(
-                       bio->bi_private, (unsigned int)dev_nr);
+       btrfs_io_bio(bio)->stripe_index = dev_nr;
        bio->bi_end_io = btrfs_end_bio;
        bio->bi_sector = physical >> 9;
 #ifdef DEBUG
@@ -5273,8 +5244,7 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
        if (atomic_dec_and_test(&bbio->stripes_pending)) {
                bio->bi_private = bbio->private;
                bio->bi_end_io = bbio->end_io;
-               bio->bi_bdev = (struct block_device *)
-                       (unsigned long)bbio->mirror_num;
+               btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
                bio->bi_sector = logical >> 9;
                kfree(bbio);
                bio_endio(bio, -EIO);
@@ -5352,7 +5322,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
                }
 
                if (dev_nr < total_devs - 1) {
-                       bio = bio_clone(first_bio, GFP_NOFS);
+                       bio = btrfs_bio_clone(first_bio, GFP_NOFS);
                        BUG_ON(!bio); /* -ENOMEM */
                } else {
                        bio = first_bio;
index 845ccbb0d2e35e9ad5b92101102b7e853d800ab0..f6247e2a47f7b643d8c88f2ee4c5b53f5c79f043 100644 (file)
@@ -152,6 +152,26 @@ struct btrfs_fs_devices {
        int rotating;
 };
 
+/*
+ * we need the mirror number and stripe index to be passed around
+ * the call chain while we are processing end_io (especially errors).
+ * Really, what we need is a btrfs_bio structure that has this info
+ * and is properly sized with its stripe array, but we're not there
+ * quite yet.  We have our own btrfs bioset, and all of the bios
+ * we allocate are actually btrfs_io_bios.  We'll cram as much of
+ * struct btrfs_bio as we can into this over time.
+ */
+struct btrfs_io_bio {
+       unsigned long mirror_num;
+       unsigned long stripe_index;
+       struct bio bio;
+};
+
+static inline struct btrfs_io_bio *btrfs_io_bio(struct bio *bio)
+{
+       return container_of(bio, struct btrfs_io_bio, bio);
+}
+
 struct btrfs_bio_stripe {
        struct btrfs_device *dev;
        u64 physical;
index 0aabb344b02e6779ed410adff60a9c0e3ab4003e..5aae3d12d4004109cff811b77011486abbaed1b5 100644 (file)
@@ -209,7 +209,6 @@ typedef struct ext4_io_end {
        ssize_t                 size;           /* size of the extent */
        struct kiocb            *iocb;          /* iocb struct for AIO */
        int                     result;         /* error value for AIO */
-       atomic_t                count;          /* reference counter */
 } ext4_io_end_t;
 
 struct ext4_io_submit {
@@ -2651,14 +2650,11 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
 
 /* page-io.c */
 extern int __init ext4_init_pageio(void);
+extern void ext4_add_complete_io(ext4_io_end_t *io_end);
 extern void ext4_exit_pageio(void);
 extern void ext4_ioend_shutdown(struct inode *);
+extern void ext4_free_io_end(ext4_io_end_t *io);
 extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
-extern ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end);
-extern int ext4_put_io_end(ext4_io_end_t *io_end);
-extern void ext4_put_io_end_defer(ext4_io_end_t *io_end);
-extern void ext4_io_submit_init(struct ext4_io_submit *io,
-                               struct writeback_control *wbc);
 extern void ext4_end_io_work(struct work_struct *work);
 extern void ext4_io_submit(struct ext4_io_submit *io);
 extern int ext4_bio_write_page(struct ext4_io_submit *io,
index 107936db244eddd5e7192b657ccef02841d3b617..bc0f1910b9cfa7dd5aa93b9c5d889c6fbacd037d 100644 (file)
@@ -3642,7 +3642,7 @@ int ext4_find_delalloc_range(struct inode *inode,
 {
        struct extent_status es;
 
-       ext4_es_find_delayed_extent(inode, lblk_start, &es);
+       ext4_es_find_delayed_extent_range(inode, lblk_start, lblk_end, &es);
        if (es.es_len == 0)
                return 0; /* there is no delay extent in this tree */
        else if (es.es_lblk <= lblk_start &&
@@ -4608,9 +4608,10 @@ static int ext4_find_delayed_extent(struct inode *inode,
        struct extent_status es;
        ext4_lblk_t block, next_del;
 
-       ext4_es_find_delayed_extent(inode, newes->es_lblk, &es);
-
        if (newes->es_pblk == 0) {
+               ext4_es_find_delayed_extent_range(inode, newes->es_lblk,
+                               newes->es_lblk + newes->es_len - 1, &es);
+
                /*
                 * No extent in extent-tree contains block @newes->es_pblk,
                 * then the block may stay in 1)a hole or 2)delayed-extent.
@@ -4630,7 +4631,7 @@ static int ext4_find_delayed_extent(struct inode *inode,
        }
 
        block = newes->es_lblk + newes->es_len;
-       ext4_es_find_delayed_extent(inode, block, &es);
+       ext4_es_find_delayed_extent_range(inode, block, EXT_MAX_BLOCKS, &es);
        if (es.es_len == 0)
                next_del = EXT_MAX_BLOCKS;
        else
index fe3337a85edeaecd6135333759173d8c6fbc0e78..e6941e622d310eb1ab47793b7c2e984609cebf0b 100644 (file)
@@ -232,14 +232,16 @@ static struct extent_status *__es_tree_search(struct rb_root *root,
 }
 
 /*
- * ext4_es_find_delayed_extent: find the 1st delayed extent covering @es->lblk
- * if it exists, otherwise, the next extent after @es->lblk.
+ * ext4_es_find_delayed_extent_range: find the 1st delayed extent covering
+ * @es->lblk if it exists, otherwise, the next extent after @es->lblk.
  *
  * @inode: the inode which owns delayed extents
  * @lblk: the offset where we start to search
+ * @end: the offset where we stop to search
  * @es: delayed extent that we found
  */
-void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
+void ext4_es_find_delayed_extent_range(struct inode *inode,
+                                ext4_lblk_t lblk, ext4_lblk_t end,
                                 struct extent_status *es)
 {
        struct ext4_es_tree *tree = NULL;
@@ -247,7 +249,8 @@ void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
        struct rb_node *node;
 
        BUG_ON(es == NULL);
-       trace_ext4_es_find_delayed_extent_enter(inode, lblk);
+       BUG_ON(end < lblk);
+       trace_ext4_es_find_delayed_extent_range_enter(inode, lblk);
 
        read_lock(&EXT4_I(inode)->i_es_lock);
        tree = &EXT4_I(inode)->i_es_tree;
@@ -270,6 +273,10 @@ out:
        if (es1 && !ext4_es_is_delayed(es1)) {
                while ((node = rb_next(&es1->rb_node)) != NULL) {
                        es1 = rb_entry(node, struct extent_status, rb_node);
+                       if (es1->es_lblk > end) {
+                               es1 = NULL;
+                               break;
+                       }
                        if (ext4_es_is_delayed(es1))
                                break;
                }
@@ -285,7 +292,7 @@ out:
        read_unlock(&EXT4_I(inode)->i_es_lock);
 
        ext4_es_lru_add(inode);
-       trace_ext4_es_find_delayed_extent_exit(inode, es);
+       trace_ext4_es_find_delayed_extent_range_exit(inode, es);
 }
 
 static struct extent_status *
index d8e2d4dc311e62c99843fa16c7fc8d4a0798bddb..f740eb03b7079b755d3033225a08546ab450c117 100644 (file)
@@ -62,7 +62,8 @@ extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
                                 unsigned long long status);
 extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
                                 ext4_lblk_t len);
-extern void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
+extern void ext4_es_find_delayed_extent_range(struct inode *inode,
+                                       ext4_lblk_t lblk, ext4_lblk_t end,
                                        struct extent_status *es);
 extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
                                 struct extent_status *es);
index 4959e29573b68d0ed2fec94c28015c52cb22afb9..b1b4d51b5d86b4e54c179ddce5f5b574238b3629 100644 (file)
@@ -465,7 +465,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
                 * If there is a delay extent at this offset,
                 * it will be as a data.
                 */
-               ext4_es_find_delayed_extent(inode, last, &es);
+               ext4_es_find_delayed_extent_range(inode, last, last, &es);
                if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
                        if (last != start)
                                dataoff = last << blkbits;
@@ -548,7 +548,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
                 * If there is a delay extent at this offset,
                 * we will skip this extent.
                 */
-               ext4_es_find_delayed_extent(inode, last, &es);
+               ext4_es_find_delayed_extent_range(inode, last, last, &es);
                if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
                        last = es.es_lblk + es.es_len;
                        holeoff = last << blkbits;
index 0723774bdfb5cd3ef27600eaeac7062c330414ac..d6382b89ecbde3077720ebc6a9bb56254883e2d7 100644 (file)
@@ -1488,10 +1488,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
        struct ext4_io_submit io_submit;
 
        BUG_ON(mpd->next_page <= mpd->first_page);
-       ext4_io_submit_init(&io_submit, mpd->wbc);
-       io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS);
-       if (!io_submit.io_end)
-               return -ENOMEM;
+       memset(&io_submit, 0, sizeof(io_submit));
        /*
         * We need to start from the first_page to the next_page - 1
         * to make sure we also write the mapped dirty buffer_heads.
@@ -1579,8 +1576,6 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
                pagevec_release(&pvec);
        }
        ext4_io_submit(&io_submit);
-       /* Drop io_end reference we got from init */
-       ext4_put_io_end_defer(io_submit.io_end);
        return ret;
 }
 
@@ -2239,16 +2234,9 @@ static int ext4_writepage(struct page *page,
                 */
                return __ext4_journalled_writepage(page, len);
 
-       ext4_io_submit_init(&io_submit, wbc);
-       io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS);
-       if (!io_submit.io_end) {
-               redirty_page_for_writepage(wbc, page);
-               return -ENOMEM;
-       }
+       memset(&io_submit, 0, sizeof(io_submit));
        ret = ext4_bio_write_page(&io_submit, page, len, wbc);
        ext4_io_submit(&io_submit);
-       /* Drop io_end reference we got from init */
-       ext4_put_io_end_defer(io_submit.io_end);
        return ret;
 }
 
@@ -3079,13 +3067,9 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
        struct inode *inode = file_inode(iocb->ki_filp);
         ext4_io_end_t *io_end = iocb->private;
 
-       /* if not async direct IO just return */
-       if (!io_end) {
-               inode_dio_done(inode);
-               if (is_async)
-                       aio_complete(iocb, ret, 0);
-               return;
-       }
+       /* if not async direct IO or dio with 0 bytes write, just return */
+       if (!io_end || !size)
+               goto out;
 
        ext_debug("ext4_end_io_dio(): io_end 0x%p "
                  "for inode %lu, iocb 0x%p, offset %llu, size %zd\n",
@@ -3093,13 +3077,25 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
                  size);
 
        iocb->private = NULL;
+
+       /* if not aio dio with unwritten extents, just free io and return */
+       if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
+               ext4_free_io_end(io_end);
+out:
+               inode_dio_done(inode);
+               if (is_async)
+                       aio_complete(iocb, ret, 0);
+               return;
+       }
+
        io_end->offset = offset;
        io_end->size = size;
        if (is_async) {
                io_end->iocb = iocb;
                io_end->result = ret;
        }
-       ext4_put_io_end_defer(io_end);
+
+       ext4_add_complete_io(io_end);
 }
 
 /*
@@ -3133,7 +3129,6 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
        get_block_t *get_block_func = NULL;
        int dio_flags = 0;
        loff_t final_size = offset + count;
-       ext4_io_end_t *io_end = NULL;
 
        /* Use the old path for reads and writes beyond i_size. */
        if (rw != WRITE || final_size > inode->i_size)
@@ -3172,16 +3167,13 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
        iocb->private = NULL;
        ext4_inode_aio_set(inode, NULL);
        if (!is_sync_kiocb(iocb)) {
-               io_end = ext4_init_io_end(inode, GFP_NOFS);
+               ext4_io_end_t *io_end = ext4_init_io_end(inode, GFP_NOFS);
                if (!io_end) {
                        ret = -ENOMEM;
                        goto retake_lock;
                }
                io_end->flag |= EXT4_IO_END_DIRECT;
-               /*
-                * Grab reference for DIO. Will be dropped in ext4_end_io_dio()
-                */
-               iocb->private = ext4_get_io_end(io_end);
+               iocb->private = io_end;
                /*
                 * we save the io structure for current async direct
                 * IO, so that later ext4_map_blocks() could flag the
@@ -3205,27 +3197,26 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
                                   NULL,
                                   dio_flags);
 
+       if (iocb->private)
+               ext4_inode_aio_set(inode, NULL);
        /*
-        * Put our reference to io_end. This can free the io_end structure e.g.
-        * in sync IO case or in case of error. It can even perform extent
-        * conversion if all bios we submitted finished before we got here.
-        * Note that in that case iocb->private can be already set to NULL
-        * here.
+        * The io_end structure takes a reference to the inode, that
+        * structure needs to be destroyed and the reference to the
+        * inode need to be dropped, when IO is complete, even with 0
+        * byte write, or failed.
+        *
+        * In the successful AIO DIO case, the io_end structure will
+        * be destroyed and the reference to the inode will be dropped
+        * after the end_io call back function is called.
+        *
+        * In the case there is 0 byte write, or error case, since VFS
+        * direct IO won't invoke the end_io call back function, we
+        * need to free the end_io structure here.
         */
-       if (io_end) {
-               ext4_inode_aio_set(inode, NULL);
-               ext4_put_io_end(io_end);
-               /*
-                * In case of error or no write ext4_end_io_dio() was not
-                * called so we have to put iocb's reference.
-                */
-               if (ret <= 0 && ret != -EIOCBQUEUED) {
-                       WARN_ON(iocb->private != io_end);
-                       ext4_put_io_end(io_end);
-                       iocb->private = NULL;
-               }
-       }
-       if (ret > 0 && !overwrite && ext4_test_inode_state(inode,
+       if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) {
+               ext4_free_io_end(iocb->private);
+               iocb->private = NULL;
+       } else if (ret > 0 && !overwrite && ext4_test_inode_state(inode,
                                                EXT4_STATE_DIO_UNWRITTEN)) {
                int err;
                /*
index b1ed9e07434ba4a15d86d1a538e6b808917901d6..def84082a9a9b73deadc0d369c63a7ef981d8ea9 100644 (file)
@@ -2105,7 +2105,11 @@ repeat:
                group = ac->ac_g_ex.fe_group;
 
                for (i = 0; i < ngroups; group++, i++) {
-                       if (group == ngroups)
+                       /*
+                        * Artificially restricted ngroups for non-extent
+                        * files makes group > ngroups possible on first loop.
+                        */
+                       if (group >= ngroups)
                                group = 0;
 
                        /* This now checks without needing the buddy page */
index 19599bded62a834be3bc52dbf68cfb0414ec564d..4acf1f78881b6c4c61aa10377a62ea4368106593 100644 (file)
@@ -62,28 +62,15 @@ void ext4_ioend_shutdown(struct inode *inode)
                cancel_work_sync(&EXT4_I(inode)->i_unwritten_work);
 }
 
-static void ext4_release_io_end(ext4_io_end_t *io_end)
+void ext4_free_io_end(ext4_io_end_t *io)
 {
-       BUG_ON(!list_empty(&io_end->list));
-       BUG_ON(io_end->flag & EXT4_IO_END_UNWRITTEN);
-
-       if (atomic_dec_and_test(&EXT4_I(io_end->inode)->i_ioend_count))
-               wake_up_all(ext4_ioend_wq(io_end->inode));
-       if (io_end->flag & EXT4_IO_END_DIRECT)
-               inode_dio_done(io_end->inode);
-       if (io_end->iocb)
-               aio_complete(io_end->iocb, io_end->result, 0);
-       kmem_cache_free(io_end_cachep, io_end);
-}
-
-static void ext4_clear_io_unwritten_flag(ext4_io_end_t *io_end)
-{
-       struct inode *inode = io_end->inode;
+       BUG_ON(!io);
+       BUG_ON(!list_empty(&io->list));
+       BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
 
-       io_end->flag &= ~EXT4_IO_END_UNWRITTEN;
-       /* Wake up anyone waiting on unwritten extent conversion */
-       if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
-               wake_up_all(ext4_ioend_wq(inode));
+       if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count))
+               wake_up_all(ext4_ioend_wq(io->inode));
+       kmem_cache_free(io_end_cachep, io);
 }
 
 /* check a range of space and convert unwritten extents to written. */
@@ -106,8 +93,13 @@ static int ext4_end_io(ext4_io_end_t *io)
                         "(inode %lu, offset %llu, size %zd, error %d)",
                         inode->i_ino, offset, size, ret);
        }
-       ext4_clear_io_unwritten_flag(io);
-       ext4_release_io_end(io);
+       /* Wake up anyone waiting on unwritten extent conversion */
+       if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
+               wake_up_all(ext4_ioend_wq(inode));
+       if (io->flag & EXT4_IO_END_DIRECT)
+               inode_dio_done(inode);
+       if (io->iocb)
+               aio_complete(io->iocb, io->result, 0);
        return ret;
 }
 
@@ -138,7 +130,7 @@ static void dump_completed_IO(struct inode *inode)
 }
 
 /* Add the io_end to per-inode completed end_io list. */
-static void ext4_add_complete_io(ext4_io_end_t *io_end)
+void ext4_add_complete_io(ext4_io_end_t *io_end)
 {
        struct ext4_inode_info *ei = EXT4_I(io_end->inode);
        struct workqueue_struct *wq;
@@ -175,6 +167,8 @@ static int ext4_do_flush_completed_IO(struct inode *inode)
                err = ext4_end_io(io);
                if (unlikely(!ret && err))
                        ret = err;
+               io->flag &= ~EXT4_IO_END_UNWRITTEN;
+               ext4_free_io_end(io);
        }
        return ret;
 }
@@ -206,43 +200,10 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
                atomic_inc(&EXT4_I(inode)->i_ioend_count);
                io->inode = inode;
                INIT_LIST_HEAD(&io->list);
-               atomic_set(&io->count, 1);
        }
        return io;
 }
 
-void ext4_put_io_end_defer(ext4_io_end_t *io_end)
-{
-       if (atomic_dec_and_test(&io_end->count)) {
-               if (!(io_end->flag & EXT4_IO_END_UNWRITTEN) || !io_end->size) {
-                       ext4_release_io_end(io_end);
-                       return;
-               }
-               ext4_add_complete_io(io_end);
-       }
-}
-
-int ext4_put_io_end(ext4_io_end_t *io_end)
-{
-       int err = 0;
-
-       if (atomic_dec_and_test(&io_end->count)) {
-               if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
-                       err = ext4_convert_unwritten_extents(io_end->inode,
-                                               io_end->offset, io_end->size);
-                       ext4_clear_io_unwritten_flag(io_end);
-               }
-               ext4_release_io_end(io_end);
-       }
-       return err;
-}
-
-ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
-{
-       atomic_inc(&io_end->count);
-       return io_end;
-}
-
 /*
  * Print an buffer I/O error compatible with the fs/buffer.c.  This
  * provides compatibility with dmesg scrapers that look for a specific
@@ -325,7 +286,12 @@ static void ext4_end_bio(struct bio *bio, int error)
                             bi_sector >> (inode->i_blkbits - 9));
        }
 
-       ext4_put_io_end_defer(io_end);
+       if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
+               ext4_free_io_end(io_end);
+               return;
+       }
+
+       ext4_add_complete_io(io_end);
 }
 
 void ext4_io_submit(struct ext4_io_submit *io)
@@ -339,37 +305,40 @@ void ext4_io_submit(struct ext4_io_submit *io)
                bio_put(io->io_bio);
        }
        io->io_bio = NULL;
-}
-
-void ext4_io_submit_init(struct ext4_io_submit *io,
-                        struct writeback_control *wbc)
-{
-       io->io_op = (wbc->sync_mode == WB_SYNC_ALL ?  WRITE_SYNC : WRITE);
-       io->io_bio = NULL;
+       io->io_op = 0;
        io->io_end = NULL;
 }
 
-static int io_submit_init_bio(struct ext4_io_submit *io,
-                             struct buffer_head *bh)
+static int io_submit_init(struct ext4_io_submit *io,
+                         struct inode *inode,
+                         struct writeback_control *wbc,
+                         struct buffer_head *bh)
 {
+       ext4_io_end_t *io_end;
+       struct page *page = bh->b_page;
        int nvecs = bio_get_nr_vecs(bh->b_bdev);
        struct bio *bio;
 
+       io_end = ext4_init_io_end(inode, GFP_NOFS);
+       if (!io_end)
+               return -ENOMEM;
        bio = bio_alloc(GFP_NOIO, min(nvecs, BIO_MAX_PAGES));
        bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
        bio->bi_bdev = bh->b_bdev;
+       bio->bi_private = io->io_end = io_end;
        bio->bi_end_io = ext4_end_bio;
-       bio->bi_private = ext4_get_io_end(io->io_end);
-       if (!io->io_end->size)
-               io->io_end->offset = (bh->b_page->index << PAGE_CACHE_SHIFT)
-                                    + bh_offset(bh);
+
+       io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh);
+
        io->io_bio = bio;
+       io->io_op = (wbc->sync_mode == WB_SYNC_ALL ?  WRITE_SYNC : WRITE);
        io->io_next_block = bh->b_blocknr;
        return 0;
 }
 
 static int io_submit_add_bh(struct ext4_io_submit *io,
                            struct inode *inode,
+                           struct writeback_control *wbc,
                            struct buffer_head *bh)
 {
        ext4_io_end_t *io_end;
@@ -380,18 +349,18 @@ submit_and_retry:
                ext4_io_submit(io);
        }
        if (io->io_bio == NULL) {
-               ret = io_submit_init_bio(io, bh);
+               ret = io_submit_init(io, inode, wbc, bh);
                if (ret)
                        return ret;
        }
-       ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh));
-       if (ret != bh->b_size)
-               goto submit_and_retry;
        io_end = io->io_end;
        if (test_clear_buffer_uninit(bh))
                ext4_set_io_unwritten_flag(inode, io_end);
-       io_end->size += bh->b_size;
+       io->io_end->size += bh->b_size;
        io->io_next_block++;
+       ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh));
+       if (ret != bh->b_size)
+               goto submit_and_retry;
        return 0;
 }
 
@@ -463,7 +432,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
        do {
                if (!buffer_async_write(bh))
                        continue;
-               ret = io_submit_add_bh(io, inode, bh);
+               ret = io_submit_add_bh(io, inode, wbc, bh);
                if (ret) {
                        /*
                         * We only get here on ENOMEM.  Not much else
index 5b3d2bd4813ae30895160d1a383ea149615d292e..64b8c7639520d1e41e1439bc558d7a35424e25ef 100644 (file)
@@ -77,7 +77,7 @@ struct acpi_signal_fatal_info {
 /*
  * OSL Initialization and shutdown primitives
  */
-acpi_status __initdata acpi_os_initialize(void);
+acpi_status __init acpi_os_initialize(void);
 
 acpi_status acpi_os_terminate(void);
 
index b327b5a9296d36fb6c31fd26e382488fd0b45cbb..ea69367fdd3bbafaf1775da248c7cc998c47fba8 100644 (file)
@@ -329,10 +329,16 @@ int acpi_processor_power_init(struct acpi_processor *pr);
 int acpi_processor_power_exit(struct acpi_processor *pr);
 int acpi_processor_cst_has_changed(struct acpi_processor *pr);
 int acpi_processor_hotplug(struct acpi_processor *pr);
-int acpi_processor_suspend(struct device *dev);
-int acpi_processor_resume(struct device *dev);
 extern struct cpuidle_driver acpi_idle_driver;
 
+#ifdef CONFIG_PM_SLEEP
+void acpi_processor_syscore_init(void);
+void acpi_processor_syscore_exit(void);
+#else
+static inline void acpi_processor_syscore_init(void) {}
+static inline void acpi_processor_syscore_exit(void) {}
+#endif
+
 /* in processor_thermal.c */
 int acpi_processor_get_limit_info(struct acpi_processor *pr);
 extern const struct thermal_cooling_device_ops processor_cooling_ops;
index 61196592152e09a3913d1989cd847a8f9457664b..63d17ee9eb488c336ad55521f346dc1c2703c4c4 100644 (file)
@@ -316,6 +316,7 @@ struct drm_ioctl_desc {
        int flags;
        drm_ioctl_t *func;
        unsigned int cmd_drv;
+       const char *name;
 };
 
 /**
@@ -324,7 +325,7 @@ struct drm_ioctl_desc {
  */
 
 #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags)                        \
-       [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl}
+       [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl, .name = #ioctl}
 
 struct drm_magic_entry {
        struct list_head head;
index 8230b46fdd73ff916324a9d4d0dd064a13207502..471f276ce8f741638ad6ced787aa7f943457e751 100644 (file)
@@ -50,13 +50,14 @@ struct drm_fb_helper_surface_size {
 
 /**
  * struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
- * @gamma_set: - Set the given gamma lut register on the given crtc.
- * @gamma_get: - Read the given gamma lut register on the given crtc, used to
- *              save the current lut when force-restoring the fbdev for e.g.
- *              kdbg.
- * @fb_probe: - Driver callback to allocate and initialize the fbdev info
- *             structure. Futhermore it also needs to allocate the drm
- *             framebuffer used to back the fbdev.
+ * @gamma_set: Set the given gamma lut register on the given crtc.
+ * @gamma_get: Read the given gamma lut register on the given crtc, used to
+ *             save the current lut when force-restoring the fbdev for e.g.
+ *             kdbg.
+ * @fb_probe: Driver callback to allocate and initialize the fbdev info
+ *            structure. Futhermore it also needs to allocate the drm
+ *            framebuffer used to back the fbdev.
+ * @initial_config: Setup an initial fbdev display configuration
  *
  * Driver callbacks used by the fbdev emulation helper library.
  */
index 393369147a2dd7812ea5555f30ac8a4390ed1442..675ddf4b441f4746942dd62b2ae5febdaaad2868 100644 (file)
@@ -87,15 +87,6 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
 /** Other copying of data from kernel space */
 #define DRM_COPY_TO_USER(arg1, arg2, arg3)             \
        copy_to_user(arg1, arg2, arg3)
-/* Macros for copyfrom user, but checking readability only once */
-#define DRM_VERIFYAREA_READ( uaddr, size )             \
-       (access_ok( VERIFY_READ, uaddr, size ) ? 0 : -EFAULT)
-#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \
-       __copy_from_user(arg1, arg2, arg3)
-#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3)   \
-       __copy_to_user(arg1, arg2, arg3)
-#define DRM_GET_USER_UNCHECKED(val, uaddr)             \
-       __get_user(val, uaddr)
 
 #define DRM_HZ HZ
 
index c2af598f701dac425a6b4b7d65bfec06529801cb..bb1bc485390b253826e683de25dcf8f8c5d72f4e 100644 (file)
        {0x1002, 0x6621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6623, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6631, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6664, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6665, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6667, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x666F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \
index 13a3da25ff0752a99bccb12b9c105cdbdae13457..98cd41bb39c8667953c10030ef32f2945765f7e8 100644 (file)
@@ -30,15 +30,19 @@ struct journal_head {
 
        /*
         * Journalling list for this buffer [jbd_lock_bh_state()]
+        * NOTE: We *cannot* combine this with b_modified into a bitfield
+        * as gcc would then (which the C standard allows but which is
+        * very unuseful) make 64-bit accesses to the bitfield and clobber
+        * b_jcount if its update races with bitfield modification.
         */
-       unsigned b_jlist:4;
+       unsigned b_jlist;
 
        /*
         * This flag signals the buffer has been modified by
         * the currently running transaction
         * [jbd_lock_bh_state()]
         */
-       unsigned b_modified:1;
+       unsigned b_modified;
 
        /*
         * Copy of the buffer data frozen for writing to the log.
index e15828fd71f1b589780b933549e3b07c9652c1e9..484604d184be7380807868d9a12edc80e9064db3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 
 struct kref {
        atomic_t refcount;
@@ -98,6 +99,38 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)
        return kref_sub(kref, 1, release);
 }
 
+/**
+ * kref_put_spinlock_irqsave - decrement refcount for object.
+ * @kref: object.
+ * @release: pointer to the function that will clean up the object when the
+ *          last reference to the object is released.
+ *          This pointer is required, and it is not acceptable to pass kfree
+ *          in as this function.
+ * @lock: lock to take in release case
+ *
+ * Behaves identical to kref_put with one exception.  If the reference count
+ * drops to zero, the lock will be taken atomically wrt dropping the reference
+ * count.  The release function has to call spin_unlock() without _irqrestore.
+ */
+static inline int kref_put_spinlock_irqsave(struct kref *kref,
+               void (*release)(struct kref *kref),
+               spinlock_t *lock)
+{
+       unsigned long flags;
+
+       WARN_ON(release == NULL);
+       if (atomic_add_unless(&kref->refcount, -1, 1))
+               return 0;
+       spin_lock_irqsave(lock, flags);
+       if (atomic_dec_and_test(&kref->refcount)) {
+               release(kref);
+               local_irq_restore(flags);
+               return 1;
+       }
+       spin_unlock_irqrestore(lock, flags);
+       return 0;
+}
+
 static inline int kref_put_mutex(struct kref *kref,
                                 void (*release)(struct kref *kref),
                                 struct mutex *lock)
index fb1bf7d6a41018edf8358c76ffce8b74e2282cba..0390d5943ed6db1885ecf67612d7cd1da60e908b 100644 (file)
@@ -373,13 +373,11 @@ struct ab8500_sysctrl_platform_data;
 /**
  * struct ab8500_platform_data - AB8500 platform data
  * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used
- * @pm_power_off: Should machine pm power off hook be registered or not
  * @init: board-specific initialization after detection of ab8500
  * @regulator: machine-specific constraints for regulators
  */
 struct ab8500_platform_data {
        int irq_base;
-       bool pm_power_off;
        void (*init) (struct ab8500 *);
        struct ab8500_regulator_platform_data *regulator;
        struct abx500_gpio_platform_data *gpio;
index 67f46ad6920a0bffeefb2efe0c437a7a2f86a883..352eec9df1b84097420a88953ce7276cbb637b69 100644 (file)
@@ -126,7 +126,7 @@ struct mlx4_rss_context {
 
 struct mlx4_qp_path {
        u8                      fl;
-       u8                      reserved1[1];
+       u8                      vlan_control;
        u8                      disable_pkey_check;
        u8                      pkey_index;
        u8                      counter_index;
@@ -141,11 +141,32 @@ struct mlx4_qp_path {
        u8                      sched_queue;
        u8                      vlan_index;
        u8                      feup;
-       u8                      reserved3;
+       u8                      fvl_rx;
        u8                      reserved4[2];
        u8                      dmac[6];
 };
 
+enum { /* fl */
+       MLX4_FL_CV      = 1 << 6,
+       MLX4_FL_ETH_HIDE_CQE_VLAN       = 1 << 2
+};
+enum { /* vlan_control */
+       MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED      = 1 << 6,
+       MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED      = 1 << 2,
+       MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED = 1 << 1, /* 802.1p priority tag */
+       MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED    = 1 << 0
+};
+
+enum { /* feup */
+       MLX4_FEUP_FORCE_ETH_UP          = 1 << 6, /* force Eth UP */
+       MLX4_FSM_FORCE_ETH_SRC_MAC      = 1 << 5, /* force Source MAC */
+       MLX4_FVL_FORCE_ETH_VLAN         = 1 << 3  /* force Eth vlan */
+};
+
+enum { /* fvl_rx */
+       MLX4_FVL_RX_FORCE_ETH_VLAN      = 1 << 0 /* enforce Eth rx vlan */
+};
+
 struct mlx4_qp_context {
        __be32                  flags;
        __be32                  pd;
@@ -185,6 +206,10 @@ struct mlx4_qp_context {
        u32                     reserved5[10];
 };
 
+enum { /* param3 */
+       MLX4_STRIP_VLAN = 1 << 30
+};
+
 /* Which firmware version adds support for NEC (NoErrorCompletion) bit */
 #define MLX4_FW_VER_WQE_CTRL_NEC mlx4_fw_ver(2, 2, 232)
 
index 3863a4dbdf1888c51ff9d4ae94057a31e5118034..2a93b64a3869f2af9ea623b8ddc0a435668b3c8c 100644 (file)
  *
  */
 
-#ifdef CONFIG_OF_DEVICE
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+
+#ifdef CONFIG_OF_DEVICE
 #include <linux/pm.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
@@ -100,7 +101,7 @@ extern int of_platform_populate(struct device_node *root,
 
 #if !defined(CONFIG_OF_ADDRESS)
 struct of_dev_auxdata;
-struct device;
+struct device_node;
 static inline int of_platform_populate(struct device_node *root,
                                        const struct of_device_id *matches,
                                        const struct of_dev_auxdata *lookup,
index 72474e18f1e0d8fef7441d3f11269eb90059b684..6aa238096622441de2125f3a7658fe2777f349a1 100644 (file)
  *     if it is 0, pull-down is disabled.
  * @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
  *     low, this is the most typical case and is typically achieved with two
- *     active transistors on the output. Sending this config will enabale
+ *     active transistors on the output. Setting this config will enable
  *     push-pull mode, the argument is ignored.
  * @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open
  *     collector) which means it is usually wired with other output ports
- *     which are then pulled up with an external resistor. Sending this
- *     config will enabale open drain mode, the argument is ignored.
+ *     which are then pulled up with an external resistor. Setting this
+ *     config will enable open drain mode, the argument is ignored.
  * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
- *     (open emitter). Sending this config will enabale open drain mode, the
+ *     (open emitter). Setting this config will enable open drain mode, the
  *     argument is ignored.
- * @PIN_CONFIG_DRIVE_STRENGTH: the pin will output the current passed as
- *     argument. The argument is in mA.
+ * @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current
+ *     passed as argument. The argument is in mA.
  * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin.
  *      If the argument != 0, schmitt-trigger mode is enabled. If it's 0,
  *      schmitt-trigger mode is disabled.
index 6af944ab38f05638e7443122abbc1ec5592dfcbe..22c7052e937248e4c3337778d8608b3508a24ce5 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdarg.h>
 #include <linux/init.h>
 #include <linux/kern_levels.h>
+#include <linux/linkage.h>
 
 extern const char linux_banner[];
 extern const char linux_proc_banner[];
index 428c37a1f95ce2eea8d9785ef69fc6050b5b7c96..33bf2dfab19d079d31a0373adc30ba9bc536edf8 100644 (file)
@@ -305,7 +305,6 @@ struct ucred {
 
 extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);
 
-extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
                               int offset, int len);
 extern int csum_partial_copy_fromiovecend(unsigned char *kdata, 
@@ -314,7 +313,6 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
                                          unsigned int len, __wsum *csump);
 
 extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode);
-extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
 extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
                             int offset, int len);
 extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
index 733eb5ee31c5446cbe6a11bb0b3603a6534edf49..6ff26c8db7b923853527cee3ee1ffff1ca55bdd6 100644 (file)
@@ -57,7 +57,7 @@ extern struct bus_type spi_bus_type;
  * @modalias: Name of the driver to use with this device, or an alias
  *     for that name.  This appears in the sysfs "modalias" attribute
  *     for driver coldplugging, and in uevents used for hotplugging
- * @cs_gpio: gpio number of the chipselect line (optional, -EINVAL when
+ * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when
  *     when not using a GPIO line)
  *
  * A @spi_device is used to interchange data between an SPI slave
@@ -266,7 +266,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  *     queue so the subsystem notifies the driver that it may relax the
  *     hardware by issuing this call
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
- *     number. Any individual value may be -EINVAL for CS lines that
+ *     number. Any individual value may be -ENOENT for CS lines that
  *     are not GPIOs (driven by the SPI controller itself).
  *
  * Each SPI master controller can communicate with one or more @spi_device
index 22d81b3c955b533bf73ec0b9353c6c7d4287c010..d5d229b2e5af1815d38d7d87d217ee8340b9ec1d 100644 (file)
@@ -117,14 +117,10 @@ static inline bool timespec_valid_strict(const struct timespec *ts)
 
 extern bool persistent_clock_exist;
 
-#ifdef ALWAYS_USE_PERSISTENT_CLOCK
-#define has_persistent_clock() true
-#else
 static inline bool has_persistent_clock(void)
 {
        return persistent_clock_exist;
 }
-#endif
 
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);
index 629aaf51f30b8c1fdc6e27cd086c9caf19378896..c55ce243cc0985c450786e4cb63f8ed3c8e5c53b 100644 (file)
@@ -35,4 +35,7 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
 }
 
 unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to);
+
+int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
+int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
 #endif
index c454a88abf2e6fed7adda903a7d2e0626613e29f..f1b0dca60f127116113361da7ff61d726d0fa26a 100644 (file)
@@ -563,9 +563,8 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g)
 }
 
 /**
- * gadget_is_superspeed() - return true if the hardware handles
- * supperspeed
- * @g: controller that might support supper speed
+ * gadget_is_superspeed() - return true if the hardware handles superspeed
+ * @g: controller that might support superspeed
  */
 static inline int gadget_is_superspeed(struct usb_gadget *g)
 {
index b9b0f7b4e43b81c4829802b5f0eea0cd0713974d..302ddf55d2daca5d74291b1eb9aaa2b4127fe7d2 100644 (file)
@@ -268,6 +268,8 @@ struct usb_serial_driver {
                        struct usb_serial_port *port, struct ktermios *old);
        void (*break_ctl)(struct tty_struct *tty, int break_state);
        int  (*chars_in_buffer)(struct tty_struct *tty);
+       void (*wait_until_sent)(struct tty_struct *tty, long timeout);
+       bool (*tx_empty)(struct usb_serial_port *port);
        void (*throttle)(struct tty_struct *tty);
        void (*unthrottle)(struct tty_struct *tty);
        int  (*tiocmget)(struct tty_struct *tty);
@@ -327,6 +329,8 @@ extern void usb_serial_generic_close(struct usb_serial_port *port);
 extern int usb_serial_generic_resume(struct usb_serial *serial);
 extern int usb_serial_generic_write_room(struct tty_struct *tty);
 extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
+extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty,
+                                                               long timeout);
 extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
 extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
 extern void usb_serial_generic_throttle(struct tty_struct *tty);
index 5c97b0fc5623aa4bb44db9082d6631ad0a27fafe..66772cf8c3c528c86104684ca3cf1ac8c5ccfd85 100644 (file)
@@ -866,6 +866,18 @@ struct inet_hashinfo;
 struct raw_hashinfo;
 struct module;
 
+/*
+ * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
+ * un-modified. Special care is taken when initializing object to zero.
+ */
+static inline void sk_prot_clear_nulls(struct sock *sk, int size)
+{
+       if (offsetof(struct sock, sk_node.next) != 0)
+               memset(sk, 0, offsetof(struct sock, sk_node.next));
+       memset(&sk->sk_node.pprev, 0,
+              size - offsetof(struct sock, sk_node.pprev));
+}
+
 /* Networking protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
  * transport -> network interface is defined by struct inet_proto
index c4af592f7057e472d8953099c56651423d0ec6ad..e773dfa5f98f401dbe19f864e6a4fdef5cd191d2 100644 (file)
@@ -463,7 +463,6 @@ struct se_cmd {
 #define CMD_T_ABORTED          (1 << 0)
 #define CMD_T_ACTIVE           (1 << 1)
 #define CMD_T_COMPLETE         (1 << 2)
-#define CMD_T_QUEUED           (1 << 3)
 #define CMD_T_SENT             (1 << 4)
 #define CMD_T_STOP             (1 << 5)
 #define CMD_T_FAILED           (1 << 6)
@@ -572,12 +571,8 @@ struct se_dev_entry {
        bool                    def_pr_registered;
        /* See transport_lunflags_table */
        u32                     lun_flags;
-       u32                     deve_cmds;
        u32                     mapped_lun;
-       u32                     average_bytes;
-       u32                     last_byte_count;
        u32                     total_cmds;
-       u32                     total_bytes;
        u64                     pr_res_key;
        u64                     creation_time;
        u32                     attach_count;
index d0e686402df883d89e474a63374cdd1aa4c73ba6..8ee15b97cd389113859e614e6135a8e1eb6916b5 100644 (file)
@@ -2139,7 +2139,7 @@ TRACE_EVENT(ext4_es_remove_extent,
                  __entry->lblk, __entry->len)
 );
 
-TRACE_EVENT(ext4_es_find_delayed_extent_enter,
+TRACE_EVENT(ext4_es_find_delayed_extent_range_enter,
        TP_PROTO(struct inode *inode, ext4_lblk_t lblk),
 
        TP_ARGS(inode, lblk),
@@ -2161,7 +2161,7 @@ TRACE_EVENT(ext4_es_find_delayed_extent_enter,
                  (unsigned long) __entry->ino, __entry->lblk)
 );
 
-TRACE_EVENT(ext4_es_find_delayed_extent_exit,
+TRACE_EVENT(ext4_es_find_delayed_extent_range_exit,
        TP_PROTO(struct inode *inode, struct extent_status *es),
 
        TP_ARGS(inode, es),
index ee13ab6c361409b31216da2e54790f804401fe51..c312f16bc4e7e692f4117b0a9280cadf1977f8db 100644 (file)
@@ -39,7 +39,7 @@
 #define VIRTIO_CONSOLE_F_SIZE  0       /* Does host provide console size? */
 #define VIRTIO_CONSOLE_F_MULTIPORT 1   /* Does host provide multiple ports? */
 
-#define VIRTIO_CONSOLE_BAD_ID          (~(u32)0)
+#define VIRTIO_CONSOLE_BAD_ID          (~(__u32)0)
 
 struct virtio_console_config {
        /* colums of the screens */
index 8b86c0c68edf4458e894433a45ac8d5b80f673a0..d5585f5e038ee1080f17777792a6927d5897e5ea 100644 (file)
@@ -40,11 +40,13 @@ __setup("hlt", cpu_idle_nopoll_setup);
 
 static inline int cpu_idle_poll(void)
 {
+       rcu_idle_enter();
        trace_cpu_idle_rcuidle(0, smp_processor_id());
        local_irq_enable();
        while (!need_resched())
                cpu_relax();
        trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
+       rcu_idle_exit();
        return 1;
 }
 
index 6b41c1899a8b00acc0ca48ae30b0e8dfbdd2ad9d..9dc297faf7c01b68cbb1a7a24444b99c300cb8a3 100644 (file)
@@ -4394,6 +4394,64 @@ perf_event_read_event(struct perf_event *event,
        perf_output_end(&handle);
 }
 
+typedef int  (perf_event_aux_match_cb)(struct perf_event *event, void *data);
+typedef void (perf_event_aux_output_cb)(struct perf_event *event, void *data);
+
+static void
+perf_event_aux_ctx(struct perf_event_context *ctx,
+                  perf_event_aux_match_cb match,
+                  perf_event_aux_output_cb output,
+                  void *data)
+{
+       struct perf_event *event;
+
+       list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+               if (event->state < PERF_EVENT_STATE_INACTIVE)
+                       continue;
+               if (!event_filter_match(event))
+                       continue;
+               if (match(event, data))
+                       output(event, data);
+       }
+}
+
+static void
+perf_event_aux(perf_event_aux_match_cb match,
+              perf_event_aux_output_cb output,
+              void *data,
+              struct perf_event_context *task_ctx)
+{
+       struct perf_cpu_context *cpuctx;
+       struct perf_event_context *ctx;
+       struct pmu *pmu;
+       int ctxn;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(pmu, &pmus, entry) {
+               cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->unique_pmu != pmu)
+                       goto next;
+               perf_event_aux_ctx(&cpuctx->ctx, match, output, data);
+               if (task_ctx)
+                       goto next;
+               ctxn = pmu->task_ctx_nr;
+               if (ctxn < 0)
+                       goto next;
+               ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
+               if (ctx)
+                       perf_event_aux_ctx(ctx, match, output, data);
+next:
+               put_cpu_ptr(pmu->pmu_cpu_context);
+       }
+
+       if (task_ctx) {
+               preempt_disable();
+               perf_event_aux_ctx(task_ctx, match, output, data);
+               preempt_enable();
+       }
+       rcu_read_unlock();
+}
+
 /*
  * task tracking -- fork/exit
  *
@@ -4416,8 +4474,9 @@ struct perf_task_event {
 };
 
 static void perf_event_task_output(struct perf_event *event,
-                                    struct perf_task_event *task_event)
+                                  void *data)
 {
+       struct perf_task_event *task_event = data;
        struct perf_output_handle handle;
        struct perf_sample_data sample;
        struct task_struct *task = task_event->task;
@@ -4445,62 +4504,11 @@ out:
        task_event->event_id.header.size = size;
 }
 
-static int perf_event_task_match(struct perf_event *event)
-{
-       if (event->state < PERF_EVENT_STATE_INACTIVE)
-               return 0;
-
-       if (!event_filter_match(event))
-               return 0;
-
-       if (event->attr.comm || event->attr.mmap ||
-           event->attr.mmap_data || event->attr.task)
-               return 1;
-
-       return 0;
-}
-
-static void perf_event_task_ctx(struct perf_event_context *ctx,
-                                 struct perf_task_event *task_event)
+static int perf_event_task_match(struct perf_event *event,
+                                void *data __maybe_unused)
 {
-       struct perf_event *event;
-
-       list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
-               if (perf_event_task_match(event))
-                       perf_event_task_output(event, task_event);
-       }
-}
-
-static void perf_event_task_event(struct perf_task_event *task_event)
-{
-       struct perf_cpu_context *cpuctx;
-       struct perf_event_context *ctx;
-       struct pmu *pmu;
-       int ctxn;
-
-       rcu_read_lock();
-       list_for_each_entry_rcu(pmu, &pmus, entry) {
-               cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
-               if (cpuctx->unique_pmu != pmu)
-                       goto next;
-               perf_event_task_ctx(&cpuctx->ctx, task_event);
-
-               ctx = task_event->task_ctx;
-               if (!ctx) {
-                       ctxn = pmu->task_ctx_nr;
-                       if (ctxn < 0)
-                               goto next;
-                       ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
-                       if (ctx)
-                               perf_event_task_ctx(ctx, task_event);
-               }
-next:
-               put_cpu_ptr(pmu->pmu_cpu_context);
-       }
-       if (task_event->task_ctx)
-               perf_event_task_ctx(task_event->task_ctx, task_event);
-
-       rcu_read_unlock();
+       return event->attr.comm || event->attr.mmap ||
+              event->attr.mmap_data || event->attr.task;
 }
 
 static void perf_event_task(struct task_struct *task,
@@ -4531,7 +4539,10 @@ static void perf_event_task(struct task_struct *task,
                },
        };
 
-       perf_event_task_event(&task_event);
+       perf_event_aux(perf_event_task_match,
+                      perf_event_task_output,
+                      &task_event,
+                      task_ctx);
 }
 
 void perf_event_fork(struct task_struct *task)
@@ -4557,8 +4568,9 @@ struct perf_comm_event {
 };
 
 static void perf_event_comm_output(struct perf_event *event,
-                                    struct perf_comm_event *comm_event)
+                                  void *data)
 {
+       struct perf_comm_event *comm_event = data;
        struct perf_output_handle handle;
        struct perf_sample_data sample;
        int size = comm_event->event_id.header.size;
@@ -4585,39 +4597,16 @@ out:
        comm_event->event_id.header.size = size;
 }
 
-static int perf_event_comm_match(struct perf_event *event)
-{
-       if (event->state < PERF_EVENT_STATE_INACTIVE)
-               return 0;
-
-       if (!event_filter_match(event))
-               return 0;
-
-       if (event->attr.comm)
-               return 1;
-
-       return 0;
-}
-
-static void perf_event_comm_ctx(struct perf_event_context *ctx,
-                                 struct perf_comm_event *comm_event)
+static int perf_event_comm_match(struct perf_event *event,
+                                void *data __maybe_unused)
 {
-       struct perf_event *event;
-
-       list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
-               if (perf_event_comm_match(event))
-                       perf_event_comm_output(event, comm_event);
-       }
+       return event->attr.comm;
 }
 
 static void perf_event_comm_event(struct perf_comm_event *comm_event)
 {
-       struct perf_cpu_context *cpuctx;
-       struct perf_event_context *ctx;
        char comm[TASK_COMM_LEN];
        unsigned int size;
-       struct pmu *pmu;
-       int ctxn;
 
        memset(comm, 0, sizeof(comm));
        strlcpy(comm, comm_event->task->comm, sizeof(comm));
@@ -4627,24 +4616,11 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
        comm_event->comm_size = size;
 
        comm_event->event_id.header.size = sizeof(comm_event->event_id) + size;
-       rcu_read_lock();
-       list_for_each_entry_rcu(pmu, &pmus, entry) {
-               cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
-               if (cpuctx->unique_pmu != pmu)
-                       goto next;
-               perf_event_comm_ctx(&cpuctx->ctx, comm_event);
 
-               ctxn = pmu->task_ctx_nr;
-               if (ctxn < 0)
-                       goto next;
-
-               ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
-               if (ctx)
-                       perf_event_comm_ctx(ctx, comm_event);
-next:
-               put_cpu_ptr(pmu->pmu_cpu_context);
-       }
-       rcu_read_unlock();
+       perf_event_aux(perf_event_comm_match,
+                      perf_event_comm_output,
+                      comm_event,
+                      NULL);
 }
 
 void perf_event_comm(struct task_struct *task)
@@ -4706,8 +4682,9 @@ struct perf_mmap_event {
 };
 
 static void perf_event_mmap_output(struct perf_event *event,
-                                    struct perf_mmap_event *mmap_event)
+                                  void *data)
 {
+       struct perf_mmap_event *mmap_event = data;
        struct perf_output_handle handle;
        struct perf_sample_data sample;
        int size = mmap_event->event_id.header.size;
@@ -4734,46 +4711,24 @@ out:
 }
 
 static int perf_event_mmap_match(struct perf_event *event,
-                                  struct perf_mmap_event *mmap_event,
-                                  int executable)
-{
-       if (event->state < PERF_EVENT_STATE_INACTIVE)
-               return 0;
-
-       if (!event_filter_match(event))
-               return 0;
-
-       if ((!executable && event->attr.mmap_data) ||
-           (executable && event->attr.mmap))
-               return 1;
-
-       return 0;
-}
-
-static void perf_event_mmap_ctx(struct perf_event_context *ctx,
-                                 struct perf_mmap_event *mmap_event,
-                                 int executable)
+                                void *data)
 {
-       struct perf_event *event;
+       struct perf_mmap_event *mmap_event = data;
+       struct vm_area_struct *vma = mmap_event->vma;
+       int executable = vma->vm_flags & VM_EXEC;
 
-       list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
-               if (perf_event_mmap_match(event, mmap_event, executable))
-                       perf_event_mmap_output(event, mmap_event);
-       }
+       return (!executable && event->attr.mmap_data) ||
+              (executable && event->attr.mmap);
 }
 
 static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
 {
-       struct perf_cpu_context *cpuctx;
-       struct perf_event_context *ctx;
        struct vm_area_struct *vma = mmap_event->vma;
        struct file *file = vma->vm_file;
        unsigned int size;
        char tmp[16];
        char *buf = NULL;
        const char *name;
-       struct pmu *pmu;
-       int ctxn;
 
        memset(tmp, 0, sizeof(tmp));
 
@@ -4829,27 +4784,10 @@ got_name:
 
        mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size;
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(pmu, &pmus, entry) {
-               cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
-               if (cpuctx->unique_pmu != pmu)
-                       goto next;
-               perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
-                                       vma->vm_flags & VM_EXEC);
-
-               ctxn = pmu->task_ctx_nr;
-               if (ctxn < 0)
-                       goto next;
-
-               ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
-               if (ctx) {
-                       perf_event_mmap_ctx(ctx, mmap_event,
-                                       vma->vm_flags & VM_EXEC);
-               }
-next:
-               put_cpu_ptr(pmu->pmu_cpu_context);
-       }
-       rcu_read_unlock();
+       perf_event_aux(perf_event_mmap_match,
+                      perf_event_mmap_output,
+                      mmap_event,
+                      NULL);
 
        kfree(buf);
 }
index 1296e72e4161be305e37606f6024db1a84ff73a3..8241906c4b61a0887304f6524516563707d1a876 100644 (file)
@@ -569,6 +569,11 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
        int retval = 0;
 
        helper_lock();
+       if (!sub_info->path) {
+               retval = -EINVAL;
+               goto out;
+       }
+
        if (sub_info->path[0] == '\0')
                goto out;
 
index b049939177f6d3a4983341b42eb4719c27b4af62..cab4bce49c23dbe3779d02db8259dda28b7b4258 100644 (file)
@@ -2431,10 +2431,10 @@ static void kmemleak_load_module(const struct module *mod,
        kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
 
        for (i = 1; i < info->hdr->e_shnum; i++) {
-               const char *name = info->secstrings + info->sechdrs[i].sh_name;
-               if (!(info->sechdrs[i].sh_flags & SHF_ALLOC))
-                       continue;
-               if (!strstarts(name, ".data") && !strstarts(name, ".bss"))
+               /* Scan all writable sections that's not executable */
+               if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) ||
+                   !(info->sechdrs[i].sh_flags & SHF_WRITE) ||
+                   (info->sechdrs[i].sh_flags & SHF_EXECINSTR))
                        continue;
 
                kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
@@ -2769,24 +2769,11 @@ static void find_module_sections(struct module *mod, struct load_info *info)
        mod->trace_events = section_objs(info, "_ftrace_events",
                                         sizeof(*mod->trace_events),
                                         &mod->num_trace_events);
-       /*
-        * This section contains pointers to allocated objects in the trace
-        * code and not scanning it leads to false positives.
-        */
-       kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) *
-                          mod->num_trace_events, GFP_KERNEL);
 #endif
 #ifdef CONFIG_TRACING
        mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt",
                                         sizeof(*mod->trace_bprintk_fmt_start),
                                         &mod->num_trace_bprintk_fmt);
-       /*
-        * This section contains pointers to allocated objects in the trace
-        * code and not scanning it leads to false positives.
-        */
-       kmemleak_scan_area(mod->trace_bprintk_fmt_start,
-                          sizeof(*mod->trace_bprintk_fmt_start) *
-                          mod->num_trace_bprintk_fmt, GFP_KERNEL);
 #endif
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
        /* sechdrs[0].sh_size is always zero */
index 170814dc418f63a4753b1cfdae39d4d2dbff78cf..3db5a375d8dd52a93f64b48a5d0d7cad5a59559a 100644 (file)
@@ -88,7 +88,7 @@ static void __init rcu_bootup_announce_oddness(void)
 #ifdef CONFIG_RCU_NOCB_CPU
 #ifndef CONFIG_RCU_NOCB_CPU_NONE
        if (!have_rcu_nocb_mask) {
-               alloc_bootmem_cpumask_var(&rcu_nocb_mask);
+               zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL);
                have_rcu_nocb_mask = true;
        }
 #ifdef CONFIG_RCU_NOCB_CPU_ZERO
@@ -1667,7 +1667,7 @@ int rcu_needs_cpu(int cpu, unsigned long *dj)
        rdtp->last_accelerate = jiffies;
 
        /* Request timer delay depending on laziness, and round. */
-       if (rdtp->all_lazy) {
+       if (!rdtp->all_lazy) {
                *dj = round_up(rcu_idle_gp_delay + jiffies,
                               rcu_idle_gp_delay) - jiffies;
        } else {
index e4c07b0692bbba4a79676ffceed77324fd6087bf..70f27e89012b29d18b4aeb9c6e5c367d1b3955a5 100644 (file)
@@ -12,11 +12,6 @@ config CLOCKSOURCE_WATCHDOG
 config ARCH_CLOCKSOURCE_DATA
        bool
 
-# Platforms has a persistent clock
-config ALWAYS_USE_PERSISTENT_CLOCK
-       bool
-       default n
-
 # Timekeeping vsyscall support
 config GENERIC_TIME_VSYSCALL
        bool
index 206bbfb34e091d21f5928a846f4e1a53ab984663..24938d57766948646e567ba4814129d3d74b7112 100644 (file)
@@ -786,11 +786,11 @@ bool tick_broadcast_oneshot_available(void)
 
 void __init tick_broadcast_init(void)
 {
-       alloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
-       alloc_cpumask_var(&tmpmask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tmpmask, GFP_NOWAIT);
 #ifdef CONFIG_TICK_ONESHOT
-       alloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
-       alloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT);
-       alloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT);
 #endif
 }
index bc67d4245e1d130b523fd36482d50ebe4cbab763..f4208138fbf4cd1a72791f99c31adcbea9180e3e 100644 (file)
@@ -717,6 +717,7 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
        if (unlikely(!cpu_online(cpu))) {
                if (cpu == tick_do_timer_cpu)
                        tick_do_timer_cpu = TICK_DO_TIMER_NONE;
+               return false;
        }
 
        if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
@@ -1168,7 +1169,7 @@ void tick_cancel_sched_timer(int cpu)
                hrtimer_cancel(&ts->sched_timer);
 # endif
 
-       ts->nohz_mode = NOHZ_MODE_INACTIVE;
+       memset(ts, 0, sizeof(*ts));
 }
 #endif
 
index a860bba34412c0d8047ff4d81c54fb500fa5de9f..15ffdb3f1948b9468c2c04527beb8190b0d79d45 100644 (file)
@@ -1539,12 +1539,12 @@ static int __cpuinit init_timers_cpu(int cpu)
                        boot_done = 1;
                        base = &boot_tvec_bases;
                }
+               spin_lock_init(&base->lock);
                tvec_base_done[cpu] = 1;
        } else {
                base = per_cpu(tvec_bases, cpu);
        }
 
-       spin_lock_init(&base->lock);
 
        for (j = 0; j < TVN_SIZE; j++) {
                INIT_LIST_HEAD(base->tv5.vec + j);
index a6361178de5ae4e17d0501db852a06ae80b06cf4..e1b653f7e1ca101f0861351d610b5c8297a4b3ca 100644 (file)
@@ -750,7 +750,11 @@ static int filter_set_pred(struct event_filter *filter,
 
 static void __free_preds(struct event_filter *filter)
 {
+       int i;
+
        if (filter->preds) {
+               for (i = 0; i < filter->n_preds; i++)
+                       kfree(filter->preds[i].ops);
                kfree(filter->preds);
                filter->preds = NULL;
        }
index 636d45fe69b37a80eefafe6b3aa6d46220f132dd..9f46e98ba8f22a712962ccc68e17b34f166439ba 100644 (file)
@@ -35,7 +35,7 @@ struct trace_probe {
        const char              *symbol;        /* symbol name */
        struct ftrace_event_class       class;
        struct ftrace_event_call        call;
-       struct ftrace_event_file        **files;
+       struct ftrace_event_file * __rcu *files;
        ssize_t                 size;           /* trace entry size */
        unsigned int            nr_args;
        struct probe_arg        args[];
@@ -185,9 +185,14 @@ static struct trace_probe *find_trace_probe(const char *event,
 
 static int trace_probe_nr_files(struct trace_probe *tp)
 {
-       struct ftrace_event_file **file = tp->files;
+       struct ftrace_event_file **file;
        int ret = 0;
 
+       /*
+        * Since all tp->files updater is protected by probe_enable_lock,
+        * we don't need to lock an rcu_read_lock.
+        */
+       file = rcu_dereference_raw(tp->files);
        if (file)
                while (*(file++))
                        ret++;
@@ -209,9 +214,10 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
        mutex_lock(&probe_enable_lock);
 
        if (file) {
-               struct ftrace_event_file **new, **old = tp->files;
+               struct ftrace_event_file **new, **old;
                int n = trace_probe_nr_files(tp);
 
+               old = rcu_dereference_raw(tp->files);
                /* 1 is for new one and 1 is for stopper */
                new = kzalloc((n + 2) * sizeof(struct ftrace_event_file *),
                              GFP_KERNEL);
@@ -251,11 +257,17 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
 static int
 trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file)
 {
+       struct ftrace_event_file **files;
        int i;
 
-       if (tp->files) {
-               for (i = 0; tp->files[i]; i++)
-                       if (tp->files[i] == file)
+       /*
+        * Since all tp->files updater is protected by probe_enable_lock,
+        * we don't need to lock an rcu_read_lock.
+        */
+       files = rcu_dereference_raw(tp->files);
+       if (files) {
+               for (i = 0; files[i]; i++)
+                       if (files[i] == file)
                                return i;
        }
 
@@ -274,10 +286,11 @@ disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
        mutex_lock(&probe_enable_lock);
 
        if (file) {
-               struct ftrace_event_file **new, **old = tp->files;
+               struct ftrace_event_file **new, **old;
                int n = trace_probe_nr_files(tp);
                int i, j;
 
+               old = rcu_dereference_raw(tp->files);
                if (n == 0 || trace_probe_file_index(tp, file) < 0) {
                        ret = -EINVAL;
                        goto out_unlock;
@@ -872,9 +885,16 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
 static __kprobes void
 kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs)
 {
-       struct ftrace_event_file **file = tp->files;
+       /*
+        * Note: preempt is already disabled around the kprobe handler.
+        * However, we still need an smp_read_barrier_depends() corresponding
+        * to smp_wmb() in rcu_assign_pointer() to access the pointer.
+        */
+       struct ftrace_event_file **file = rcu_dereference_raw(tp->files);
+
+       if (unlikely(!file))
+               return;
 
-       /* Note: preempt is already disabled around the kprobe handler */
        while (*file) {
                __kprobe_trace_func(tp, regs, *file);
                file++;
@@ -925,9 +945,16 @@ static __kprobes void
 kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
                     struct pt_regs *regs)
 {
-       struct ftrace_event_file **file = tp->files;
+       /*
+        * Note: preempt is already disabled around the kprobe handler.
+        * However, we still need an smp_read_barrier_depends() corresponding
+        * to smp_wmb() in rcu_assign_pointer() to access the pointer.
+        */
+       struct ftrace_event_file **file = rcu_dereference_raw(tp->files);
+
+       if (unlikely(!file))
+               return;
 
-       /* Note: preempt is already disabled around the kprobe handler */
        while (*file) {
                __kretprobe_trace_func(tp, ri, regs, *file);
                file++;
@@ -935,7 +962,7 @@ kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
 }
 
 /* Event entry printers */
-enum print_line_t
+static enum print_line_t
 print_kprobe_event(struct trace_iterator *iter, int flags,
                   struct trace_event *event)
 {
@@ -971,7 +998,7 @@ partial:
        return TRACE_TYPE_PARTIAL_LINE;
 }
 
-enum print_line_t
+static enum print_line_t
 print_kretprobe_event(struct trace_iterator *iter, int flags,
                      struct trace_event *event)
 {
index 4aa9f5bc6b2dfdd9f152f5d20bf06c15f070aa21..ee8e29a2320c7c76d67df8f4816af52cd9da5f68 100644 (file)
@@ -296,7 +296,7 @@ static DEFINE_HASHTABLE(unbound_pool_hash, UNBOUND_POOL_HASH_ORDER);
 static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS];
 
 struct workqueue_struct *system_wq __read_mostly;
-EXPORT_SYMBOL_GPL(system_wq);
+EXPORT_SYMBOL(system_wq);
 struct workqueue_struct *system_highpri_wq __read_mostly;
 EXPORT_SYMBOL_GPL(system_highpri_wq);
 struct workqueue_struct *system_long_wq __read_mostly;
@@ -1411,7 +1411,7 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq,
        local_irq_restore(flags);
        return ret;
 }
-EXPORT_SYMBOL_GPL(queue_work_on);
+EXPORT_SYMBOL(queue_work_on);
 
 void delayed_work_timer_fn(unsigned long __data)
 {
@@ -1485,7 +1485,7 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
        local_irq_restore(flags);
        return ret;
 }
-EXPORT_SYMBOL_GPL(queue_delayed_work_on);
+EXPORT_SYMBOL(queue_delayed_work_on);
 
 /**
  * mod_delayed_work_on - modify delay of or queue a delayed work on specific CPU
@@ -2059,6 +2059,7 @@ static bool manage_workers(struct worker *worker)
        if (unlikely(!mutex_trylock(&pool->manager_mutex))) {
                spin_unlock_irq(&pool->lock);
                mutex_lock(&pool->manager_mutex);
+               spin_lock_irq(&pool->lock);
                ret = true;
        }
 
@@ -4311,6 +4312,12 @@ bool current_is_workqueue_rescuer(void)
  * no synchronization around this function and the test result is
  * unreliable and only useful as advisory hints or for debugging.
  *
+ * If @cpu is WORK_CPU_UNBOUND, the test is performed on the local CPU.
+ * Note that both per-cpu and unbound workqueues may be associated with
+ * multiple pool_workqueues which have separate congested states.  A
+ * workqueue being congested on one CPU doesn't mean the workqueue is also
+ * contested on other CPUs / NUMA nodes.
+ *
  * RETURNS:
  * %true if congested, %false otherwise.
  */
@@ -4321,6 +4328,9 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq)
 
        rcu_read_lock_sched();
 
+       if (cpu == WORK_CPU_UNBOUND)
+               cpu = smp_processor_id();
+
        if (!(wq->flags & WQ_UNBOUND))
                pwq = per_cpu_ptr(wq->cpu_pwqs, cpu);
        else
@@ -4895,7 +4905,8 @@ static void __init wq_numa_init(void)
        BUG_ON(!tbl);
 
        for_each_node(node)
-               BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL, node));
+               BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL,
+                               node_online(node) ? node : NUMA_NO_NODE));
 
        for_each_possible_cpu(cpu) {
                node = cpu_to_node(cpu);
index e9c52e1b853a658c0b99580e092023d7f53a341e..c55a037a354eb9ffbd8f492f8e07c92e3aa0b941 100644 (file)
@@ -23,7 +23,7 @@ lib-y += kobject.o klist.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
         bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
-        gcd.o lcm.o list_sort.o uuid.o flex_array.o \
+        gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o \
         bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o
 obj-y += string_helpers.o
 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
diff --git a/lib/iovec.c b/lib/iovec.c
new file mode 100644 (file)
index 0000000..454baa8
--- /dev/null
@@ -0,0 +1,53 @@
+#include <linux/uaccess.h>
+#include <linux/export.h>
+#include <linux/uio.h>
+
+/*
+ *     Copy iovec to kernel. Returns -EFAULT on error.
+ *
+ *     Note: this modifies the original iovec.
+ */
+
+int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
+{
+       while (len > 0) {
+               if (iov->iov_len) {
+                       int copy = min_t(unsigned int, len, iov->iov_len);
+                       if (copy_from_user(kdata, iov->iov_base, copy))
+                               return -EFAULT;
+                       len -= copy;
+                       kdata += copy;
+                       iov->iov_base += copy;
+                       iov->iov_len -= copy;
+               }
+               iov++;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(memcpy_fromiovec);
+
+/*
+ *     Copy kernel to iovec. Returns -EFAULT on error.
+ *
+ *     Note: this modifies the original iovec.
+ */
+
+int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
+{
+       while (len > 0) {
+               if (iov->iov_len) {
+                       int copy = min_t(unsigned int, iov->iov_len, len);
+                       if (copy_to_user(iov->iov_base, kdata, copy))
+                               return -EFAULT;
+                       kdata += copy;
+                       len -= copy;
+                       iov->iov_len -= copy;
+                       iov->iov_base += copy;
+               }
+               iov++;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(memcpy_toiovec);
index 0874e41609a6fbf4d786f3b49aa76f85130893f7..358a368a2947057ef9d9309c9dd4fc893523d63d 100644 (file)
@@ -193,10 +193,10 @@ static void klist_release(struct kref *kref)
                if (waiter->node != n)
                        continue;
 
+               list_del(&waiter->list);
                waiter->woken = 1;
                mb();
                wake_up_process(waiter->process);
-               list_del(&waiter->list);
        }
        spin_unlock(&klist_remove_lock);
        knode_set_klist(n, NULL);
index 98cbdf6e553217a87b62daac80d26c026ecf60e3..378a15bcd64940cd4bab29335604f757543839be 100644 (file)
@@ -5158,7 +5158,7 @@ unsigned long free_reserved_area(unsigned long start, unsigned long end,
        for (pages = 0; pos < end; pos += PAGE_SIZE, pages++) {
                if (poison)
                        memset((void *)pos, poison, PAGE_SIZE);
-               free_reserved_page(virt_to_page(pos));
+               free_reserved_page(virt_to_page((void *)pos));
        }
 
        if (pages && s)
index 8e15d966d9b0a9f30e1010c242c440e206f73ea2..239992021b1d635382dfcec141723696d7cbf564 100644 (file)
@@ -837,6 +837,19 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
 
        dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
        if (dat_entry) {
+               /* If the ARP request is destined for a local client the local
+                * client will answer itself. DAT would only generate a
+                * duplicate packet.
+                *
+                * Moreover, if the soft-interface is enslaved into a bridge, an
+                * additional DAT answer may trigger kernel warnings about
+                * a packet coming from the wrong port.
+                */
+               if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) {
+                       ret = true;
+                       goto out;
+               }
+
                skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
                                     bat_priv->soft_iface, ip_dst, hw_src,
                                     dat_entry->mac_addr, hw_src);
index 3e30a0f1b908b2872bcb6a13100306e0deda0c85..1240f07ad31dc631c5dc941f31bfd541f0205fea 100644 (file)
@@ -163,14 +163,22 @@ void batadv_mesh_free(struct net_device *soft_iface)
        batadv_vis_quit(bat_priv);
 
        batadv_gw_node_purge(bat_priv);
-       batadv_originator_free(bat_priv);
        batadv_nc_free(bat_priv);
+       batadv_dat_free(bat_priv);
+       batadv_bla_free(bat_priv);
 
+       /* Free the TT and the originator tables only after having terminated
+        * all the other depending components which may use these structures for
+        * their purposes.
+        */
        batadv_tt_free(bat_priv);
 
-       batadv_bla_free(bat_priv);
-
-       batadv_dat_free(bat_priv);
+       /* Since the originator table clean up routine is accessing the TT
+        * tables as well, it has to be invoked after the TT tables have been
+        * freed and marked as empty. This ensures that no cleanup RCU callbacks
+        * accessing the TT data are scheduled for later execution.
+        */
+       batadv_originator_free(bat_priv);
 
        free_percpu(bat_priv->bat_counters);
 
@@ -475,7 +483,7 @@ static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
        char *algo_name = (char *)val;
        size_t name_len = strlen(algo_name);
 
-       if (algo_name[name_len - 1] == '\n')
+       if (name_len > 0 && algo_name[name_len - 1] == '\n')
                algo_name[name_len - 1] = '\0';
 
        bat_algo_ops = batadv_algo_get(algo_name);
index f7c54305a9188f83dbd02af6eae287247854babf..e84629ece9b7cfb0a06a0baf856474173f02a144 100644 (file)
@@ -1514,6 +1514,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
        struct ethhdr *ethhdr, ethhdr_tmp;
        uint8_t *orig_dest, ttl, ttvn;
        unsigned int coding_len;
+       int err;
 
        /* Save headers temporarily */
        memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp));
@@ -1568,8 +1569,11 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
                         coding_len);
 
        /* Resize decoded skb if decoded with larger packet */
-       if (nc_packet->skb->len > coding_len + h_size)
-               pskb_trim_rcsum(skb, coding_len + h_size);
+       if (nc_packet->skb->len > coding_len + h_size) {
+               err = pskb_trim_rcsum(skb, coding_len + h_size);
+               if (err)
+                       return NULL;
+       }
 
        /* Create decoded unicast packet */
        unicast_packet = (struct batadv_unicast_packet *)skb->data;
index a3395fdfbd4f6345cdf3bd3a12ebdc1d7f26ecbb..d5953b87918c072daaa1427187246f9f9cfcad3e 100644 (file)
@@ -1204,6 +1204,7 @@ void ceph_osdc_unregister_linger_request(struct ceph_osd_client *osdc,
        mutex_lock(&osdc->request_mutex);
        if (req->r_linger) {
                __unregister_linger_request(osdc, req);
+               req->r_linger = 0;
                ceph_osdc_put_request(req);
        }
        mutex_unlock(&osdc->request_mutex);
@@ -2120,7 +2121,9 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
        down_read(&osdc->map_sem);
        mutex_lock(&osdc->request_mutex);
        __register_request(osdc, req);
-       WARN_ON(req->r_sent);
+       req->r_sent = 0;
+       req->r_got_reply = 0;
+       req->r_completed = 0;
        rc = __map_request(osdc, req, 0);
        if (rc < 0) {
                if (nofail) {
index 7e7aeb01de45cf3236469d7f62b51254b73abac4..de178e462682af6c97dbfc4326df85942ec25174 100644 (file)
@@ -73,31 +73,6 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
        return err;
 }
 
-/*
- *     Copy kernel to iovec. Returns -EFAULT on error.
- *
- *     Note: this modifies the original iovec.
- */
-
-int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
-{
-       while (len > 0) {
-               if (iov->iov_len) {
-                       int copy = min_t(unsigned int, iov->iov_len, len);
-                       if (copy_to_user(iov->iov_base, kdata, copy))
-                               return -EFAULT;
-                       kdata += copy;
-                       len -= copy;
-                       iov->iov_len -= copy;
-                       iov->iov_base += copy;
-               }
-               iov++;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(memcpy_toiovec);
-
 /*
  *     Copy kernel to iovec. Returns -EFAULT on error.
  */
@@ -124,31 +99,6 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
 }
 EXPORT_SYMBOL(memcpy_toiovecend);
 
-/*
- *     Copy iovec to kernel. Returns -EFAULT on error.
- *
- *     Note: this modifies the original iovec.
- */
-
-int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
-{
-       while (len > 0) {
-               if (iov->iov_len) {
-                       int copy = min_t(unsigned int, len, iov->iov_len);
-                       if (copy_from_user(kdata, iov->iov_base, copy))
-                               return -EFAULT;
-                       len -= copy;
-                       kdata += copy;
-                       iov->iov_base += copy;
-                       iov->iov_len -= copy;
-               }
-               iov++;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(memcpy_fromiovec);
-
 /*
  *     Copy iovec from kernel. Returns -EFAULT on error.
  */
index d4f4cea726e7bfdb0d9cc47a779d5252738bf37c..6ba327da79e1efece2479f4745136a091e4958d3 100644 (file)
@@ -1217,18 +1217,6 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
 #endif
 }
 
-/*
- * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
- * un-modified. Special care is taken when initializing object to zero.
- */
-static inline void sk_prot_clear_nulls(struct sock *sk, int size)
-{
-       if (offsetof(struct sock, sk_node.next) != 0)
-               memset(sk, 0, offsetof(struct sock, sk_node.next));
-       memset(&sk->sk_node.pprev, 0,
-              size - offsetof(struct sock, sk_node.pprev));
-}
-
 void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
 {
        unsigned long nulls1, nulls2;
index 147abf5275aa6604df58c3b022eaeceaee10df4f..4bcabf3ab4cad3bdc43f5b9ed33eba9c1357557d 100644 (file)
@@ -84,7 +84,7 @@ int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
 EXPORT_SYMBOL(sysctl_ip_default_ttl);
 
 /* Generate a checksum for an outgoing IP datagram. */
-__inline__ void ip_send_check(struct iphdr *iph)
+void ip_send_check(struct iphdr *iph)
 {
        iph->check = 0;
        iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
index d3ddd840035450570d634fb22002496a447d5d34..ecd60733e5e24afdb28a52c95686fec28e2e4d73 100644 (file)
@@ -1081,6 +1081,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
                }
                if (t == NULL)
                        t = netdev_priv(dev);
+               memset(&p, 0, sizeof(p));
                ip6gre_tnl_parm_to_user(&p, &t->parms);
                if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
                        err = -EFAULT;
@@ -1128,6 +1129,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
                if (t) {
                        err = 0;
 
+                       memset(&p, 0, sizeof(p));
                        ip6gre_tnl_parm_to_user(&p, &t->parms);
                        if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
                                err = -EFAULT;
index 71167069b394e741101d33486cb8bd1e2680c68f..0a17ed9eaf390c4b84a6264c03697f60af9281a1 100644 (file)
@@ -1890,6 +1890,17 @@ void tcp6_proc_exit(struct net *net)
 }
 #endif
 
+static void tcp_v6_clear_sk(struct sock *sk, int size)
+{
+       struct inet_sock *inet = inet_sk(sk);
+
+       /* we do not want to clear pinet6 field, because of RCU lookups */
+       sk_prot_clear_nulls(sk, offsetof(struct inet_sock, pinet6));
+
+       size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
+       memset(&inet->pinet6 + 1, 0, size);
+}
+
 struct proto tcpv6_prot = {
        .name                   = "TCPv6",
        .owner                  = THIS_MODULE,
@@ -1933,6 +1944,7 @@ struct proto tcpv6_prot = {
 #ifdef CONFIG_MEMCG_KMEM
        .proto_cgroup           = tcp_proto_cgroup,
 #endif
+       .clear_sk               = tcp_v6_clear_sk,
 };
 
 static const struct inet6_protocol tcpv6_protocol = {
index d4defdd449372604c21f2d3c353c20339e920d5c..42923b14dfa618ce83ba969c126611fe2ad4a828 100644 (file)
@@ -1432,6 +1432,17 @@ void udp6_proc_exit(struct net *net) {
 }
 #endif /* CONFIG_PROC_FS */
 
+void udp_v6_clear_sk(struct sock *sk, int size)
+{
+       struct inet_sock *inet = inet_sk(sk);
+
+       /* we do not want to clear pinet6 field, because of RCU lookups */
+       sk_prot_clear_portaddr_nulls(sk, offsetof(struct inet_sock, pinet6));
+
+       size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
+       memset(&inet->pinet6 + 1, 0, size);
+}
+
 /* ------------------------------------------------------------------------ */
 
 struct proto udpv6_prot = {
@@ -1462,7 +1473,7 @@ struct proto udpv6_prot = {
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
 #endif
-       .clear_sk          = sk_prot_clear_portaddr_nulls,
+       .clear_sk          = udp_v6_clear_sk,
 };
 
 static struct inet_protosw udpv6_protosw = {
index d7571046bfc440386a52b71bdb2c5295e4360001..4691ed50a9282a108e43ce8e7de56d79c1635c4a 100644 (file)
@@ -31,6 +31,8 @@ extern int    udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
 extern int     udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
 extern void    udpv6_destroy_sock(struct sock *sk);
 
+extern void udp_v6_clear_sk(struct sock *sk, int size);
+
 #ifdef CONFIG_PROC_FS
 extern int     udp6_seq_show(struct seq_file *seq, void *v);
 #endif
index 1d08e21d9f6993e92a4a16b589784873aaf63fd8..dfcc4be46898281f09038bbd7638edfefa04ea3e 100644 (file)
@@ -56,7 +56,7 @@ struct proto udplitev6_prot = {
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
 #endif
-       .clear_sk          = sk_prot_clear_portaddr_nulls,
+       .clear_sk          = udp_v6_clear_sk,
 };
 
 static struct inet_protosw udplite6_protosw = {
index 4ef7bdb65440ca965561d4ca6fdd10b4d97f97d6..23ed03d786c8376cc59f9fa2cf577ee01a4c2c2d 100644 (file)
@@ -103,8 +103,10 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        dev_hold(dev);
 
        xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
-       if (!xdst->u.rt6.rt6i_idev)
+       if (!xdst->u.rt6.rt6i_idev) {
+               dev_put(dev);
                return -ENODEV;
+       }
 
        rt6_transfer_peer(&xdst->u.rt6, rt);
 
index 84a406070f6f2b3f7ca48998bdce1a7d1ad7c3b4..a4f31c900fa6a44ab75d1a4f3916d2bb1075c448 100644 (file)
@@ -63,7 +63,7 @@ binrpm-pkg: FORCE
        mv -f $(objtree)/.tmp_version $(objtree)/.version
 
        $(RPM) $(RPMOPTS) --define "_builddir $(objtree)" --target \
-               $(UTS_MACHINE) -bb $<
+               $(UTS_MACHINE) -bb $(objtree)/binkernel.spec
        rm binkernel.spec
 
 # Deb target
index 552b97afbca5346a96ca6187602ba0326ce4ef28..61ab640e195f3cbf6ee30d574116c797eead5a99 100644 (file)
@@ -113,6 +113,7 @@ MODULE_ALIAS("sound-layout-100");
 MODULE_ALIAS("aoa-device-id-14");
 MODULE_ALIAS("aoa-device-id-22");
 MODULE_ALIAS("aoa-device-id-35");
+MODULE_ALIAS("aoa-device-id-44");
 
 /* onyx with all but microphone connected */
 static struct codec_connection onyx_connections_nomic[] = {
@@ -361,6 +362,13 @@ static struct layout layouts[] = {
                .connections = tas_connections_nolineout,
          },
        },
+       /* PowerBook6,5 */
+       { .device_id = 44,
+         .codecs[0] = {
+               .name = "tas",
+               .connections = tas_connections_all,
+         },
+       },
        /* PowerBook6,7 */
        { .layout_id = 80,
          .codecs[0] = {
index 010658335881cf133b918d2159817267c375a522..15e76131b5015dd88cccf93ea08837694b1f03c7 100644 (file)
@@ -200,7 +200,8 @@ static int i2sbus_add_dev(struct macio_dev *macio,
                         * We probably cannot handle all device-id machines,
                         * so restrict to those we do handle for now.
                         */
-                       if (id && (*id == 22 || *id == 14 || *id == 35)) {
+                       if (id && (*id == 22 || *id == 14 || *id == 35 ||
+                                  *id == 44)) {
                                snprintf(dev->sound.modalias, 32,
                                         "aoa-device-id-%d", *id);
                                ok = 1;
index 51c4ba95a32d3961375a593d41afe538ab787760..1a9640254433e22ce61264a006fd6d52db0aad97 100644 (file)
@@ -250,7 +250,7 @@ config MSND_FIFOSIZE
 menuconfig SOUND_OSS
        tristate "OSS sound modules"
        depends on ISA_DMA_API && VIRT_TO_BUS
-       depends on !ISA_DMA_SUPPORT_BROKEN
+       depends on !GENERIC_ISA_DMA_SUPPORT_BROKEN
        help
          OSS is the Open Sound System suite of sound card drivers.  They make
          sound programming easier since they provide a common API.  Say Y or
index ac079f93c5354ae576eca7745047883e4b0d051c..ae85bbd2e6f842a8fcc0feac57ecc709cfd4b6b3 100644 (file)
@@ -606,6 +606,10 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
        return false;
 }
 
+/* check whether the NID is referred by any active paths */
+#define is_active_nid_for_any(codec, nid) \
+       is_active_nid(codec, nid, HDA_OUTPUT, 0)
+
 /* get the default amp value for the target state */
 static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid,
                                   int dir, unsigned int caps, bool enable)
@@ -759,7 +763,8 @@ static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path)
 
        for (i = 0; i < path->depth; i++) {
                hda_nid_t nid = path->path[i];
-               if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D3)) {
+               if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D3) &&
+                   !is_active_nid_for_any(codec, nid)) {
                        snd_hda_codec_write(codec, nid, 0,
                                            AC_VERB_SET_POWER_STATE,
                                            AC_PWRST_D3);
@@ -4157,7 +4162,7 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
                return power_state;
        if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER)
                return power_state;
-       if (is_active_nid(codec, nid, HDA_OUTPUT, 0))
+       if (is_active_nid_for_any(codec, nid))
                return power_state;
        return AC_PWRST_D3;
 }
index 6bf47f7326ad4964fc3b4f3403360df6ef52bfd8..59d2e91a9ab6d066d529a76bec681359d3b51f19 100644 (file)
@@ -3482,6 +3482,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
index 114f69a0c6290b43cb90ab591e02af3f14cb4f9d..306d0bc8455faeb202f4c13d87892355350fa0b3 100644 (file)
 
 /* AB8500_ADSLOTSELX */
 #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD  0x00
-#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD  0x01
-#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD  0x02
-#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD  0x03
-#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD  0x04
-#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD  0x05
-#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD  0x06
-#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD  0x07
-#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD   0x08
-#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0x0F
+#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD  0x10
+#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD  0x20
+#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD  0x30
+#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD  0x40
+#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD  0x50
+#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD  0x60
+#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD  0x70
+#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD   0x80
+#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0xF0
 #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
-#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x10
-#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x20
-#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x30
-#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x40
-#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x50
-#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x60
-#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x70
-#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN  0x80
-#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN        0xF0
+#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x01
+#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x02
+#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x03
+#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x04
+#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x05
+#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x06
+#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x07
+#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN  0x08
+#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN        0x0F
 #define AB8500_ADSLOTSELX_EVEN_SHIFT           0
 #define AB8500_ADSLOTSELX_ODD_SHIFT            4
 
index 41230ad1c3e038e8337c053f5948af2c60745eee..4a6f1daf911fc0685f16ea5f54fe774bc58581ac 100644 (file)
@@ -1488,17 +1488,17 @@ static int da7213_probe(struct snd_soc_codec *codec)
                                     DA7213_DMIC_DATA_SEL_SHIFT);
                        break;
                }
-               switch (pdata->dmic_data_sel) {
+               switch (pdata->dmic_samplephase) {
                case DA7213_DMIC_SAMPLE_ON_CLKEDGE:
                case DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE:
-                       dmic_cfg |= (pdata->dmic_data_sel <<
+                       dmic_cfg |= (pdata->dmic_samplephase <<
                                     DA7213_DMIC_SAMPLEPHASE_SHIFT);
                        break;
                }
-               switch (pdata->dmic_data_sel) {
+               switch (pdata->dmic_clk_rate) {
                case DA7213_DMIC_CLK_3_0MHZ:
                case DA7213_DMIC_CLK_1_5MHZ:
-                       dmic_cfg |= (pdata->dmic_data_sel <<
+                       dmic_cfg |= (pdata->dmic_clk_rate <<
                                     DA7213_DMIC_CLK_RATE_SHIFT);
                        break;
                }
index 8df2b6e1a1a6c7fa74cb6cb0b8f94afced8efc2e..370af0cbcc9a97393c695a55936fb22b6ec6e103 100644 (file)
@@ -667,6 +667,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
                /* On wm0010 only the CLKCTRL1 value is used */
                pll_rec.clkctrl1 = wm0010->pll_clkctrl1;
 
+               ret = -ENOMEM;
                len = pll_rec.length + 8;
                out = kzalloc(len, GFP_KERNEL);
                if (!out) {
index 902fab02b8512aab0288788b18781ff032da8798..c6fa03e2114ab985186cb8f86a3ee6f4317dc4bc 100644 (file)
@@ -540,11 +540,6 @@ static int imx_ssi_probe(struct platform_device *pdev)
        clk_prepare_enable(ssi->clk);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               ret = -ENODEV;
-               goto failed_get_resource;
-       }
-
        ssi->base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(ssi->base)) {
                ret = PTR_ERR(ssi->base);
@@ -633,7 +628,6 @@ failed_pdev_fiq_alloc:
        snd_soc_unregister_component(&pdev->dev);
 failed_register:
        release_mem_region(res->start, resource_size(res));
-failed_get_resource:
        clk_disable_unprepare(ssi->clk);
 failed_clk:
 
index befe68f59285df63b653436a4d2d0dd2d1202ec7..4c9dad3263c5f7b754d108b3bf66a3ebdb6d67f3 100644 (file)
@@ -471,11 +471,6 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
        dev_set_drvdata(&pdev->dev, priv);
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem) {
-               dev_err(&pdev->dev, "platform_get_resource failed\n");
-               return -ENXIO;
-       }
-
        priv->io = devm_ioremap_resource(&pdev->dev, mem);
        if (IS_ERR(priv->io))
                return PTR_ERR(priv->io);
index 135c7687106303fe53a156decdf434150aaba02e..5f761ab34c0140b1b62673e46fc59659488b8cc7 100644 (file)
@@ -116,21 +116,22 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
 }
 
 static void proc_dump_ep_status(struct snd_usb_substream *subs,
-                               struct snd_usb_endpoint *ep,
+                               struct snd_usb_endpoint *data_ep,
+                               struct snd_usb_endpoint *sync_ep,
                                struct snd_info_buffer *buffer)
 {
-       if (!ep)
+       if (!data_ep)
                return;
-       snd_iprintf(buffer, "    Packet Size = %d\n", ep->curpacksize);
+       snd_iprintf(buffer, "    Packet Size = %d\n", data_ep->curpacksize);
        snd_iprintf(buffer, "    Momentary freq = %u Hz (%#x.%04x)\n",
                    subs->speed == USB_SPEED_FULL
-                   ? get_full_speed_hz(ep->freqm)
-                   : get_high_speed_hz(ep->freqm),
-                   ep->freqm >> 16, ep->freqm & 0xffff);
-       if (ep->freqshift != INT_MIN) {
-               int res = 16 - ep->freqshift;
+                   ? get_full_speed_hz(data_ep->freqm)
+                   : get_high_speed_hz(data_ep->freqm),
+                   data_ep->freqm >> 16, data_ep->freqm & 0xffff);
+       if (sync_ep && data_ep->freqshift != INT_MIN) {
+               int res = 16 - data_ep->freqshift;
                snd_iprintf(buffer, "    Feedback Format = %d.%d\n",
-                           (ep->syncmaxsize > 3 ? 32 : 24) - res, res);
+                           (sync_ep->syncmaxsize > 3 ? 32 : 24) - res, res);
        }
 }
 
@@ -140,8 +141,7 @@ static void proc_dump_substream_status(struct snd_usb_substream *subs, struct sn
                snd_iprintf(buffer, "  Status: Running\n");
                snd_iprintf(buffer, "    Interface = %d\n", subs->interface);
                snd_iprintf(buffer, "    Altset = %d\n", subs->altset_idx);
-               proc_dump_ep_status(subs, subs->data_endpoint, buffer);
-               proc_dump_ep_status(subs, subs->sync_endpoint, buffer);
+               proc_dump_ep_status(subs, subs->data_endpoint, subs->sync_endpoint, buffer);
        } else {
                snd_iprintf(buffer, "  Status: Stop\n");
        }