Merge tag 'tegra-for-3.17-pcie-regulators' of git://git.kernel.org/pub/scm/linux...
authorOlof Johansson <olof@lixom.net>
Sat, 19 Jul 2014 19:35:45 +0000 (12:35 -0700)
committerOlof Johansson <olof@lixom.net>
Sat, 19 Jul 2014 19:35:45 +0000 (12:35 -0700)
Merge "ARM: tegra: rework PCIe regulators" from Thierry Reding:

This branch reworks the set of regulators that the Tegra PCIe driver
uses, so that the driver and DT bindings more correctly model what's
really going on in HW. For backwards-compatibility the driver will
fallback to using the old set of regulators if the new ones can't be
found.

I've made this a separate branch in case it needs to be pulled into the
PCIe tree to resolve any conflicts.

* tag 'tegra-for-3.17-pcie-regulators' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  ARM: tegra: Remove legacy PCIe power supply properties
  PCI: tegra: Remove deprecated power supply properties
  PCI: tegra: Implement accurate power supply scheme
  ARM: tegra: Add new PCIe regulator properties
  PCI: tegra: Overhaul regulator usage

Signed-off-by: Olof Johansson <olof@lixom.net>
862 files changed:
CREDITS
Documentation/DocBook/media/Makefile
Documentation/accounting/getdelays.c
Documentation/devicetree/bindings/arm/armada-38x.txt
Documentation/devicetree/bindings/arm/l2cc.txt
Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt
Documentation/devicetree/bindings/arm/spear-misc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt
Documentation/devicetree/bindings/i2c/i2c-rk3x.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pci/spear13xx-pcie.txt [new file with mode: 0644]
Documentation/devicetree/bindings/phy/st-spear-miphy.txt [new file with mode: 0644]
Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/email-clients.txt
Documentation/hwmon/ntc_thermistor
Documentation/kbuild/makefiles.txt
Documentation/kernel-parameters.txt
Documentation/memory-hotplug.txt
Documentation/ptp/testptp.c
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/sysctl/kernel.txt
Documentation/sysctl/vm.txt
Documentation/thermal/nouveau_thermal
MAINTAINERS
Makefile
arch/arc/include/asm/cache.h
arch/arc/include/uapi/asm/ptrace.h
arch/arc/kernel/ctx_sw_asm.S
arch/arc/kernel/devtree.c
arch/arc/kernel/head.S
arch/arc/kernel/ptrace.c
arch/arc/kernel/smp.c
arch/arc/kernel/vmlinux.lds.S
arch/arc/mm/cache_arc700.c
arch/arm/Kconfig
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/armada-375-db.dts
arch/arm/boot/dts/armada-380.dtsi
arch/arm/boot/dts/armada-385-db.dts
arch/arm/boot/dts/armada-385-rd.dts
arch/arm/boot/dts/armada-385.dtsi
arch/arm/boot/dts/armada-38x.dtsi
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
arch/arm/boot/dts/at91sam9261.dtsi
arch/arm/boot/dts/at91sam9261ek.dts
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts
arch/arm/boot/dts/imx53-m53evk.dts
arch/arm/boot/dts/imx6dl-hummingboard.dts
arch/arm/boot/dts/imx6q-gw51xx.dts
arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
arch/arm/boot/dts/imx6qdl-microsom.dtsi
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
arch/arm/boot/dts/spear1310-evb.dts
arch/arm/boot/dts/spear1310.dtsi
arch/arm/boot/dts/spear1340-evb.dts
arch/arm/boot/dts/spear1340.dtsi
arch/arm/boot/dts/spear13xx.dtsi
arch/arm/boot/dts/stih415.dtsi
arch/arm/boot/dts/stih416-b2020-revE.dts [deleted file]
arch/arm/boot/dts/stih416-b2020e.dts [new file with mode: 0644]
arch/arm/boot/dts/stih416.dtsi
arch/arm/common/scoop.c
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mvebu_v7_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/spear13xx_defconfig
arch/arm/include/asm/ftrace.h
arch/arm/include/asm/mcpm.h
arch/arm/include/asm/thread_info.h
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/ptrace.c
arch/arm/mach-at91/at91sam9263.c
arch/arm/mach-at91/at91sam9263_devices.c
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/at91sam9rl.c
arch/arm/mach-at91/at91sam9rl_devices.c
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/board.h
arch/arm/mach-at91/leds.c
arch/arm/mach-bcm/Kconfig
arch/arm/mach-berlin/Kconfig
arch/arm/mach-cns3xxx/Kconfig
arch/arm/mach-davinci/Kconfig
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/hotplug.c
arch/arm/mach-exynos/mcpm-exynos.c
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/pm.c
arch/arm/mach-highbank/Kconfig
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/clk-imx6sl.c
arch/arm/mach-integrator/Kconfig
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-keystone/Kconfig
arch/arm/mach-moxart/Kconfig
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-nomadik/Kconfig
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/common.h
arch/arm/mach-prima2/Kconfig
arch/arm/mach-qcom/Kconfig
arch/arm/mach-s3c24xx/Kconfig
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s5p64x0/Kconfig
arch/arm/mach-s5pc100/Kconfig
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-sa1100/collie.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-spear/Kconfig
arch/arm/mach-spear/include/mach/spear.h
arch/arm/mach-spear/spear1340.c
arch/arm/mach-spear/spear13xx.c
arch/arm/mach-sti/Kconfig
arch/arm/mach-tegra/Kconfig
arch/arm/mach-u300/Kconfig
arch/arm/mach-ux500/Kconfig
arch/arm/mach-vexpress/Kconfig
arch/arm/mach-vt8500/Kconfig
arch/arm/mach-zynq/Kconfig
arch/arm/mm/Kconfig
arch/arm/mm/cache-l2x0.c
arch/arm/mm/nommu.c
arch/arm/mm/proc-arm925.S
arch/arm/plat-samsung/Kconfig
arch/arm64/Kconfig
arch/arm64/boot/dts/apm-mustang.dts
arch/arm64/boot/dts/apm-storm.dtsi
arch/arm64/configs/defconfig
arch/arm64/crypto/ghash-ce-core.S
arch/arm64/crypto/ghash-ce-glue.c
arch/arm64/include/asm/Kbuild
arch/arm64/include/asm/dma-mapping.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/uapi/asm/posix_types.h [new file with mode: 0644]
arch/arm64/include/uapi/asm/sigcontext.h
arch/arm64/kernel/entry-ftrace.S
arch/arm64/kernel/entry.S
arch/arm64/kernel/ptrace.c
arch/arm64/mm/init.c
arch/avr32/boards/atngw100/mrmt.c
arch/avr32/boards/favr-32/setup.c
arch/avr32/boards/merisc/setup.c
arch/avr32/configs/atngw100_mrmt_defconfig
arch/avr32/configs/atstk1002_defconfig
arch/avr32/configs/atstk1003_defconfig
arch/avr32/configs/atstk1004_defconfig
arch/avr32/configs/atstk1006_defconfig
arch/avr32/configs/favr-32_defconfig
arch/avr32/configs/merisc_defconfig
arch/avr32/mach-at32ap/at32ap700x.c
arch/ia64/hp/common/sba_iommu.c
arch/ia64/include/uapi/asm/fcntl.h
arch/mips/Kconfig
arch/mips/include/asm/sigcontext.h
arch/mips/include/asm/uasm.h
arch/mips/include/uapi/asm/inst.h
arch/mips/include/uapi/asm/sigcontext.h
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/irq-msc01.c
arch/mips/kernel/pm-cps.c
arch/mips/kernel/r4k_fpu.S
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/smp-cps.c
arch/mips/math-emu/ieee754.c
arch/mips/mm/uasm-micromips.c
arch/mips/mm/uasm-mips.c
arch/mips/mm/uasm.c
arch/mips/net/bpf_jit.c
arch/powerpc/Kconfig.debug
arch/powerpc/include/asm/code-patching.h
arch/powerpc/include/asm/opal.h
arch/powerpc/include/asm/swab.h
arch/powerpc/kernel/ftrace.c
arch/powerpc/kernel/iomap.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/module_64.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_init_check.sh
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/platforms/cell/cbe_thermal.c
arch/powerpc/platforms/powernv/Makefile
arch/powerpc/platforms/powernv/opal-takeover.S [deleted file]
arch/powerpc/sysdev/dart_iommu.c
arch/s390/configs/default_defconfig
arch/s390/configs/gcov_defconfig
arch/s390/configs/performance_defconfig
arch/s390/configs/zfcpdump_defconfig
arch/s390/defconfig
arch/s390/include/asm/mmu_context.h
arch/s390/include/asm/switch_to.h
arch/s390/include/uapi/asm/ucontext.h
arch/s390/kernel/compat_linux.h
arch/sparc/crypto/aes_glue.c
arch/sparc/include/asm/atomic_32.h
arch/sparc/include/asm/atomic_64.h
arch/sparc/include/asm/auxio.h
arch/sparc/include/asm/auxio_32.h
arch/sparc/include/asm/auxio_64.h
arch/sparc/include/asm/bitext.h
arch/sparc/include/asm/bitops_32.h
arch/sparc/include/asm/bitops_64.h
arch/sparc/include/asm/btext.h
arch/sparc/include/asm/bug.h
arch/sparc/include/asm/cacheflush_32.h
arch/sparc/include/asm/cacheflush_64.h
arch/sparc/include/asm/checksum_32.h
arch/sparc/include/asm/checksum_64.h
arch/sparc/include/asm/cmpxchg_32.h
arch/sparc/include/asm/cmpxchg_64.h
arch/sparc/include/asm/cpudata.h
arch/sparc/include/asm/cpudata_64.h
arch/sparc/include/asm/delay_32.h
arch/sparc/include/asm/delay_64.h
arch/sparc/include/asm/device.h
arch/sparc/include/asm/dma-mapping.h
arch/sparc/include/asm/ebus_dma.h
arch/sparc/include/asm/floppy_32.h
arch/sparc/include/asm/floppy_64.h
arch/sparc/include/asm/ftrace.h
arch/sparc/include/asm/highmem.h
arch/sparc/include/asm/hvtramp.h
arch/sparc/include/asm/hypervisor.h
arch/sparc/include/asm/idprom.h
arch/sparc/include/asm/io-unit.h
arch/sparc/include/asm/io_32.h
arch/sparc/include/asm/io_64.h
arch/sparc/include/asm/iommu_32.h
arch/sparc/include/asm/iommu_64.h
arch/sparc/include/asm/irq_32.h
arch/sparc/include/asm/irq_64.h
arch/sparc/include/asm/irqflags_32.h
arch/sparc/include/asm/kdebug_64.h
arch/sparc/include/asm/kgdb.h
arch/sparc/include/asm/kprobes.h
arch/sparc/include/asm/ldc.h
arch/sparc/include/asm/leon.h
arch/sparc/include/asm/leon_pci.h
arch/sparc/include/asm/mc146818rtc.h
arch/sparc/include/asm/mdesc.h
arch/sparc/include/asm/mmu_64.h
arch/sparc/include/asm/mmu_context_64.h
arch/sparc/include/asm/nmi.h
arch/sparc/include/asm/oplib_32.h
arch/sparc/include/asm/oplib_64.h
arch/sparc/include/asm/page.h
arch/sparc/include/asm/page_64.h
arch/sparc/include/asm/pci_64.h
arch/sparc/include/asm/pcic.h
arch/sparc/include/asm/pcr.h
arch/sparc/include/asm/pgalloc_32.h
arch/sparc/include/asm/pgalloc_64.h
arch/sparc/include/asm/pgtable_32.h
arch/sparc/include/asm/pgtable_64.h
arch/sparc/include/asm/processor_32.h
arch/sparc/include/asm/processor_64.h
arch/sparc/include/asm/prom.h
arch/sparc/include/asm/ptrace.h
arch/sparc/include/asm/setup.h
arch/sparc/include/asm/sfp-machine_32.h
arch/sparc/include/asm/smp_32.h
arch/sparc/include/asm/smp_64.h
arch/sparc/include/asm/spitfire.h
arch/sparc/include/asm/stacktrace.h
arch/sparc/include/asm/starfire.h
arch/sparc/include/asm/string_32.h
arch/sparc/include/asm/string_64.h
arch/sparc/include/asm/switch_to_32.h
arch/sparc/include/asm/switch_to_64.h
arch/sparc/include/asm/syscalls.h
arch/sparc/include/asm/timer_32.h
arch/sparc/include/asm/timer_64.h
arch/sparc/include/asm/tlb_64.h
arch/sparc/include/asm/tlbflush_64.h
arch/sparc/include/asm/topology_64.h
arch/sparc/include/asm/trap_block.h
arch/sparc/include/asm/uaccess.h
arch/sparc/include/asm/uaccess_32.h
arch/sparc/include/asm/uaccess_64.h
arch/sparc/include/asm/vio.h
arch/sparc/include/asm/visasm.h
arch/sparc/include/asm/xor_64.h
arch/sparc/kernel/Makefile
arch/sparc/kernel/audit.c
arch/sparc/kernel/auxio_32.c
arch/sparc/kernel/btext.c
arch/sparc/kernel/compat_audit.c
arch/sparc/kernel/cpu.c
arch/sparc/kernel/cpumap.h
arch/sparc/kernel/devices.c
arch/sparc/kernel/entry.h
arch/sparc/kernel/iommu.c
arch/sparc/kernel/iommu_common.h
arch/sparc/kernel/ioport.c
arch/sparc/kernel/irq.h
arch/sparc/kernel/irq_32.c
arch/sparc/kernel/kernel.h
arch/sparc/kernel/kgdb_64.c
arch/sparc/kernel/kprobes.c
arch/sparc/kernel/leon_kernel.c
arch/sparc/kernel/leon_pci.c
arch/sparc/kernel/leon_pci_grpci1.c
arch/sparc/kernel/leon_pci_grpci2.c
arch/sparc/kernel/leon_pmc.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/of_device_common.c
arch/sparc/kernel/pci.c
arch/sparc/kernel/pci_impl.h
arch/sparc/kernel/pci_sun4v.h
arch/sparc/kernel/pcic.c
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/process_32.c
arch/sparc/kernel/process_64.c
arch/sparc/kernel/prom.h
arch/sparc/kernel/prom_64.c
arch/sparc/kernel/psycho_common.h
arch/sparc/kernel/ptrace_32.c
arch/sparc/kernel/setup_32.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/smp_32.c
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/sun4d_irq.c
arch/sparc/kernel/sys_sparc32.c
arch/sparc/kernel/sys_sparc_32.c
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/kernel/systbls.h
arch/sparc/kernel/tadpole.c [deleted file]
arch/sparc/kernel/time_32.c
arch/sparc/kernel/traps_32.c
arch/sparc/kernel/traps_64.c
arch/sparc/kernel/unaligned_32.c
arch/sparc/kernel/unaligned_64.c
arch/sparc/kernel/windows.c
arch/sparc/lib/Makefile
arch/sparc/math-emu/sfp-util_32.h
arch/sparc/math-emu/sfp-util_64.h
arch/sparc/mm/fault_32.c
arch/sparc/mm/fault_64.c
arch/sparc/mm/init_32.c
arch/sparc/mm/init_64.c
arch/sparc/mm/init_64.h
arch/sparc/mm/io-unit.c
arch/sparc/mm/iommu.c
arch/sparc/mm/leon_mm.c
arch/sparc/mm/mm_32.h [new file with mode: 0644]
arch/sparc/mm/srmmu.c
arch/sparc/mm/srmmu.h [deleted file]
arch/sparc/mm/tsb.c
arch/sparc/prom/misc_64.c
arch/unicore32/Kconfig
arch/unicore32/include/asm/io.h
arch/unicore32/include/asm/pgtable.h
arch/unicore32/include/asm/ptrace.h
arch/unicore32/kernel/clock.c
arch/unicore32/kernel/ksyms.c
arch/unicore32/kernel/ksyms.h
arch/unicore32/kernel/module.c
arch/unicore32/kernel/process.c
arch/unicore32/kernel/setup.c
arch/unicore32/mm/alignment.c
arch/unicore32/mm/proc-syms.c
arch/x86/Kconfig
arch/x86/boot/compressed/aslr.c
arch/x86/include/asm/irq.h
arch/x86/kernel/apic/hw_nmi.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/signal.c
arch/x86/kernel/traps.c
arch/x86/vdso/Makefile
arch/x86/vdso/vclock_gettime.c
arch/x86/vdso/vdso-fakesections.c
arch/x86/vdso/vdso-layout.lds.S
arch/x86/vdso/vdso.lds.S
arch/x86/vdso/vdso2c.c
arch/x86/vdso/vdso2c.h
arch/x86/vdso/vdso32/vdso-fakesections.c [new file with mode: 0644]
arch/x86/vdso/vdsox32.lds.S
arch/x86/xen/enlighten.c
arch/x86/xen/setup.c
arch/x86/xen/xen-ops.h
block/bio.c
block/blk-cgroup.c
block/blk-cgroup.h
block/blk-core.c
block/blk-flush.c
block/blk-merge.c
block/blk-mq-tag.c
block/blk-mq-tag.h
block/blk-mq.c
block/blk.h
block/elevator.c
drivers/acpi/acpi_lpss.c
drivers/acpi/battery.c
drivers/acpi/osl.c
drivers/acpi/tables.c
drivers/base/dma-contiguous.c
drivers/block/drbd/drbd_receiver.c
drivers/block/floppy.c
drivers/block/null_blk.c
drivers/block/rbd.c
drivers/bus/Kconfig
drivers/char/random.c
drivers/clocksource/exynos_mct.c
drivers/cpufreq/Kconfig
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpuidle/cpuidle-armada-370-xp.c
drivers/firmware/efi/efi-pstore.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/fdt.c
drivers/gpu/drm/drm_drv.c [changed mode: 0644->0755]
drivers/gpu/drm/drm_modeset_lock.c
drivers/gpu/drm/exynos/exynos_drm_dpi.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/exynos/regs-mixer.h
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/msm/hdmi/hdmi.c
drivers/gpu/drm/msm/hdmi/hdmi.h
drivers/gpu/drm/msm/hdmi/hdmi_connector.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_fbdev.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/msm/msm_iommu.c
drivers/gpu/drm/msm/msm_mmu.h
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
drivers/gpu/drm/nouveau/core/engine/disp/base.c
drivers/gpu/drm/nouveau/core/engine/disp/dport.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h
drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc
drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h
drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c
drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/r500_reg.h
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/hwmon/Kconfig
drivers/hwmon/gpio-fan.c
drivers/hwmon/ntc_thermistor.c
drivers/hwmon/w83l786ng.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-rk3x.c [new file with mode: 0644]
drivers/i2c/busses/i2c-sun6i-p2wi.c [new file with mode: 0644]
drivers/iio/adc/at91_adc.c
drivers/iio/adc/men_z188_adc.c
drivers/iio/adc/twl4030-madc.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/magnetometer/ak8975.c
drivers/iio/pressure/mpl3115.c
drivers/iommu/amd_iommu_v2.c
drivers/iommu/intel-iommu.c
drivers/isdn/hisax/Kconfig
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/leds-atmel-pwm.c [deleted file]
drivers/macintosh/smu.c
drivers/memstick/host/rtsx_pci_ms.c
drivers/mfd/Kconfig
drivers/mfd/ab8500-core.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/atmel_pwm.c [deleted file]
drivers/misc/vexpress-syscfg.c
drivers/misc/vmw_balloon.c
drivers/net/bonding/bond_main.c
drivers/net/can/slcan.c
drivers/net/ethernet/allwinner/sun4i-emac.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/dec/tulip/timer.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/marvell/skge.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/tile/tilegx.c
drivers/net/hyperv/netvsc.c
drivers/net/ieee802154/at86rf230.c
drivers/net/phy/at803x.c
drivers/net/phy/phy.c
drivers/net/slip/slip.c
drivers/net/slip/slip.h
drivers/net/usb/huawei_cdc_ncm.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_ethtool.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/util.h
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/xen-netback/common.h
drivers/net/xen-netback/interface.c
drivers/net/xen-netback/xenbus.c
drivers/net/xen-netfront.c
drivers/of/base.c
drivers/of/of_mdio.c
drivers/of/platform.c
drivers/pci/host/Kconfig
drivers/pci/host/Makefile
drivers/pci/host/pcie-spear13xx.c [new file with mode: 0644]
drivers/phy/Kconfig
drivers/phy/Makefile
drivers/phy/phy-spear1310-miphy.c [new file with mode: 0644]
drivers/phy/phy-spear1340-miphy.c [new file with mode: 0644]
drivers/ptp/Kconfig
drivers/pwm/Kconfig
drivers/regulator/as3722-regulator.c
drivers/regulator/bcm590xx-regulator.c
drivers/regulator/ltc3589.c
drivers/regulator/palmas-regulator.c
drivers/regulator/tps65218-regulator.c
drivers/remoteproc/Kconfig
drivers/rtc/rtc-puv3.c
drivers/s390/block/dcssblk.c
drivers/s390/char/Makefile
drivers/s390/char/sclp_vt220.c
drivers/s390/char/vmlogrdr.c
drivers/s390/char/vmwatchdog.c [deleted file]
drivers/s390/cio/airq.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/cio.c
drivers/s390/cio/device.c
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_debug.h
drivers/s390/cio/qdio_main.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/zcrypt_api.c
drivers/scsi/mvsas/mv_94xx.c
drivers/scsi/mvsas/mv_94xx.h
drivers/spi/spi-pxa2xx-dma.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-qup.c
drivers/spi/spi-sh-sci.c
drivers/staging/android/timed_output.c
drivers/staging/comedi/Kconfig
drivers/staging/iio/Kconfig
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/iio/light/tsl2x7x_core.c
drivers/staging/imx-drm/parallel-display.c
drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c
drivers/staging/rtl8723au/os_dep/os_intfs.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_auth.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/iscsi/iscsi_target_util.c
drivers/target/loopback/tcm_loop.c
drivers/target/target_core_device.c
drivers/tc/tc.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_early.c
drivers/tty/serial/altera_uart.c
drivers/tty/serial/amba-pl010.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/bcm63xx_uart.c
drivers/tty/serial/bfin_uart.c
drivers/tty/serial/dz.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/efm32-uart.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/ip22zilog.c
drivers/tty/serial/m32r_sio.c
drivers/tty/serial/max310x.c
drivers/tty/serial/mcf.c
drivers/tty/serial/mfd.c
drivers/tty/serial/mpsc.c
drivers/tty/serial/msm_serial.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/netx-serial.c
drivers/tty/serial/pmac_zilog.c
drivers/tty/serial/pnx8xxx_uart.c
drivers/tty/serial/pxa.c
drivers/tty/serial/samsung.c
drivers/tty/serial/sb1250-duart.c
drivers/tty/serial/sccnxp.c
drivers/tty/serial/serial_ks8695.c
drivers/tty/serial/serial_txx9.c
drivers/tty/serial/sirfsoc_uart.c
drivers/tty/serial/st-asc.c
drivers/tty/serial/sunsab.c
drivers/tty/serial/sunsu.c
drivers/tty/serial/sunzilog.c
drivers/tty/serial/ucc_uart.c
drivers/tty/serial/vr41xx_siu.c
drivers/tty/serial/zs.c
drivers/tty/vt/vt.c
drivers/uio/uio.c
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/port.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/xhci-hub.c
drivers/usb/misc/usbtest.c
drivers/vhost/net.c
drivers/vhost/scsi.c
drivers/video/backlight/Kconfig
drivers/video/backlight/Makefile
drivers/video/backlight/atmel-pwm-bl.c [deleted file]
drivers/video/console/dummycon.c
drivers/video/console/vgacon.c
drivers/video/fbdev/offb.c
drivers/w1/masters/mxc_w1.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/diag288_wdt.c [new file with mode: 0644]
drivers/xen/grant-table.c
fs/aio.c
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.h
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/locking.c
fs/btrfs/scrub.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/cifs/cifs_unicode.c
fs/cifs/cifsfs.c
fs/cifs/link.c
fs/eventpoll.c
fs/locks.c
fs/nfs/inode.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4namespace.c
fs/nfs/nfs4proc.c
fs/nfs/write.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/dlm/dlmthread.c
fs/ocfs2/dlm/dlmunlock.c
fs/ocfs2/namei.c
fs/ocfs2/ocfs2_trace.h
fs/ocfs2/refcounttree.c
fs/ocfs2/super.c
include/acpi/processor.h
include/drm/i915_pciids.h
include/drm/i915_powerwell.h
include/dt-bindings/clock/imx6sl-clock.h
include/dt-bindings/clock/stih415-clks.h
include/dt-bindings/clock/stih416-clks.h
include/linux/atmel-pwm-bl.h [deleted file]
include/linux/atmel_pwm.h [deleted file]
include/linux/bio.h
include/linux/blk-mq.h
include/linux/blkdev.h
include/linux/elevator.h
include/linux/fs.h
include/linux/nmi.h
include/linux/page-flags.h
include/linux/phy.h
include/linux/profile.h
include/linux/regulator/consumer.h
include/linux/socket.h
include/linux/suspend.h
include/linux/uio.h
include/net/netfilter/nf_tables.h
include/net/sock.h
include/sound/core.h
include/trace/ftrace.h
include/trace/syscall.h
include/uapi/linux/perf_event.h
include/uapi/sound/compress_offload.h
include/uapi/sound/compress_params.h
kernel/context_tracking.c
kernel/events/core.c
kernel/fork.c
kernel/kexec.c
kernel/locking/rtmutex-debug.h
kernel/locking/rtmutex.c
kernel/locking/rtmutex.h
kernel/power/hibernate.c
kernel/power/main.c
kernel/power/user.c
kernel/smp.c
kernel/sysctl.c
kernel/tracepoint.c
kernel/watchdog.c
lib/Kconfig.debug
lib/iovec.c
lib/lz4/lz4_decompress.c
lib/lzo/lzo1x_decompress_safe.c
lib/swiotlb.c
mm/huge_memory.c
mm/hugetlb.c
mm/ksm.c
mm/mempolicy.c
mm/migrate.c
mm/nommu.c
mm/page_alloc.c
mm/rmap.c
mm/shmem.c
mm/slab.c
net/8021q/vlan_core.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bluetooth/smp.c
net/core/dst.c
net/core/filter.c
net/core/iovec.c
net/core/skbuff.c
net/ipv4/ip_tunnel.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_input.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_nat_core.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_compat.c
net/netfilter/nft_nat.c
net/sctp/sysctl.c
net/sunrpc/auth.c
samples/trace_events/trace-events-sample.h
scripts/checkpatch.pl
scripts/package/builddeb
scripts/package/buildtar
scripts/recordmcount.h
sound/core/control.c
sound/core/init.c
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_i915.c
sound/pci/hda/hda_i915.h
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/sigmadsp-i2c.c [new file with mode: 0644]
sound/soc/codecs/sigmadsp-regmap.c [new file with mode: 0644]
sound/soc/codecs/sigmadsp.c
sound/soc/codecs/sigmadsp.h
sound/soc/fsl/fsl_dma.c
sound/soc/fsl/fsl_spdif.c
sound/soc/pxa/Kconfig
sound/soc/sh/rcar/core.c
sound/soc/soc-dapm.c
sound/usb/card.c
sound/usb/endpoint.c
sound/usb/endpoint.h
tools/lib/traceevent/event-parse.c
tools/lib/traceevent/event-parse.h
tools/lib/traceevent/event-plugin.c
tools/lib/traceevent/plugin_function.c
tools/perf/Documentation/perf-report.txt
tools/perf/Documentation/perf-timechart.txt
tools/perf/Makefile.perf
tools/perf/builtin-inject.c
tools/perf/builtin-probe.c
tools/perf/config/Makefile
tools/perf/perf.c
tools/perf/tests/builtin-test.c
tools/perf/tests/dso-data.c
tools/perf/tests/dwarf-unwind.c
tools/perf/tests/make
tools/perf/tests/tests.h
tools/perf/util/dso.c
tools/perf/util/dso.h
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/evsel.c
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/machine.c
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/perf_regs.c
tools/perf/util/perf_regs.h
tools/perf/util/probe-event.c
tools/perf/util/probe-finder.c
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/unwind-libunwind.c
tools/perf/util/util.c
tools/perf/util/util.h
tools/testing/selftests/powerpc/tm/Makefile
tools/testing/selftests/powerpc/tm/tm-resched-dscr.c

diff --git a/CREDITS b/CREDITS
index c322dcf..28ee151 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -9,6 +9,10 @@
                        Linus
 ----------
 
+M: Matt Mackal
+E: mpm@selenic.com
+D: SLOB slab allocator
+
 N: Matti Aarnio
 E: mea@nic.funet.fi
 D: Alpha systems hacking, IPv6 and other network related stuff
index 1d27f0a..639e748 100644 (file)
@@ -202,8 +202,8 @@ $(MEDIA_OBJ_DIR)/%: $(MEDIA_SRC_DIR)/%.b64
 
 $(MEDIA_OBJ_DIR)/v4l2.xml: $(OBJIMGFILES)
        @$($(quiet)gen_xml)
-       @(ln -sf $(MEDIA_SRC_DIR)/v4l/*xml $(MEDIA_OBJ_DIR)/)
-       @(ln -sf $(MEDIA_SRC_DIR)/dvb/*xml $(MEDIA_OBJ_DIR)/)
+       @(ln -sf `cd $(MEDIA_SRC_DIR) && /bin/pwd`/v4l/*xml $(MEDIA_OBJ_DIR)/)
+       @(ln -sf `cd $(MEDIA_SRC_DIR) && /bin/pwd`/dvb/*xml $(MEDIA_OBJ_DIR)/)
 
 $(MEDIA_OBJ_DIR)/videodev2.h.xml: $(srctree)/include/uapi/linux/videodev2.h $(MEDIA_OBJ_DIR)/v4l2.xml
        @$($(quiet)gen_xml)
index c6a06b7..f405780 100644 (file)
@@ -314,6 +314,7 @@ int main(int argc, char *argv[])
                        break;
                case 'm':
                        strncpy(cpumask, optarg, sizeof(cpumask));
+                       cpumask[sizeof(cpumask) - 1] = '\0';
                        maskset = 1;
                        printf("cpumask %s maskset %d\n", cpumask, maskset);
                        break;
index 11f2330..ad9f8ed 100644 (file)
@@ -6,5 +6,15 @@ following property:
 
 Required root node property:
 
- - compatible: must contain either "marvell,armada380" or
-   "marvell,armada385" depending on the variant of the SoC being used.
+ - compatible: must contain "marvell,armada380"
+
+In addition, boards using the Marvell Armada 385 SoC shall have the
+following property before the previous one:
+
+Required root node property:
+
+compatible: must contain "marvell,armada385"
+
+Example:
+
+compatible = "marvell,a385-rd", "marvell,armada385", "marvell,armada380";
index b513cb8..af527ee 100644 (file)
@@ -40,6 +40,9 @@ Optional properties:
 - arm,filter-ranges : <start length> Starting address and length of window to
   filter. Addresses in the filter window are directed to the M1 port. Other
   addresses will go to the M0 port.
+- arm,io-coherent : indicates that the system is operating in an hardware
+  I/O coherent mode. Valid only when the arm,pl310-cache compatible
+  string is used.
 - interrupts : 1 combined interrupt.
 - cache-id-part: cache id part number to be used if it is not present
   on hardware
index 5d49f2b..832fe8c 100644 (file)
@@ -48,7 +48,7 @@ adc@12D10000 {
 
        /* NTC thermistor is a hwmon device */
        ncp15wb473@0 {
-               compatible = "ntc,ncp15wb473";
+               compatible = "murata,ncp15wb473";
                pullup-uv = <1800000>;
                pullup-ohm = <47000>;
                pulldown-ohm = <0>;
diff --git a/Documentation/devicetree/bindings/arm/spear-misc.txt b/Documentation/devicetree/bindings/arm/spear-misc.txt
new file mode 100644 (file)
index 0000000..cf64982
--- /dev/null
@@ -0,0 +1,9 @@
+SPEAr Misc configuration
+===========================
+SPEAr SOCs have some miscellaneous registers which are used to configure
+few properties of different peripheral controllers.
+
+misc node required properties:
+
+- compatible Should be "st,spear1340-misc", "syscon".
+- reg: Address range of misc space upto 8K
index c6f6667..b117b2e 100644 (file)
@@ -3,11 +3,19 @@ NTC Thermistor hwmon sensors
 
 Requires node properties:
 - "compatible" value : one of
-       "ntc,ncp15wb473"
-       "ntc,ncp18wb473"
-       "ntc,ncp21wb473"
-       "ntc,ncp03wb473"
-       "ntc,ncp15wl333"
+       "murata,ncp15wb473"
+       "murata,ncp18wb473"
+       "murata,ncp21wb473"
+       "murata,ncp03wb473"
+       "murata,ncp15wl333"
+
+/* Usage of vendor name "ntc" is deprecated */
+<DEPRECATED>   "ntc,ncp15wb473"
+<DEPRECATED>   "ntc,ncp18wb473"
+<DEPRECATED>   "ntc,ncp21wb473"
+<DEPRECATED>   "ntc,ncp03wb473"
+<DEPRECATED>   "ntc,ncp15wl333"
+
 - "pullup-uv"  Pull up voltage in micro volts
 - "pullup-ohm" Pull up resistor value in ohms
 - "pulldown-ohm" Pull down resistor value in ohms
@@ -21,7 +29,7 @@ Read more about iio bindings at
 
 Example:
        ncp15wb473@0 {
-               compatible = "ntc,ncp15wb473";
+               compatible = "murata,ncp15wb473";
                pullup-uv = <1800000>;
                pullup-ohm = <47000>;
                pulldown-ohm = <0>;
diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt
new file mode 100644 (file)
index 0000000..dde6c22
--- /dev/null
@@ -0,0 +1,42 @@
+* Rockchip RK3xxx I2C controller
+
+This driver interfaces with the native I2C controller present in Rockchip
+RK3xxx SoCs.
+
+Required properties :
+
+ - reg : Offset and length of the register set for the device
+ - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c" or
+               "rockchip,rk3288-i2c".
+ - interrupts : interrupt number
+ - clocks : parent clock
+
+Required on RK3066, RK3188 :
+
+ - rockchip,grf : the phandle of the syscon node for the general register
+                 file (GRF)
+ - on those SoCs an alias with the correct I2C bus ID (bit offset in the GRF)
+   is also required.
+
+Optional properties :
+
+ - clock-frequency : SCL frequency to use (in Hz). If omitted, 100kHz is used.
+
+Example:
+
+aliases {
+       i2c0 = &i2c0;
+}
+
+i2c0: i2c@2002d000 {
+       compatible = "rockchip,rk3188-i2c";
+       reg = <0x2002d000 0x1000>;
+       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       rockchip,grf = <&grf>;
+
+       clock-names = "i2c";
+       clocks = <&cru PCLK_I2C0>;
+};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt b/Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt
new file mode 100644 (file)
index 0000000..6b76548
--- /dev/null
@@ -0,0 +1,41 @@
+
+* Allwinner P2WI (Push/Pull 2 Wire Interface) controller
+
+Required properties :
+
+ - reg             : Offset and length of the register set for the device.
+ - compatible      : Should one of the following:
+                     - "allwinner,sun6i-a31-p2wi"
+ - interrupts      : The interrupt line connected to the P2WI peripheral.
+ - clocks          : The gate clk connected to the P2WI peripheral.
+ - resets          : The reset line connected to the P2WI peripheral.
+
+Optional properties :
+
+ - clock-frequency : Desired P2WI bus clock frequency in Hz. If not set the
+default frequency is 100kHz
+
+A P2WI may contain one child node encoding a P2WI slave device.
+
+Slave device properties:
+  Required properties:
+   - reg           : the I2C slave address used during the initialization
+                     process to switch from I2C to P2WI mode
+
+Example:
+
+       p2wi@01f03400 {
+               compatible = "allwinner,sun6i-a31-p2wi";
+               reg = <0x01f03400 0x400>;
+               interrupts = <0 39 4>;
+               clocks = <&apb0_gates 3>;
+               clock-frequency = <6000000>;
+               resets = <&apb0_rst 3>;
+
+               axp221: pmic@68 {
+                       compatible = "x-powers,axp221";
+                       reg = <0x68>;
+
+                       /* ... */
+               };
+       };
diff --git a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt
new file mode 100644 (file)
index 0000000..49ea76d
--- /dev/null
@@ -0,0 +1,14 @@
+SPEAr13XX PCIe DT detail:
+================================
+
+SPEAr13XX uses synopsis designware PCIe controller and ST MiPHY as phy
+controller.
+
+Required properties:
+- compatible : should be "st,spear1340-pcie", "snps,dw-pcie".
+- phys             : phandle to phy node associated with pcie controller
+- phy-names        : must be "pcie-phy"
+- All other definitions as per generic PCI bindings
+
+ Optional properties:
+- st,pcie-is-gen1 indicates that forced gen1 initialization is needed.
diff --git a/Documentation/devicetree/bindings/phy/st-spear-miphy.txt b/Documentation/devicetree/bindings/phy/st-spear-miphy.txt
new file mode 100644 (file)
index 0000000..2a6bfdc
--- /dev/null
@@ -0,0 +1,15 @@
+ST SPEAr miphy DT details
+=========================
+
+ST Microelectronics SPEAr miphy is a phy controller supporting PCIe and SATA.
+
+Required properties:
+- compatible : should be "st,spear1310-miphy" or "st,spear1340-miphy"
+- reg : offset and length of the PHY register set.
+- misc: phandle for the syscon node to access misc registers
+- #phy-cells : from the generic PHY bindings, must be 1.
+       - cell[1]: 0 if phy used for SATA, 1 for PCIe.
+
+Optional properties:
+- phy-id: Instance id of the phy. Only required when there are multiple phys
+  present on a implementation.
index b82a268..bee6ff2 100644 (file)
@@ -23,6 +23,12 @@ Optional properties:
 - spi-max-frequency: Specifies maximum SPI clock frequency,
                      Units - Hz. Definition as per
                      Documentation/devicetree/bindings/spi/spi-bus.txt
+- num-cs:      total number of chipselects
+- cs-gpios:    should specify GPIOs used for chipselects.
+               The gpios will be referred to as reg = <index> in the SPI child
+               nodes.  If unspecified, a single SPI device without a chip
+               select can be used.
+
 
 SPI slave nodes must be children of the SPI master node and can contain
 properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
index 4d7f375..46a311e 100644 (file)
@@ -83,6 +83,7 @@ mosaixtech    Mosaix Technologies, Inc.
 moxa   Moxa
 mpl    MPL AG
 mundoreader    Mundo Reader S.L.
+murata Murata Manufacturing Co., Ltd.
 mxicy  Macronix International Co., Ltd.
 national       National Semiconductor
 neonode                Neonode Inc.
index 4e30eba..9af538b 100644 (file)
@@ -1,6 +1,17 @@
 Email clients info for Linux
 ======================================================================
 
+Git
+----------------------------------------------------------------------
+These days most developers use `git send-email` instead of regular
+email clients.  The man page for this is quite good.  On the receiving
+end, maintainers use `git am` to apply the patches.
+
+If you are new to git then send your first patch to yourself.  Save it
+as raw text including all the headers.  Run `git am raw_email.txt` and
+then review the changelog with `git log`.  When that works then send
+the patch to the appropriate mailing list(s).
+
 General Preferences
 ----------------------------------------------------------------------
 Patches for the Linux kernel are submitted via email, preferably as
index 3bfda94..057b770 100644 (file)
@@ -1,7 +1,7 @@
 Kernel driver ntc_thermistor
 =================
 
-Supported thermistors:
+Supported thermistors from Murata:
 * Murata NTC Thermistors NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, NCP15WL333
   Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473', 'ncp15wl333'
   Datasheet: Publicly available at Murata
@@ -15,9 +15,9 @@ Authors:
 Description
 -----------
 
-The NTC thermistor is a simple thermistor that requires users to provide the
-resistance and lookup the corresponding compensation table to get the
-temperature input.
+The NTC (Negative Temperature Coefficient) thermistor is a simple thermistor
+that requires users to provide the resistance and lookup the corresponding
+compensation table to get the temperature input.
 
 The NTC driver provides lookup tables with a linear approximation function
 and four circuit models with an option not to use any of the four models.
index d567a7c..c600e2f 100644 (file)
@@ -1171,7 +1171,7 @@ When kbuild executes, the following steps are followed (roughly):
              obvious reason.
 
     dtc
-       Create flattend device tree blob object suitable for linking
+       Create flattened device tree blob object suitable for linking
        into vmlinux. Device tree blobs linked into vmlinux are placed
        in an init section in the image. Platform code *must* copy the
        blob to non-init memory prior to calling unflatten_device_tree().
index 6eaa9cd..c1b9aa8 100644 (file)
@@ -1474,6 +1474,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        js=             [HW,JOY] Analog joystick
                        See Documentation/input/joystick.txt.
 
+       kaslr/nokaslr   [X86]
+                       Enable/disable kernel and module base offset ASLR
+                       (Address Space Layout Randomization) if built into
+                       the kernel. When CONFIG_HIBERNATION is selected,
+                       kASLR is disabled by default. When kASLR is enabled,
+                       hibernation will be disabled.
+
        keepinitrd      [HW,ARM]
 
        kernelcore=nn[KMG]      [KNL,X86,IA-64,PPC] This parameter
@@ -2110,10 +2117,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        noapic          [SMP,APIC] Tells the kernel to not make use of any
                        IOAPICs that may be present in the system.
 
-       nokaslr         [X86]
-                       Disable kernel and module base offset ASLR (Address
-                       Space Layout Randomization) if built into the kernel.
-
        noautogroup     Disable scheduler automatic task group creation.
 
        nobats          [PPC] Do not use BATs for mapping kernel lowmem
@@ -2184,6 +2187,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        in certain environments such as networked servers or
                        real-time systems.
 
+       nohibernate     [HIBERNATION] Disable hibernation and resume.
+
        nohz=           [KNL] Boottime enable/disable dynamic ticks
                        Valid arguments: on, off
                        Default: on
@@ -2980,6 +2985,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                noresume        Don't check if there's a hibernation image
                                present during boot.
                nocompress      Don't compress/decompress hibernation images.
+               no              Disable hibernation and resume.
 
        retain_initrd   [RAM] Keep initrd memory after extraction
 
@@ -3124,6 +3130,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        [KNL] Should the soft-lockup detector generate panics.
                        Format: <integer>
 
+       softlockup_all_cpu_backtrace=
+                       [KNL] Should the soft-lockup detector generate
+                       backtraces on all cpus.
+                       Format: <integer>
+
        sonypi.*=       [HW] Sony Programmable I/O Control Device driver
                        See Documentation/laptops/sonypi.txt
 
index f304edb..45134dc 100644 (file)
@@ -209,15 +209,12 @@ If memory device is found, memory hotplug code will be called.
 
 4.2 Notify memory hot-add event by hand
 ------------
-On powerpc, the firmware does not notify a memory hotplug event to the kernel.
-Therefore, "probe" interface is supported to notify the event to the kernel.
-This interface depends on CONFIG_ARCH_MEMORY_PROBE.
-
-CONFIG_ARCH_MEMORY_PROBE is supported on powerpc only. On x86, this config
-option is disabled by default since ACPI notifies a memory hotplug event to
-the kernel, which performs its hotplug operation as the result. Please
-enable this option if you need the "probe" interface for testing purposes
-on x86.
+On some architectures, the firmware may not notify the kernel of a memory
+hotplug event.  Therefore, the memory "probe" interface is supported to
+explicitly notify the kernel.  This interface depends on
+CONFIG_ARCH_MEMORY_PROBE and can be configured on powerpc, sh, and x86
+if hotplug is supported, although for x86 this should be handled by ACPI
+notification.
 
 Probe interface is located at
 /sys/devices/system/memory/probe
index f1ac2da..ba1d502 100644 (file)
@@ -17,6 +17,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+#define _GNU_SOURCE
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #define CLOCK_INVALID -1
 #endif
 
-/* When glibc offers the syscall, this will go away. */
+/* clock_adjtime is not available in GLIBC < 2.14 */
+#if !__GLIBC_PREREQ(2, 14)
 #include <sys/syscall.h>
 static int clock_adjtime(clockid_t id, struct timex *tx)
 {
        return syscall(__NR_clock_adjtime, id, tx);
 }
+#endif
 
 static clockid_t get_clockid(int fd)
 {
index 85c362d..d1ab5e1 100644 (file)
@@ -286,6 +286,11 @@ STAC92HD83*
   hp-inv-led   HP with broken BIOS for inverted mute LED
   auto         BIOS setup (default)
 
+STAC92HD95
+==========
+  hp-led       LED support for HP laptops
+  hp-bass      Bass HPF setup for HP Spectre 13
+
 STAC9872
 ========
   vaio         VAIO laptop without SPDIF
index 708bb7f..c14374e 100644 (file)
@@ -75,6 +75,7 @@ show up in /proc/sys/kernel:
 - shmall
 - shmmax                      [ sysv ipc ]
 - shmmni
+- softlockup_all_cpu_backtrace
 - stop-a                      [ SPARC only ]
 - sysrq                       ==> Documentation/sysrq.txt
 - sysctl_writes_strict
@@ -783,6 +784,22 @@ via the /proc/sys interface:
 
 ==============================================================
 
+softlockup_all_cpu_backtrace:
+
+This value controls the soft lockup detector thread's behavior
+when a soft lockup condition is detected as to whether or not
+to gather further debug information. If enabled, each cpu will
+be issued an NMI and instructed to capture stack trace.
+
+This feature is only applicable for architectures which support
+NMI.
+
+0: do nothing. This is the default behavior.
+
+1: on detection capture more debug information.
+
+==============================================================
+
 tainted:
 
 Non-zero if the kernel has been tainted.  Numeric values, which
index bd4b34c..4415aa9 100644 (file)
@@ -702,7 +702,8 @@ The batch value of each per cpu pagelist is also updated as a result.  It is
 set to pcp->high/4.  The upper limit of batch is (PAGE_SHIFT * 8)
 
 The initial value is zero.  Kernel does not use this value at boot time to set
-the high water marks for each per cpu page list.
+the high water marks for each per cpu page list.  If the user writes '0' to this
+sysctl, it will revert to this default behavior.
 
 ==============================================================
 
index efceb78..60bc293 100644 (file)
@@ -4,7 +4,7 @@ Kernel driver nouveau
 Supported chips:
 * NV43+
 
-Authors: Martin Peres (mupuf) <martin.peres@labri.fr>
+Authors: Martin Peres (mupuf) <martin.peres@free.fr>
 
 Description
 ---------
@@ -68,8 +68,9 @@ Your fan can be driven in different modes:
 
 NOTE: Be sure to use the manual mode if you want to drive the fan speed manually
 
-NOTE2: Not all fan management modes may be supported on all chipsets. We are
-working on it.
+NOTE2: When operating in manual mode outside the vbios-defined
+[PWM_min, PWM_max] range, the reported fan speed (RPM) may not be accurate
+depending on your hardware.
 
 Bug reports
 ---------
index 134483f..766948e 100644 (file)
@@ -2917,6 +2917,9 @@ L:        linux-doc@vger.kernel.org
 T:     quilt http://www.infradead.org/~rdunlap/Doc/patches/
 S:     Maintained
 F:     Documentation/
+X:     Documentation/ABI/
+X:     Documentation/devicetree/
+X:     Documentation/[a-z][a-z]_[A-Z][A-Z]/
 
 DOUBLETALK DRIVER
 M:     "James R. Van Zandt" <jrv@vanzandt.mv.com>
@@ -3189,14 +3192,6 @@ L:       linux-scsi@vger.kernel.org
 S:     Maintained
 F:     drivers/scsi/eata_pio.*
 
-EBTABLES
-L:     netfilter-devel@vger.kernel.org
-W:     http://ebtables.sourceforge.net/
-S:     Orphan
-F:     include/linux/netfilter_bridge/ebt_*.h
-F:     include/uapi/linux/netfilter_bridge/ebt_*.h
-F:     net/bridge/netfilter/ebt*.c
-
 EC100 MEDIA DRIVER
 M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
@@ -6105,12 +6100,11 @@ F:      Documentation/networking/s2io.txt
 F:     Documentation/networking/vxge.txt
 F:     drivers/net/ethernet/neterion/
 
-NETFILTER/IPTABLES
+NETFILTER ({IP,IP6,ARP,EB,NF}TABLES)
 M:     Pablo Neira Ayuso <pablo@netfilter.org>
 M:     Patrick McHardy <kaber@trash.net>
 M:     Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
 L:     netfilter-devel@vger.kernel.org
-L:     netfilter@vger.kernel.org
 L:     coreteam@netfilter.org
 W:     http://www.netfilter.org/
 W:     http://www.iptables.org/
@@ -6826,6 +6820,12 @@ S:       Maintained
 F:     Documentation/devicetree/bindings/pci/host-generic-pci.txt
 F:     drivers/pci/host/pci-host-generic.c
 
+PCIE DRIVER FOR ST SPEAR13XX
+M:     Mohit Kumar <mohit.kumar@st.com>
+L:     linux-pci@vger.kernel.org
+S:     Maintained
+F:     drivers/pci/host/*spear*
+
 PCMCIA SUBSYSTEM
 P:     Linux PCMCIA Team
 L:     linux-pcmcia@lists.infradead.org
@@ -6960,7 +6960,7 @@ PKUNITY SOC DRIVERS
 M:     Guan Xuetao <gxt@mprc.pku.edu.cn>
 W:     http://mprc.pku.edu.cn/~guanxuetao/linux
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32.git
+T:     git git://github.com/gxt/linux.git
 F:     drivers/input/serio/i8042-unicore32io.h
 F:     drivers/i2c/busses/i2c-puv3.c
 F:     drivers/video/fb-puv3.c
@@ -7948,6 +7948,7 @@ F:        drivers/mmc/host/sdhci-spear.c
 
 SECURITY SUBSYSTEM
 M:     James Morris <james.l.morris@oracle.com>
+M:     Serge E. Hallyn <serge@hallyn.com>
 L:     linux-security-module@vger.kernel.org (suggested Cc:)
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git
 W:     http://kernsec.org/
@@ -8195,13 +8196,15 @@ S:      Maintained
 F:     drivers/usb/misc/sisusbvga/
 
 SLAB ALLOCATOR
-M:     Christoph Lameter <cl@linux-foundation.org>
+M:     Christoph Lameter <cl@linux.com>
 M:     Pekka Enberg <penberg@kernel.org>
-M:     Matt Mackall <mpm@selenic.com>
+M:     David Rientjes <rientjes@google.com>
+M:     Joonsoo Kim <iamjoonsoo.kim@lge.com>
+M:     Andrew Morton <akpm@linux-foundation.org>
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     include/linux/sl?b*.h
-F:     mm/sl?b.c
+F:     mm/sl?b*
 
 SLEEPABLE READ-COPY UPDATE (SRCU)
 M:     Lai Jiangshan <laijs@cn.fujitsu.com>
@@ -9276,7 +9279,7 @@ UNICORE32 ARCHITECTURE:
 M:     Guan Xuetao <gxt@mprc.pku.edu.cn>
 W:     http://mprc.pku.edu.cn/~guanxuetao/linux
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32.git
+T:     git git://github.com/gxt/linux.git
 F:     arch/unicore32/
 
 UNIFDEF
@@ -9743,6 +9746,14 @@ L:       virtualization@lists.linux-foundation.org
 S:     Supported
 F:     arch/x86/kernel/cpu/vmware.c
 
+VMWARE BALLOON DRIVER
+M:     Xavier Deguillard <xdeguillard@vmware.com>
+M:     Philip Moltmann <moltmann@vmware.com>
+M:     "VMware, Inc." <pv-drivers@vmware.com>
+L:     linux-kernel@vger.kernel.org
+S:     Maintained
+F:     drivers/misc/vmw_balloon.c
+
 VMWARE VMXNET3 ETHERNET DRIVER
 M:     Shreyas Bhatewara <sbhatewara@vmware.com>
 M:     "VMware, Inc." <pv-drivers@vmware.com>
index 97b2861..1317563 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 16
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
 NAME = Shuffling Zombie Juror
 
 # *DOCUMENTATION*
index c1d3d2d..b3c7509 100644 (file)
@@ -60,7 +60,7 @@ extern void read_decode_cache_bcr(void);
 #define ARC_REG_IC_IVIC                0x10
 #define ARC_REG_IC_CTRL                0x11
 #define ARC_REG_IC_IVIL                0x19
-#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
+#if defined(CONFIG_ARC_MMU_V3)
 #define ARC_REG_IC_PTAG                0x1E
 #endif
 
@@ -74,7 +74,7 @@ extern void read_decode_cache_bcr(void);
 #define ARC_REG_DC_IVDL                0x4A
 #define ARC_REG_DC_FLSH                0x4B
 #define ARC_REG_DC_FLDL                0x4C
-#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
+#if defined(CONFIG_ARC_MMU_V3)
 #define ARC_REG_DC_PTAG                0x5C
 #endif
 
index 2618cc1..76a7739 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef _UAPI__ASM_ARC_PTRACE_H
 #define _UAPI__ASM_ARC_PTRACE_H
 
+#define PTRACE_GET_THREAD_AREA 25
 
 #ifndef __ASSEMBLY__
 /*
index 2ff0347..e248594 100644 (file)
@@ -10,9 +10,9 @@
  *  -This is the more "natural" hand written assembler
  */
 
+#include <linux/linkage.h>
 #include <asm/entry.h>       /* For the SAVE_* macros */
 #include <asm/asm-offsets.h>
-#include <asm/linkage.h>
 
 #define KSP_WORD_OFF   ((TASK_THREAD + THREAD_KSP) / 4)
 
index 0b3ef40..fffdb5e 100644 (file)
@@ -41,7 +41,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt)
 {
        const struct machine_desc *mdesc;
        unsigned long dt_root;
-       void *clk;
+       const void *clk;
        int len;
 
        if (!early_init_dt_scan(dt))
index 07a58f2..4d2481b 100644 (file)
@@ -77,10 +77,11 @@ stext:
        ; Clear BSS before updating any globals
        ; XXX: use ZOL here
        mov     r5, __bss_start
-       mov     r6, __bss_stop
+       sub     r6, __bss_stop, r5
+       lsr.f   lp_count, r6, 2
+       lpnz    1f
+       st.ab   0, [r5, 4]
 1:
-       st.ab   0, [r5,4]
-       brlt    r5, r6, 1b
 
        ; Uboot - kernel ABI
        ;    r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2
index 5d76706..13b3ffb 100644 (file)
@@ -146,6 +146,10 @@ long arch_ptrace(struct task_struct *child, long request,
        pr_debug("REQ=%ld: ADDR =0x%lx, DATA=0x%lx)\n", request, addr, data);
 
        switch (request) {
+       case PTRACE_GET_THREAD_AREA:
+               ret = put_user(task_thread_info(child)->thr_ptr,
+                              (unsigned long __user *)data);
+               break;
        default:
                ret = ptrace_request(child, request, addr, data);
                break;
index cf90b6f..c802bb5 100644 (file)
@@ -337,8 +337,19 @@ irqreturn_t do_IPI(int irq, void *dev_id)
  * API called by platform code to hookup arch-common ISR to their IPI IRQ
  */
 static DEFINE_PER_CPU(int, ipi_dev);
+
+static struct irqaction arc_ipi_irq = {
+        .name    = "IPI Interrupt",
+        .flags   = IRQF_PERCPU,
+        .handler = do_IPI,
+};
+
 int smp_ipi_irq_setup(int cpu, int irq)
 {
-       int *dev_id = &per_cpu(ipi_dev, smp_processor_id());
-       return request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev_id);
+       if (!cpu)
+               return setup_irq(irq, &arc_ipi_irq);
+       else
+               arch_unmask_irq(irq);
+
+       return 0;
 }
index 2555f58..dd35bde 100644 (file)
@@ -116,7 +116,7 @@ SECTIONS
 
        _edata = .;
 
-       BSS_SECTION(0, 0, 0)
+       BSS_SECTION(4, 4, 4)
 
 #ifdef CONFIG_ARC_DW2_UNWIND
        . = ALIGN(PAGE_SIZE);
index 1f676c4..353b202 100644 (file)
@@ -389,7 +389,7 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr,
 /***********************************************************
  * Machine specific helper for per line I-Cache invalidate.
  */
-static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
+static void __ic_line_inv_vaddr_local(unsigned long paddr, unsigned long vaddr,
                                unsigned long sz)
 {
        unsigned long flags;
@@ -405,6 +405,23 @@ static inline void __ic_entire_inv(void)
        read_aux_reg(ARC_REG_IC_CTRL);  /* blocks */
 }
 
+struct ic_line_inv_vaddr_ipi {
+       unsigned long paddr, vaddr;
+       int sz;
+};
+
+static void __ic_line_inv_vaddr_helper(void *info)
+{
+        struct ic_line_inv_vaddr_ipi *ic_inv = (struct ic_line_inv_vaddr_ipi*) info;
+        __ic_line_inv_vaddr_local(ic_inv->paddr, ic_inv->vaddr, ic_inv->sz);
+}
+
+static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
+                               unsigned long sz)
+{
+       struct ic_line_inv_vaddr_ipi ic_inv = { paddr, vaddr , sz};
+       on_each_cpu(__ic_line_inv_vaddr_helper, &ic_inv, 1);
+}
 #else
 
 #define __ic_entire_inv()
@@ -553,12 +570,8 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
  */
 void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len)
 {
-       unsigned long flags;
-
-       local_irq_save(flags);
-       __ic_line_inv_vaddr(paddr, vaddr, len);
        __dc_line_op(paddr, vaddr, len, OP_FLUSH_N_INV);
-       local_irq_restore(flags);
+       __ic_line_inv_vaddr(paddr, vaddr, len);
 }
 
 /* wrapper to compile time eliminate alignment checks in flush loop */
index 87b63fd..245058b 100644 (file)
@@ -175,13 +175,6 @@ config ARCH_HAS_ILOG2_U32
 config ARCH_HAS_ILOG2_U64
        bool
 
-config ARCH_HAS_CPUFREQ
-       bool
-       help
-         Internal node to signify that the ARCH has CPUFREQ support
-         and that the relevant menu configurations are displayed for
-         it.
-
 config ARCH_HAS_BANDGAP
        bool
 
@@ -318,7 +311,6 @@ config ARCH_MULTIPLATFORM
 
 config ARCH_INTEGRATOR
        bool "ARM Ltd. Integrator family"
-       select ARCH_HAS_CPUFREQ
        select ARM_AMBA
        select ARM_PATCH_PHYS_VIRT
        select AUTO_ZRELADDR
@@ -538,7 +530,6 @@ config ARCH_DOVE
 
 config ARCH_KIRKWOOD
        bool "Marvell Kirkwood"
-       select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select CPU_FEROCEON
        select GENERIC_CLOCKEVENTS
@@ -637,7 +628,6 @@ config ARCH_LPC32XX
 config ARCH_PXA
        bool "PXA2xx/PXA3xx-based"
        depends on MMU
-       select ARCH_HAS_CPUFREQ
        select ARCH_MTD_XIP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_CPU_SUSPEND if PM
@@ -707,7 +697,6 @@ config ARCH_RPC
 
 config ARCH_SA1100
        bool "SA1100-based"
-       select ARCH_HAS_CPUFREQ
        select ARCH_MTD_XIP
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_SPARSEMEM_ENABLE
@@ -725,7 +714,6 @@ config ARCH_SA1100
 
 config ARCH_S3C24XX
        bool "Samsung S3C24XX SoCs"
-       select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select ATAGS
        select CLKDEV_LOOKUP
@@ -746,7 +734,6 @@ config ARCH_S3C24XX
 
 config ARCH_S3C64XX
        bool "Samsung S3C64XX"
-       select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select ARM_VIC
@@ -809,7 +796,6 @@ config ARCH_S5PC100
 
 config ARCH_S5PV210
        bool "Samsung S5PV210/S5PC110"
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_SPARSEMEM_ENABLE
        select ATAGS
@@ -845,7 +831,6 @@ config ARCH_DAVINCI
 config ARCH_OMAP1
        bool "TI OMAP1"
        depends on MMU
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_OMAP
        select ARCH_REQUIRE_GPIOLIB
@@ -1009,8 +994,6 @@ source "arch/arm/mach-rockchip/Kconfig"
 
 source "arch/arm/mach-sa1100/Kconfig"
 
-source "arch/arm/plat-samsung/Kconfig"
-
 source "arch/arm/mach-socfpga/Kconfig"
 
 source "arch/arm/mach-spear/Kconfig"
@@ -1028,6 +1011,7 @@ source "arch/arm/mach-s5pc100/Kconfig"
 source "arch/arm/mach-s5pv210/Kconfig"
 
 source "arch/arm/mach-exynos/Kconfig"
+source "arch/arm/plat-samsung/Kconfig"
 
 source "arch/arm/mach-shmobile/Kconfig"
 
@@ -2109,9 +2093,7 @@ endmenu
 
 menu "CPU Power Management"
 
-if ARCH_HAS_CPUFREQ
 source "drivers/cpufreq/Kconfig"
-endif
 
 source "drivers/cpuidle/Kconfig"
 
index 5986ff6..adb5ed9 100644 (file)
@@ -357,7 +357,7 @@ dtb-$(CONFIG_ARCH_STI)+= stih407-b2120.dtb \
        stih415-b2020.dtb \
        stih416-b2000.dtb \
        stih416-b2020.dtb \
-       stih416-b2020-revE.dtb
+       stih416-b2020e.dtb
 dtb-$(CONFIG_MACH_SUN4I) += \
        sun4i-a10-a1000.dtb \
        sun4i-a10-cubieboard.dtb \
index 772fec2..1e2919d 100644 (file)
@@ -91,6 +91,8 @@
                                marvell,nand-keep-config;
                                marvell,nand-enable-arbiter;
                                nand-on-flash-bbt;
+                               nand-ecc-strength = <4>;
+                               nand-ecc-step-size = <512>;
 
                                partition@0 {
                                        label = "U-Boot";
index e69bc67..4173a8a 100644 (file)
@@ -16,7 +16,7 @@
 
 / {
        model = "Marvell Armada 380 family SoC";
-       compatible = "marvell,armada380", "marvell,armada38x";
+       compatible = "marvell,armada380";
 
        cpus {
                #address-cells = <1>;
index ff9637d..1af886f 100644 (file)
@@ -16,7 +16,7 @@
 
 / {
        model = "Marvell Armada 385 Development Board";
-       compatible = "marvell,a385-db", "marvell,armada385", "marvell,armada38x";
+       compatible = "marvell,a385-db", "marvell,armada385", "marvell,armada380";
 
        chosen {
                bootargs = "console=ttyS0,115200 earlyprintk";
@@ -98,6 +98,8 @@
                                marvell,nand-keep-config;
                                marvell,nand-enable-arbiter;
                                nand-on-flash-bbt;
+                               nand-ecc-strength = <4>;
+                               nand-ecc-step-size = <512>;
 
                                partition@0 {
                                        label = "U-Boot";
index 4089325..aaca286 100644 (file)
@@ -17,7 +17,7 @@
 
 / {
        model = "Marvell Armada 385 Reference Design";
-       compatible = "marvell,a385-rd", "marvell,armada385", "marvell,armada38x";
+       compatible = "marvell,a385-rd", "marvell,armada385", "marvell,armada380";
 
        chosen {
                bootargs = "console=ttyS0,115200 earlyprintk";
index f011009..6283d79 100644 (file)
@@ -16,7 +16,7 @@
 
 / {
        model = "Marvell Armada 385 family SoC";
-       compatible = "marvell,armada385", "marvell,armada38x";
+       compatible = "marvell,armada385", "marvell,armada380";
 
        cpus {
                #address-cells = <1>;
index 3de364e..689fa1a 100644 (file)
@@ -20,7 +20,7 @@
 
 / {
        model = "Marvell Armada 38x family SoC";
-       compatible = "marvell,armada38x";
+       compatible = "marvell,armada380";
 
        aliases {
                gpio0 = &gpio0;
index e5c6a04..4e5a59e 100644 (file)
@@ -25,7 +25,7 @@
 
        memory {
                device_type = "memory";
-               reg = <0 0x00000000 0 0xC0000000>; /* 3 GB */
+               reg = <0 0x00000000 0 0x40000000>; /* 1 GB soldered on */
        };
 
        soc {
index b309c1c..04927db 100644 (file)
                                #size-cells = <0>;
                                #interrupt-cells = <1>;
 
-                               slow_rc_osc: slow_rc_osc {
-                                       compatible = "fixed-clock";
+                               main_osc: main_osc {
+                                       compatible = "atmel,at91rm9200-clk-main-osc";
                                        #clock-cells = <0>;
-                                       clock-frequency = <32768>;
-                                       clock-accuracy = <50000000>;
-                               };
-
-                               clk32k: slck {
-                                       compatible = "atmel,at91sam9260-clk-slow";
-                                       #clock-cells = <0>;
-                                       clocks = <&slow_rc_osc &slow_xtal>;
+                                       interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+                                       clocks = <&main_xtal>;
                                };
 
                                main: mainck {
                                        compatible = "atmel,at91rm9200-clk-main";
                                        #clock-cells = <0>;
-                                       interrupts-extended = <&pmc AT91_PMC_MOSCS>;
-                                       clocks = <&main_xtal>;
+                                       clocks = <&main_osc>;
                                };
 
                                plla: pllack {
                                        compatible = "atmel,at91rm9200-clk-master";
                                        #clock-cells = <0>;
                                        interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
-                                       clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
+                                       clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
                                        atmel,clk-output-range = <0 94000000>;
                                        atmel,clk-divisors = <1 2 4 0>;
                                };
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        interrupt-parent = <&pmc>;
-                                       clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
+                                       clocks = <&slow_xtal>, <&main>, <&plla>, <&pllb>;
 
                                        prog0: prog0 {
                                                #clock-cells = <0>;
index c6683ea..aa35a7a 100644 (file)
                reg = <0x20000000 0x4000000>;
        };
 
+       slow_xtal {
+               clock-frequency = <32768>;
+       };
+
        main_xtal {
                clock-frequency = <18432000>;
        };
index d1b82e6..2877959 100644 (file)
                                                                      <595000000 650000000 3 0>,
                                                                      <545000000 600000000 0 1>,
                                                                      <495000000 555000000 1 1>,
-                                                                     <445000000 500000000 1 2>,
-                                                                     <400000000 450000000 1 3>;
+                                                                     <445000000 500000000 2 1>,
+                                                                     <400000000 450000000 3 1>;
                                };
 
                                plladiv: plladivck {
index 1a57298..d6133f4 100644 (file)
                                                                       595000000 650000000 3 0
                                                                       545000000 600000000 0 1
                                                                       495000000 555000000 1 1
-                                                                      445000000 500000000 1 2
-                                                                      400000000 450000000 1 3>;
+                                                                      445000000 500000000 2 1
+                                                                      400000000 450000000 3 1>;
                                };
 
                                plladiv: plladivck {
index b8ece4b..fbaf426 100644 (file)
                compatible = "arm,cortex-a9-gic";
                #interrupt-cells = <3>;
                interrupt-controller;
-               reg = <0x10490000 0x1000>, <0x10480000 0x100>;
+               reg = <0x10490000 0x10000>, <0x10480000 0x10000>;
        };
 
        combiner: interrupt-controller@10440000 {
index 6bc3243..181d77f 100644 (file)
 &esdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_esdhc1>;
-       fsl,cd-controller;
-       fsl,wp-controller;
+       cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
 
 &esdhc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_esdhc2>;
-       cd-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+       cd-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
        wp-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
                                MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
                                MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
                                MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
-                               MX51_PAD_GPIO1_0__SD1_CD                0x20d5
-                               MX51_PAD_GPIO1_1__SD1_WP                0x20d5
+                               MX51_PAD_GPIO1_0__GPIO1_0               0x100
+                               MX51_PAD_GPIO1_1__GPIO1_1               0x100
                        >;
                };
 
index 75e66c9..31cfb7f 100644 (file)
 &esdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_esdhc1 &pinctrl_esdhc1_cd>;
-       fsl,cd-controller;
+       cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
 
 
                pinctrl_esdhc1_cd: esdhc1_cd {
                        fsl,pins = <
-                               MX51_PAD_GPIO1_0__SD1_CD 0x20d5
+                               MX51_PAD_GPIO1_0__GPIO1_0 0xd5
                        >;
                };
 
index d5d146a..c4956b0 100644 (file)
                      <0xb0000000 0x20000000>;
        };
 
-       soc {
-               display1: display@di1 {
-                       compatible = "fsl,imx-parallel-display";
-                       interface-pix-fmt = "bgr666";
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_ipu_disp1>;
-
-                       display-timings {
-                               800x480p60 {
-                                       native-mode;
-                                       clock-frequency = <31500000>;
-                                       hactive = <800>;
-                                       vactive = <480>;
-                                       hfront-porch = <40>;
-                                       hback-porch = <88>;
-                                       hsync-len = <128>;
-                                       vback-porch = <33>;
-                                       vfront-porch = <9>;
-                                       vsync-len = <3>;
-                                       vsync-active = <1>;
-                               };
+       display1: display@di1 {
+               compatible = "fsl,imx-parallel-display";
+               interface-pix-fmt = "bgr666";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ipu_disp1>;
+
+               display-timings {
+                       800x480p60 {
+                               native-mode;
+                               clock-frequency = <31500000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hfront-porch = <40>;
+                               hback-porch = <88>;
+                               hsync-len = <128>;
+                               vback-porch = <33>;
+                               vfront-porch = <9>;
+                               vsync-len = <3>;
+                               vsync-active = <1>;
                        };
                };
 
index 5373a5f..c8e51dd 100644 (file)
                        fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
                };
 
+               pinctrl_hummingboard_usbotg_id: hummingboard-usbotg-id {
+                       /*
+                        * Similar to pinctrl_usbotg_2, but we want it
+                        * pulled down for a fixed host connection.
+                        */
+                       fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
+               };
+
                pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
                        fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
                };
 };
 
 &usbotg {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hummingboard_usbotg_id>;
        vbus-supply = <&reg_usbotg_vbus>;
        status = "okay";
 };
index af4929a..0e1406e 100644 (file)
@@ -11,7 +11,7 @@
 
 /dts-v1/;
 #include "imx6q.dtsi"
-#include "imx6qdl-gw54xx.dtsi"
+#include "imx6qdl-gw51xx.dtsi"
 
 / {
        model = "Gateworks Ventana i.MX6 Quad GW51XX";
index 25da82a..e8e7816 100644 (file)
                pinctrl-0 = <&pinctrl_cubox_i_ir>;
        };
 
+       pwmleds {
+               compatible = "pwm-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_cubox_i_pwm1>;
+
+               front {
+                       active-low;
+                       label = "imx6:red:front";
+                       max-brightness = <248>;
+                       pwms = <&pwm1 0 50000>;
+               };
+       };
+
        regulators {
                compatible = "simple-bus";
 
                        >;
                };
 
+               pinctrl_cubox_i_pwm1: cubox-i-pwm1-front-led {
+                       fsl,pins = <MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b0>;
+               };
+
                pinctrl_cubox_i_spdif: cubox-i-spdif {
                        fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
                };
                        fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x4001b0b0>;
                };
 
+               pinctrl_cubox_i_usbotg_id: cubox-i-usbotg-id {
+                       /*
+                        * The Cubox-i pulls this low, but as it's pointless
+                        * leaving it as a pull-up, even if it is just 10uA.
+                        */
+                       fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
+               };
+
                pinctrl_cubox_i_usbotg_vbus: cubox-i-usbotg-vbus {
                        fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x4001b0b0>;
                };
 };
 
 &usbotg {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cubox_i_usbotg_id>;
        vbus-supply = <&reg_usbotg_vbus>;
        status = "okay";
 };
index 31665ad..0db15af 100644 (file)
        status = "okay";
 
        pmic: ltc3676@3c {
-               compatible = "ltc,ltc3676";
+               compatible = "lltc,ltc3676";
                reg = <0x3c>;
 
                regulators {
index 367af3e..744c8a2 100644 (file)
        };
 
        pmic: ltc3676@3c {
-               compatible = "ltc,ltc3676";
+               compatible = "lltc,ltc3676";
                reg = <0x3c>;
 
                regulators {
        codec: sgtl5000@0a {
                compatible = "fsl,sgtl5000";
                reg = <0x0a>;
-               clocks = <&clks 169>;
+               clocks = <&clks 201>;
                VDDA-supply = <&reg_1p8v>;
                VDDIO-supply = <&reg_3p3v>;
        };
index c91b5a6..adf150c 100644 (file)
        };
 
        pmic: ltc3676@3c {
-               compatible = "ltc,ltc3676";
+               compatible = "lltc,ltc3676";
                reg = <0x3c>;
 
                regulators {
index d729d0b..79eac68 100644 (file)
                                MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA    0x1b0b1
                        >;
                };
-
-               pinctrl_microsom_usbotg: microsom-usbotg {
-                       /*
-                        * Similar to pinctrl_usbotg_2, but we want it
-                        * pulled down for a fixed host connection.
-                        */
-                       fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
-               };
        };
 };
 
@@ -26,8 +18,3 @@
        pinctrl-0 = <&pinctrl_microsom_uart1>;
        status = "okay";
 };
-
-&usbotg {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_microsom_usbotg>;
-};
index 2d4e528..57d4abe 100644 (file)
                                compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
                                reg = <0x02188000 0x4000>;
                                interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&clks IMX6SL_CLK_ENET_REF>,
+                               clocks = <&clks IMX6SL_CLK_ENET>,
                                         <&clks IMX6SL_CLK_ENET_REF>;
                                clock-names = "ipg", "ahb";
                                status = "disabled";
index c5a1fc7..b2d9834 100644 (file)
                compatible = "ethernet-phy-id0141.0cb0",
                             "ethernet-phy-ieee802.3-c22";
                reg = <0>;
-               phy-connection-type = "rgmii-id";
        };
 
        ethphy1: ethernet-phy@1 {
                compatible = "ethernet-phy-id0141.0cb0",
                             "ethernet-phy-ieee802.3-c22";
                reg = <1>;
-               phy-connection-type = "rgmii-id";
        };
 };
 
        status = "okay";
        ethernet0-port@0 {
                phy-handle = <&ethphy0>;
+               phy-connection-type = "rgmii-id";
        };
 };
 
        status = "okay";
        ethernet1-port@0 {
                phy-handle = <&ethphy1>;
+               phy-connection-type = "rgmii-id";
        };
 };
index b56a801..d42c84b 100644 (file)
                        status = "okay";
                };
 
+               miphy@eb800000 {
+                       status = "okay";
+               };
+
                cf@b2800000 {
                        status = "okay";
                };
index 122ae94..fa5f2bb 100644 (file)
                        #gpio-cells = <2>;
                };
 
-               ahci@b1000000 {
+               miphy0: miphy@eb800000 {
+                       compatible = "st,spear1310-miphy";
+                       reg = <0xeb800000 0x4000>;
+                       misc = <&misc>;
+                       phy-id = <0>;
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
+
+               miphy1: miphy@eb804000 {
+                       compatible = "st,spear1310-miphy";
+                       reg = <0xeb804000 0x4000>;
+                       misc = <&misc>;
+                       phy-id = <1>;
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
+
+               miphy2: miphy@eb808000 {
+                       compatible = "st,spear1310-miphy";
+                       reg = <0xeb808000 0x4000>;
+                       misc = <&misc>;
+                       phy-id = <2>;
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
+
+               ahci0: ahci@b1000000 {
                        compatible = "snps,spear-ahci";
                        reg = <0xb1000000 0x10000>;
                        interrupts = <0 68 0x4>;
+                       phys = <&miphy0 0>;
+                       phy-names = "sata-phy";
                        status = "disabled";
                };
 
-               ahci@b1800000 {
+               ahci1: ahci@b1800000 {
                        compatible = "snps,spear-ahci";
                        reg = <0xb1800000 0x10000>;
                        interrupts = <0 69 0x4>;
+                       phys = <&miphy1 0>;
+                       phy-names = "sata-phy";
                        status = "disabled";
                };
 
-               ahci@b4000000 {
+               ahci2: ahci@b4000000 {
                        compatible = "snps,spear-ahci";
                        reg = <0xb4000000 0x10000>;
                        interrupts = <0 70 0x4>;
+                       phys = <&miphy2 0>;
+                       phy-names = "sata-phy";
+                       status = "disabled";
+               };
+
+               pcie0: pcie@b1000000 {
+                       compatible = "st,spear1340-pcie", "snps,dw-pcie";
+                       reg = <0xb1000000 0x4000>;
+                       interrupts = <0 68 0x4>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0x0 0 &gic 0 68 0x4>;
+                       num-lanes = <1>;
+                       phys = <&miphy0 1>;
+                       phy-names = "pcie-phy";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000   /* configuration space */
+                               0x81000000 0 0   0x80020000 0 0x00010000   /* downstream I/O */
+                               0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
+                       status = "disabled";
+               };
+
+               pcie1: pcie@b1800000 {
+                       compatible = "st,spear1340-pcie", "snps,dw-pcie";
+                       reg = <0xb1800000 0x4000>;
+                       interrupts = <0 69 0x4>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0x0 0 &gic 0 69 0x4>;
+                       num-lanes = <1>;
+                       phys = <&miphy1 1>;
+                       phy-names = "pcie-phy";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       ranges = <0x00000800 0 0x90000000 0x90000000 0 0x00020000   /* configuration space */
+                               0x81000000 0 0  0x90020000 0 0x00010000   /* downstream I/O */
+                               0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */
+                       status = "disabled";
+               };
+
+               pcie2: pcie@b4000000 {
+                       compatible = "st,spear1340-pcie", "snps,dw-pcie";
+                       reg = <0xb4000000 0x4000>;
+                       interrupts = <0 70 0x4>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0x0 0 &gic 0 70 0x4>;
+                       num-lanes = <1>;
+                       phys = <&miphy2 1>;
+                       phy-names = "pcie-phy";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       ranges = <0x00000800 0 0xc0000000 0xc0000000 0 0x00020000   /* configuration space */
+                               0x81000000 0 0   0xc0020000 0 0x00010000   /* downstream I/O */
+                               0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
                        status = "disabled";
                };
 
index d6c30ae..b23e05e 100644 (file)
                        status = "okay";
                };
 
+               miphy@eb800000 {
+                       status = "okay";
+               };
+
                dma@ea800000 {
                        status = "okay";
                };
index 54d128d..e71df0f 100644 (file)
                        status = "disabled";
                };
 
-               ahci@b1000000 {
+               miphy0: miphy@eb800000 {
+                       compatible = "st,spear1340-miphy";
+                       reg = <0xeb800000 0x4000>;
+                       misc = <&misc>;
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
+
+               ahci0: ahci@b1000000 {
                        compatible = "snps,spear-ahci";
                        reg = <0xb1000000 0x10000>;
                        interrupts = <0 72 0x4>;
+                       phys = <&miphy0 0>;
+                       phy-names = "sata-phy";
+                       status = "disabled";
+               };
+
+               pcie0: pcie@b1000000 {
+                       compatible = "st,spear1340-pcie", "snps,dw-pcie";
+                       reg = <0xb1000000 0x4000>;
+                       interrupts = <0 68 0x4>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0x0 0 &gic 0 68 0x4>;
+                       num-lanes = <1>;
+                       phys = <&miphy0 1>;
+                       phy-names = "pcie-phy";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000   /* configuration space */
+                               0x81000000 0 0   0x80020000 0 0x00010000   /* downstream I/O */
+                               0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
                        status = "disabled";
                };
 
index 4382547..a6eb543 100644 (file)
@@ -83,8 +83,8 @@
                #size-cells = <1>;
                compatible = "simple-bus";
                ranges = <0x50000000 0x50000000 0x10000000
-                         0xb0000000 0xb0000000 0x10000000
-                         0xd0000000 0xd0000000 0x02000000
+                         0x80000000 0x80000000 0x20000000
+                         0xb0000000 0xb0000000 0x22000000
                          0xd8000000 0xd8000000 0x01000000
                          0xe0000000 0xe0000000 0x10000000>;
 
                                  0xd8000000 0xd8000000 0x01000000
                                  0xe0000000 0xe0000000 0x10000000>;
 
+                       misc: syscon@e0700000 {
+                               compatible = "st,spear1340-misc", "syscon";
+                               reg = <0xe0700000 0x1000>;
+                       };
+
                        gpio0: gpio@e0600000 {
                                compatible = "arm,pl061", "arm,primecell";
                                reg = <0xe0600000 0x1000>;
index d6f254f..a0f6f75 100644 (file)
 
                        pinctrl-names   = "default";
                        pinctrl-0       = <&pinctrl_mii0>;
-                       clock-names     = "stmmaceth";
-                       clocks          = <&clk_s_a1_ls CLK_GMAC0_PHY>;
+                       clock-names     = "stmmaceth", "sti-ethclk";
+                       clocks          = <&clk_s_a1_ls CLK_ICN_IF_2>, <&clk_s_a1_ls CLK_GMAC0_PHY>;
                };
 
                ethernet1: dwmac@fef08000 {
                        reset-names             = "stmmaceth";
                        pinctrl-names   = "default";
                        pinctrl-0       = <&pinctrl_mii1>;
-                       clock-names     = "stmmaceth";
-                       clocks          = <&clk_s_a0_ls CLK_ETH1_PHY>;
+                       clock-names     = "stmmaceth", "sti-ethclk";
+                       clocks          = <&clk_s_a0_ls CLK_ICN_REG>, <&clk_s_a0_ls CLK_ETH1_PHY>;
                };
 
                rc: rc@fe518000 {
diff --git a/arch/arm/boot/dts/stih416-b2020-revE.dts b/arch/arm/boot/dts/stih416-b2020-revE.dts
deleted file mode 100644 (file)
index ba0fa2c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2014 STMicroelectronics (R&D) Limited.
- * Author: Lee Jones <lee.jones@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * publishhed by the Free Software Foundation.
- */
-/dts-v1/;
-#include "stih416.dtsi"
-#include "stih41x-b2020.dtsi"
-/ {
-       model = "STiH416 B2020 REV-E";
-       compatible = "st,stih416-b2020", "st,stih416";
-
-       soc {
-               leds {
-                       compatible = "gpio-leds";
-                       red {
-                               #gpio-cells             = <1>;
-                               label                   = "Front Panel LED";
-                               gpios                   = <&PIO4 1>;
-                               linux,default-trigger   = "heartbeat";
-                       };
-                       green {
-                               gpios                   = <&PIO1 3>;
-                               default-state           = "off";
-                       };
-               };
-
-               ethernet1: dwmac@fef08000 {
-                       snps,reset-gpio = <&PIO0 7>;
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/stih416-b2020e.dts b/arch/arm/boot/dts/stih416-b2020e.dts
new file mode 100644 (file)
index 0000000..ba0fa2c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics (R&D) Limited.
+ * Author: Lee Jones <lee.jones@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+       model = "STiH416 B2020 REV-E";
+       compatible = "st,stih416-b2020", "st,stih416";
+
+       soc {
+               leds {
+                       compatible = "gpio-leds";
+                       red {
+                               #gpio-cells             = <1>;
+                               label                   = "Front Panel LED";
+                               gpios                   = <&PIO4 1>;
+                               linux,default-trigger   = "heartbeat";
+                       };
+                       green {
+                               gpios                   = <&PIO1 3>;
+                               default-state           = "off";
+                       };
+               };
+
+               ethernet1: dwmac@fef08000 {
+                       snps,reset-gpio = <&PIO0 7>;
+               };
+       };
+};
index 06473c5..84758d7 100644 (file)
                        reset-names             = "stmmaceth";
                        pinctrl-names   = "default";
                        pinctrl-0       = <&pinctrl_mii0>;
-                       clock-names     = "stmmaceth";
-                       clocks          = <&clk_s_a1_ls CLK_GMAC0_PHY>;
+                       clock-names     = "stmmaceth", "sti-ethclk";
+                       clocks          = <&clk_s_a1_ls CLK_ICN_IF_2>, <&clk_s_a1_ls CLK_GMAC0_PHY>;
                };
 
                ethernet1: dwmac@fef08000 {
                        reset-names     = "stmmaceth";
                        pinctrl-names   = "default";
                        pinctrl-0       = <&pinctrl_mii1>;
-                       clock-names     = "stmmaceth";
-                       clocks          = <&clk_s_a0_ls CLK_ETH1_PHY>;
+                       clock-names     = "stmmaceth", "sti-ethclk";
+                       clocks          = <&clk_s_a0_ls CLK_ICN_REG>, <&clk_s_a0_ls CLK_ETH1_PHY>;
                };
 
                rc: rc@fe518000 {
index 6ef146e..a20fa80 100644 (file)
@@ -182,7 +182,6 @@ static int scoop_probe(struct platform_device *pdev)
        struct scoop_config *inf;
        struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        int ret;
-       int temp;
 
        if (!mem)
                return -EINVAL;
index ef88153..59b7e45 100644 (file)
@@ -186,6 +186,7 @@ CONFIG_VIDEO_MX3=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_CODA=y
 CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_IMX_IPUV3_CORE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
index e2d6204..be1a345 100644 (file)
@@ -300,6 +300,7 @@ CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_OF_ARASAN=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
 CONFIG_MMC_SDHCI_DOVE=y
@@ -352,6 +353,7 @@ CONFIG_MFD_NVEC=y
 CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
+CONFIG_QCOM_GSBI=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_MSM_GCC_8660=y
 CONFIG_MSM_MMCC_8960=y
index e11170e..b0bfefa 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_MACH_ARMADA_370=y
 CONFIG_MACH_ARMADA_375=y
 CONFIG_MACH_ARMADA_38X=y
 CONFIG_MACH_ARMADA_XP=y
+CONFIG_MACH_DOVE=y
 CONFIG_NEON=y
 # CONFIG_CACHE_L2X0 is not set
 # CONFIG_SWP_EMULATE is not set
@@ -52,6 +53,7 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_I2C=y
 CONFIG_SPI=y
 CONFIG_SPI_ORION=y
index 59066cf..536a137 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_SOC_OMAP5=y
 CONFIG_SOC_AM33XX=y
 CONFIG_SOC_AM43XX=y
 CONFIG_SOC_DRA7XX=y
+CONFIG_CACHE_L2X0=y
 CONFIG_ARM_THUMBEE=y
 CONFIG_ARM_ERRATA_411920=y
 CONFIG_SMP=y
index 82eaa55..d271b26 100644 (file)
@@ -11,13 +11,24 @@ CONFIG_ARCH_SPEAR13XX=y
 CONFIG_MACH_SPEAR1310=y
 CONFIG_MACH_SPEAR1340=y
 # CONFIG_SWP_EMULATE is not set
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIE_SPEAR13XX=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
 # CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_AEABI=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_VFP=y
 CONFIG_BINFMT_MISC=y
 CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_OF_PARTS=y
@@ -27,6 +38,7 @@ CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
 # CONFIG_SATA_PMP is not set
 CONFIG_SATA_AHCI_PLATFORM=y
@@ -66,6 +78,7 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SPEAR=y
@@ -79,11 +92,14 @@ CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_SECURITY=y
 CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
 CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=m
index eb577f4..39eb16b 100644 (file)
@@ -52,7 +52,7 @@ extern inline void *return_address(unsigned int level)
 
 #endif
 
-#define ftrace_return_addr(n) return_address(n)
+#define ftrace_return_address(n) return_address(n)
 
 #endif /* ifndef __ASSEMBLY__ */
 
index d9702eb..94060ad 100644 (file)
@@ -208,8 +208,6 @@ struct sync_struct {
        struct mcpm_sync_struct clusters[MAX_NR_CLUSTERS];
 };
 
-extern unsigned long sync_phys;        /* physical address of *mcpm_sync */
-
 void __mcpm_cpu_going_down(unsigned int cpu, unsigned int cluster);
 void __mcpm_cpu_down(unsigned int cpu, unsigned int cluster);
 void __mcpm_outbound_leave_critical(unsigned int cluster, int state);
index f989d7c..e4e4208 100644 (file)
@@ -114,8 +114,14 @@ static inline struct thread_info *current_thread_info(void)
        ((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
 #define thread_saved_sp(tsk)   \
        ((unsigned long)(task_thread_info(tsk)->cpu_context.sp))
+
+#ifndef CONFIG_THUMB2_KERNEL
 #define thread_saved_fp(tsk)   \
        ((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
+#else
+#define thread_saved_fp(tsk)   \
+       ((unsigned long)(task_thread_info(tsk)->cpu_context.r7))
+#endif
 
 extern void crunch_task_disable(struct thread_info *);
 extern void crunch_task_copy(struct thread_info *, void *);
index 2037f72..1d37568 100644 (file)
@@ -1924,7 +1924,7 @@ static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
                                   struct perf_event *event)
 {
        int idx;
-       int bit;
+       int bit = -1;
        unsigned int prefix;
        unsigned int region;
        unsigned int code;
@@ -1953,7 +1953,7 @@ static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
        }
 
        idx = armv7pmu_get_event_idx(cpuc, event);
-       if (idx < 0 && krait_event)
+       if (idx < 0 && bit >= 0)
                clear_bit(bit, cpuc->used_mask);
 
        return idx;
index 0dd3b79..0c27ed6 100644 (file)
@@ -908,7 +908,7 @@ enum ptrace_syscall_dir {
        PTRACE_SYSCALL_EXIT,
 };
 
-static int tracehook_report_syscall(struct pt_regs *regs,
+static void tracehook_report_syscall(struct pt_regs *regs,
                                    enum ptrace_syscall_dir dir)
 {
        unsigned long ip;
@@ -926,7 +926,6 @@ static int tracehook_report_syscall(struct pt_regs *regs,
                current_thread_info()->syscall = -1;
 
        regs->ARM_ip = ip;
-       return current_thread_info()->syscall;
 }
 
 asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
@@ -938,7 +937,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
                return -1;
 
        if (test_thread_flag(TIF_SYSCALL_TRACE))
-               scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+               tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
+       scno = current_thread_info()->syscall;
 
        if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
                trace_sys_enter(regs, scno);
index f302905..f6663d6 100644 (file)
@@ -199,6 +199,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
        CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
        CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk),
+       CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
        /* fake hclk clock */
        CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
        CLKDEV_CON_ID("pioA", &pioA_clk),
index 309390d..cef0e2f 100644 (file)
@@ -1131,9 +1131,7 @@ static void __init at91_add_device_watchdog(void) {}
  *  PWM
  * --------------------------------------------------------------------*/
 
-#if defined(CONFIG_ATMEL_PWM)
-static u32 pwm_mask;
-
+#if IS_ENABLED(CONFIG_PWM_ATMEL)
 static struct resource pwm_resources[] = {
        [0] = {
                .start  = AT91SAM9263_BASE_PWMC,
@@ -1148,11 +1146,8 @@ static struct resource pwm_resources[] = {
 };
 
 static struct platform_device at91sam9263_pwm0_device = {
-       .name   = "atmel_pwm",
+       .name   = "at91sam9rl-pwm",
        .id     = -1,
-       .dev    = {
-               .platform_data          = &pwm_mask,
-       },
        .resource       = pwm_resources,
        .num_resources  = ARRAY_SIZE(pwm_resources),
 };
@@ -1171,8 +1166,6 @@ void __init at91_add_device_pwm(u32 mask)
        if (mask & (1 << AT91_PWM3))
                at91_set_B_periph(AT91_PIN_PB29, 1);    /* enable PWM3 */
 
-       pwm_mask = mask;
-
        platform_device_register(&at91sam9263_pwm0_device);
 }
 #else
index 9d3d544..7300523 100644 (file)
@@ -251,6 +251,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk),
        CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk),
        CLKDEV_CON_DEV_ID(NULL, "atmel_aes", &aestdessha_clk),
+       CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
        /* more usart lookup table for DT entries */
        CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck),
        CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk),
index 391ab6b..21ab782 100644 (file)
@@ -1334,9 +1334,7 @@ static void __init at91_add_device_watchdog(void) {}
  *  PWM
  * --------------------------------------------------------------------*/
 
-#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
-static u32 pwm_mask;
-
+#if IS_ENABLED(CONFIG_PWM_ATMEL)
 static struct resource pwm_resources[] = {
        [0] = {
                .start  = AT91SAM9G45_BASE_PWMC,
@@ -1351,11 +1349,8 @@ static struct resource pwm_resources[] = {
 };
 
 static struct platform_device at91sam9g45_pwm0_device = {
-       .name   = "atmel_pwm",
+       .name   = "at91sam9rl-pwm",
        .id     = -1,
-       .dev    = {
-               .platform_data          = &pwm_mask,
-       },
        .resource       = pwm_resources,
        .num_resources  = ARRAY_SIZE(pwm_resources),
 };
@@ -1374,8 +1369,6 @@ void __init at91_add_device_pwm(u32 mask)
        if (mask & (1 << AT91_PWM3))
                at91_set_B_periph(AT91_PIN_PD0, 1);     /* enable PWM3 */
 
-       pwm_mask = mask;
-
        platform_device_register(&at91sam9g45_pwm0_device);
 }
 #else
index a79960f..878d501 100644 (file)
@@ -200,6 +200,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk),
        CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk),
        CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk),
+       CLKDEV_CON_DEV_ID(NULL, "at91sam9rl-pwm", &pwm_clk),
        CLKDEV_CON_ID("pioA", &pioA_clk),
        CLKDEV_CON_ID("pioB", &pioB_clk),
        CLKDEV_CON_ID("pioC", &pioC_clk),
index 0b1d71a..37d1c9e 100644 (file)
@@ -799,9 +799,7 @@ static void __init at91_add_device_watchdog(void) {}
  *  PWM
  * --------------------------------------------------------------------*/
 
-#if defined(CONFIG_ATMEL_PWM)
-static u32 pwm_mask;
-
+#if IS_ENABLED(CONFIG_PWM_ATMEL)
 static struct resource pwm_resources[] = {
        [0] = {
                .start  = AT91SAM9RL_BASE_PWMC,
@@ -816,11 +814,8 @@ static struct resource pwm_resources[] = {
 };
 
 static struct platform_device at91sam9rl_pwm0_device = {
-       .name   = "atmel_pwm",
+       .name   = "at91sam9rl-pwm",
        .id     = -1,
-       .dev    = {
-               .platform_data          = &pwm_mask,
-       },
        .resource       = pwm_resources,
        .num_resources  = ARRAY_SIZE(pwm_resources),
 };
@@ -839,8 +834,6 @@ void __init at91_add_device_pwm(u32 mask)
        if (mask & (1 << AT91_PWM3))
                at91_set_B_periph(AT91_PIN_PD8, 1);     /* enable PWM3 */
 
-       pwm_mask = mask;
-
        platform_device_register(&at91sam9rl_pwm0_device);
 }
 #else
index cd2726e..fc44609 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/leds.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -369,21 +371,47 @@ static struct gpio_led ek_leds[] = {
                .name                   = "ds3",
                .gpio                   = AT91_PIN_PB7,
                .default_trigger        = "heartbeat",
+       },
+#if !IS_ENABLED(CONFIG_LEDS_PWM)
+       {
+               .name                   = "ds1",
+               .gpio                   = AT91_PIN_PB8,
+               .active_low             = 1,
+               .default_trigger        = "none",
        }
+#endif
 };
 
 /*
  * PWM Leds
  */
-static struct gpio_led ek_pwm_led[] = {
-       /* For now only DS1 is PWM-driven (by pwm1) */
+static struct pwm_lookup pwm_lookup[] = {
+       PWM_LOOKUP("at91sam9rl-pwm", 1, "leds_pwm", "ds1",
+                  5000, PWM_POLARITY_INVERSED),
+};
+
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+static struct led_pwm pwm_leds[] = {
        {
-               .name                   = "ds1",
-               .gpio                   = 1,    /* is PWM channel number */
-               .active_low             = 1,
-               .default_trigger        = "none",
-       }
+               .name = "ds1",
+               .max_brightness = 255,
+       },
+};
+
+static struct led_pwm_platform_data pwm_data = {
+       .num_leds       = ARRAY_SIZE(pwm_leds),
+       .leds           = pwm_leds,
+};
+
+static struct platform_device leds_pwm = {
+       .name   = "leds_pwm",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &pwm_data,
+       },
 };
+#endif
+
 
 /*
  * CAN
@@ -403,6 +431,12 @@ static struct at91_can_data ek_can_data = {
        .transceiver_switch = sam9263ek_transceiver_switch,
 };
 
+static struct platform_device *devices[] __initdata = {
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+       &leds_pwm,
+#endif
+};
+
 static void __init ek_board_init(void)
 {
        /* Serial */
@@ -437,9 +471,14 @@ static void __init ek_board_init(void)
        at91_add_device_ac97(&ek_ac97_data);
        /* LEDs */
        at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
-       at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+       pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+       at91_add_device_pwm(1 << AT91_PWM1);
+#endif
        /* CAN */
        at91_add_device_can(&ek_can_data);
+       /* Other platform devices */
+       platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
index 1ea6132..b227732 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/leds.h>
 #include <linux/atmel-mci.h>
 #include <linux/delay.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
 
 #include <linux/platform_data/at91_adc.h>
 
@@ -416,7 +418,7 @@ static struct gpio_led ek_leds[] = {
                .active_low             = 1,
                .default_trigger        = "nand-disk",
        },
-#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE))
+#if !IS_ENABLED(CONFIG_LEDS_PWM)
        {       /* "right" led, green, userled1, pwm1 */
                .name                   = "d7",
                .gpio                   = AT91_PIN_PD31,
@@ -430,22 +432,41 @@ static struct gpio_led ek_leds[] = {
 /*
  * PWM Leds
  */
-static struct gpio_led ek_pwm_led[] = {
-#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)
+static struct pwm_lookup pwm_lookup[] = {
+       PWM_LOOKUP("at91sam9rl-pwm", 1, "leds_pwm", "d7",
+                  5000, PWM_POLARITY_INVERSED),
+};
+
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+static struct led_pwm pwm_leds[] = {
        {       /* "right" led, green, userled1, pwm1 */
-               .name                   = "d7",
-               .gpio                   = 1,    /* is PWM channel number */
-               .active_low             = 1,
-               .default_trigger        = "none",
+               .name = "d7",
+               .max_brightness = 255,
        },
-#endif
 };
 
+static struct led_pwm_platform_data pwm_data = {
+       .num_leds       = ARRAY_SIZE(pwm_leds),
+       .leds           = pwm_leds,
+};
+
+static struct platform_device leds_pwm = {
+       .name   = "leds_pwm",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &pwm_data,
+       },
+};
+#endif
+
 static struct platform_device *devices[] __initdata = {
 #if defined(CONFIG_SOC_CAMERA_OV2640) || \
        defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
        &isi_ov2640,
 #endif
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+       &leds_pwm,
+#endif
 };
 
 static void __init ek_board_init(void)
@@ -486,7 +507,10 @@ static void __init ek_board_init(void)
        at91_add_device_ac97(&ek_ac97_data);
        /* LEDs */
        at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
-       at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+       pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+       at91_add_device_pwm(1 << AT91_PWM1);
+#endif
        /* Other platform devices */
        platform_add_devices(devices, ARRAY_SIZE(devices));
 }
index 4e773b5..836e9a5 100644 (file)
@@ -123,6 +123,5 @@ extern void __init at91_add_device_can(struct at91_can_data *data);
 
  /* LEDs */
 extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
-extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
 
 #endif
index 77c4d8f..eb22e33 100644 (file)
@@ -54,40 +54,3 @@ void __init at91_gpio_leds(struct gpio_led *leds, int nr)
 void __init at91_gpio_leds(struct gpio_led *leds, int nr) {}
 #endif
 
-
-/* ------------------------------------------------------------------------- */
-
-#if defined (CONFIG_LEDS_ATMEL_PWM)
-
-/*
- * PWM Leds
- */
-
-static struct gpio_led_platform_data pwm_led_data;
-
-static struct platform_device at91_pwm_leds_device = {
-       .name                   = "leds-atmel-pwm",
-       .id                     = -1,
-       .dev.platform_data      = &pwm_led_data,
-};
-
-void __init at91_pwm_leds(struct gpio_led *leds, int nr)
-{
-       int i;
-       u32 pwm_mask = 0;
-
-       if (!nr)
-               return;
-
-       for (i = 0; i < nr; i++)
-               pwm_mask |= (1 << leds[i].gpio);
-
-       pwm_led_data.leds = leds;
-       pwm_led_data.num_leds = nr;
-
-       at91_add_device_pwm(pwm_mask);
-       platform_device_register(&at91_pwm_leds_device);
-}
-#else
-void __init at91_pwm_leds(struct gpio_led *leds, int nr){}
-#endif
index 9bc6db1..41c8391 100644 (file)
@@ -1,10 +1,9 @@
-config ARCH_BCM
+menuconfig ARCH_BCM
        bool "Broadcom SoC Support" if ARCH_MULTI_V6_V7
        help
          This enables support for Broadcom ARM based SoC chips
 
-menu "Broadcom SoC Selection"
-       depends on ARCH_BCM
+if ARCH_BCM
 
 config ARCH_BCM_MOBILE
        bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7
@@ -88,4 +87,4 @@ config ARCH_BCM_5301X
          different SoC or with the older BCM47XX and BCM53XX based
          network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
 
-endmenu
+endif
index 101e0f3..2631cfc 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_BERLIN
+menuconfig ARCH_BERLIN
        bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select ARM_GIC
@@ -9,8 +9,6 @@ config ARCH_BERLIN
 
 if ARCH_BERLIN
 
-menu "Marvell Berlin SoC variants"
-
 config MACH_BERLIN_BG2
        bool "Marvell Armada 1500 (BG2)"
        select CACHE_L2X0
@@ -30,6 +28,4 @@ config MACH_BERLIN_BG2Q
        select HAVE_ARM_TWD if SMP
        select PINCTRL_BERLIN_BG2Q
 
-endmenu
-
 endif
index 66838f4..3c22a19 100644 (file)
@@ -1,12 +1,11 @@
-config ARCH_CNS3XXX
+menuconfig ARCH_CNS3XXX
        bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
        select ARM_GIC
        select PCI_DOMAINS if PCI
        help
          Support for Cavium Networks CNS3XXX platform.
 
-menu "CNS3XXX platform type"
-       depends on ARCH_CNS3XXX
+if ARCH_CNS3XXX
 
 config MACH_CNS3420VB
        bool "Support for CNS3420 Validation Board"
@@ -17,4 +16,4 @@ config MACH_CNS3420VB
          This is a platform with an on-board ARM11 MPCore and has support
          for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc.
 
-endmenu
+endif
index db18ef8..584e8d4 100644 (file)
@@ -39,7 +39,6 @@ config ARCH_DAVINCI_DA830
 config ARCH_DAVINCI_DA850
        bool "DA850/OMAP-L138/AM18x based system"
        select ARCH_DAVINCI_DA8XX
-       select ARCH_HAS_CPUFREQ
        select CP_INTC
 
 config ARCH_DAVINCI_DA8XX
index d58995c..8f9b66c 100644 (file)
@@ -7,10 +7,9 @@
 
 # Configuration options for the EXYNOS4
 
-config ARCH_EXYNOS
+menuconfig ARCH_EXYNOS
        bool "Samsung EXYNOS" if ARCH_MULTI_V7
        select ARCH_HAS_BANDGAP
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
@@ -30,8 +29,6 @@ config ARCH_EXYNOS
 
 if ARCH_EXYNOS
 
-menu "SAMSUNG EXYNOS SoCs Support"
-
 config ARCH_EXYNOS3
        bool "SAMSUNG EXYNOS3"
        select ARM_CPU_SUSPEND if PM
@@ -118,8 +115,6 @@ config SOC_EXYNOS5800
        default y
        depends on SOC_EXYNOS5420
 
-endmenu
-
 config EXYNOS5420_MCPM
        bool "Exynos5420 Multi-Cluster PM support"
        depends on MCPM && SOC_EXYNOS5420
index 16617bd..1ee9176 100644 (file)
@@ -118,6 +118,7 @@ extern void __iomem *sysram_ns_base_addr;
 extern void __iomem *sysram_base_addr;
 void exynos_init_io(void);
 void exynos_restart(enum reboot_mode mode, const char *cmd);
+void exynos_sysram_init(void);
 void exynos_cpuidle_init(void);
 void exynos_cpufreq_init(void);
 void exynos_init_late(void);
index 90aab4d..f38cf7c 100644 (file)
@@ -184,6 +184,28 @@ void __init exynos_cpufreq_init(void)
        platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
 }
 
+void __iomem *sysram_base_addr;
+void __iomem *sysram_ns_base_addr;
+
+void __init exynos_sysram_init(void)
+{
+       struct device_node *node;
+
+       for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram") {
+               if (!of_device_is_available(node))
+                       continue;
+               sysram_base_addr = of_iomap(node, 0);
+               break;
+       }
+
+       for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram-ns") {
+               if (!of_device_is_available(node))
+                       continue;
+               sysram_ns_base_addr = of_iomap(node, 0);
+               break;
+       }
+}
+
 void __init exynos_init_late(void)
 {
        if (of_machine_is_compatible("samsung,exynos5440"))
@@ -198,7 +220,7 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
                                        int depth, void *data)
 {
        struct map_desc iodesc;
-       __be32 *reg;
+       const __be32 *reg;
        int len;
 
        if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
@@ -271,6 +293,13 @@ static void __init exynos_dt_machine_init(void)
                }
        }
 
+       /*
+        * This is called from smp_prepare_cpus if we've built for SMP, but
+        * we still need to set it up for PM and firmware ops if not.
+        */
+       if (!IS_ENABLED(SMP))
+               exynos_sysram_init();
+
        exynos_cpuidle_init();
        exynos_cpufreq_init();
 
index 69fa483..8a134d0 100644 (file)
@@ -46,13 +46,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
                if (cpu == 1)
                        exynos_cpu_power_down(cpu);
 
-               /*
-                * here's the WFI
-                */
-               asm(".word      0xe320f003\n"
-                   :
-                   :
-                   : "memory", "cc");
+               wfi();
 
                if (pen_release == cpu_logical_map(cpu)) {
                        /*
index 0498d0b..ace0ed6 100644 (file)
@@ -25,7 +25,6 @@
 
 #define EXYNOS5420_CPUS_PER_CLUSTER    4
 #define EXYNOS5420_NR_CLUSTERS         2
-#define MCPM_BOOT_ADDR_OFFSET          0x1c
 
 /*
  * The common v7_exit_coherency_flush API could not be used because of the
@@ -343,11 +342,13 @@ static int __init exynos_mcpm_init(void)
        pr_info("Exynos MCPM support installed\n");
 
        /*
-        * Future entries into the kernel can now go
-        * through the cluster entry vectors.
+        * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
+        * as part of secondary_cpu_start().  Let's redirect it to the
+        * mcpm_entry_point().
         */
-       __raw_writel(virt_to_phys(mcpm_entry_point),
-                       ns_sram_base_addr + MCPM_BOOT_ADDR_OFFSET);
+       __raw_writel(0xe59f0000, ns_sram_base_addr);     /* ldr r0, [pc, #0] */
+       __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx  r0 */
+       __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
 
        iounmap(ns_sram_base_addr);
 
index ec02422..1c8d31e 100644 (file)
 
 extern void exynos4_secondary_startup(void);
 
-void __iomem *sysram_base_addr;
-void __iomem *sysram_ns_base_addr;
-
-static void __init exynos_smp_prepare_sysram(void)
-{
-       struct device_node *node;
-
-       for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram") {
-               if (!of_device_is_available(node))
-                       continue;
-               sysram_base_addr = of_iomap(node, 0);
-               break;
-       }
-
-       for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram-ns") {
-               if (!of_device_is_available(node))
-                       continue;
-               sysram_ns_base_addr = of_iomap(node, 0);
-               break;
-       }
-}
-
 static inline void __iomem *cpu_boot_reg_base(void)
 {
        if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
@@ -234,11 +212,11 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
        int i;
 
+       exynos_sysram_init();
+
        if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
                scu_enable(scu_base_addr());
 
-       exynos_smp_prepare_sysram();
-
        /*
         * Write the address of secondary startup into the
         * system-wide flags register. The boot monitor waits
index 87c0d34..202ca73 100644 (file)
@@ -300,7 +300,7 @@ static int exynos_pm_suspend(void)
        tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
        __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
 
-       if (!soc_is_exynos5250())
+       if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
                exynos_cpu_save_register();
 
        return 0;
@@ -334,7 +334,7 @@ static void exynos_pm_resume(void)
        if (exynos_pm_central_resume())
                goto early_wakeup;
 
-       if (!soc_is_exynos5250())
+       if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
                exynos_cpu_restore_register();
 
        /* For release retention */
@@ -353,7 +353,7 @@ static void exynos_pm_resume(void)
 
        s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
 
-       if (!soc_is_exynos5250())
+       if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
                scu_enable(S5P_VA_SCU);
 
 early_wakeup:
@@ -440,15 +440,18 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
        case CPU_PM_ENTER:
                if (cpu == 0) {
                        exynos_pm_central_suspend();
-                       exynos_cpu_save_register();
+                       if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
+                               exynos_cpu_save_register();
                }
                break;
 
        case CPU_PM_EXIT:
                if (cpu == 0) {
-                       if (!soc_is_exynos5250())
+                       if (read_cpuid_part_number() ==
+                                       ARM_CPU_PART_CORTEX_A9) {
                                scu_enable(S5P_VA_SCU);
-                       exynos_cpu_restore_register();
+                               exynos_cpu_restore_register();
+                       }
                        exynos_pm_central_resume();
                }
                break;
index 830b76e..a5960e2 100644 (file)
@@ -1,7 +1,6 @@
 config ARCH_HIGHBANK
        bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
        select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_HAS_OPP
        select ARCH_SUPPORTS_BIG_ENDIAN
index 8d42eab..4b51857 100644 (file)
@@ -1,6 +1,5 @@
-config ARCH_MXC
+menuconfig ARCH_MXC
        bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_CPU_SUSPEND if PM
@@ -13,8 +12,7 @@ config ARCH_MXC
        help
          Support for Freescale MXC/iMX-based family of processors
 
-menu "Freescale i.MX support"
-       depends on ARCH_MXC
+if ARCH_MXC
 
 config MXC_TZIC
        bool
@@ -99,7 +97,6 @@ config SOC_IMX25
 
 config SOC_IMX27
        bool
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select CPU_ARM926T
        select IMX_HAVE_IOMUX_V1
@@ -124,7 +121,6 @@ config SOC_IMX35
 
 config SOC_IMX5
        bool
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select ARCH_MXC_IOMUX_V3
        select MXC_TZIC
@@ -738,9 +734,9 @@ config SOC_IMX6
        select HAVE_IMX_MMDC
        select HAVE_IMX_SRC
        select MFD_SYSCON
-       select PL310_ERRATA_588369 if CACHE_PL310
-       select PL310_ERRATA_727915 if CACHE_PL310
-       select PL310_ERRATA_769419 if CACHE_PL310
+       select PL310_ERRATA_588369 if CACHE_L2X0
+       select PL310_ERRATA_727915 if CACHE_L2X0
+       select PL310_ERRATA_769419 if CACHE_L2X0
 
 config SOC_IMX6Q
        bool "i.MX6 Quad/DualLite support"
@@ -775,9 +771,9 @@ config SOC_VF610
        select ARM_GIC
        select PINCTRL_VF610
        select VF_PIT_TIMER
-       select PL310_ERRATA_588369 if CACHE_PL310
-       select PL310_ERRATA_727915 if CACHE_PL310
-       select PL310_ERRATA_769419 if CACHE_PL310
+       select PL310_ERRATA_588369 if CACHE_L2X0
+       select PL310_ERRATA_727915 if CACHE_L2X0
+       select PL310_ERRATA_769419 if CACHE_L2X0
 
        help
          This enable support for Freescale Vybrid VF610 processor.
@@ -786,4 +782,4 @@ endif
 
 source "arch/arm/mach-imx/devices/Kconfig"
 
-endmenu
+endif
index 21cf06c..5408ca7 100644 (file)
@@ -312,6 +312,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        clks[IMX6SL_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",       "ecspi_root",        base + 0x6c, 2);
        clks[IMX6SL_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",       "ecspi_root",        base + 0x6c, 4);
        clks[IMX6SL_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",       "ecspi_root",        base + 0x6c, 6);
+       clks[IMX6SL_CLK_ENET]         = imx_clk_gate2("enet",         "ipg",               base + 0x6c, 10);
        clks[IMX6SL_CLK_EPIT1]        = imx_clk_gate2("epit1",        "perclk",            base + 0x6c, 12);
        clks[IMX6SL_CLK_EPIT2]        = imx_clk_gate2("epit2",        "perclk",            base + 0x6c, 14);
        clks[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16);
index ba43321..64f8e25 100644 (file)
@@ -28,7 +28,7 @@ config ARCH_CINTEGRATOR
        bool
 
 config INTEGRATOR_IMPD1
-       tristate "Include support for Integrator/IM-PD1"
+       bool "Include support for Integrator/IM-PD1"
        depends on ARCH_INTEGRATOR_AP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_VIC
index 0e870ea..3ce8807 100644 (file)
@@ -308,7 +308,12 @@ static struct impd1_device impd1_devs[] = {
  */
 #define IMPD1_VALID_IRQS 0x00000bffU
 
-static int __init impd1_probe(struct lm_device *dev)
+/*
+ * As this module is bool, it is OK to have this as __init_refok() - no
+ * probe calls will be done after the initial system bootup, as devices
+ * are discovered as part of the machine startup.
+ */
+static int __init_refok impd1_probe(struct lm_device *dev)
 {
        struct impd1_module *impd1;
        int irq_base;
@@ -397,6 +402,11 @@ static void impd1_remove(struct lm_device *dev)
 static struct lm_driver impd1_driver = {
        .drv = {
                .name   = "impd1",
+               /*
+                * As we're dropping the probe() function, suppress driver
+                * binding from sysfs.
+                */
+               .suppress_bind_attrs = true,
        },
        .probe          = impd1_probe,
        .remove         = impd1_remove,
index dd0cc67..660ca6f 100644 (file)
@@ -480,25 +480,18 @@ static const struct of_device_id ebi_match[] = {
 static void __init ap_init_of(void)
 {
        unsigned long sc_dec;
-       struct device_node *root;
        struct device_node *syscon;
        struct device_node *ebi;
        struct device *parent;
        struct soc_device *soc_dev;
        struct soc_device_attribute *soc_dev_attr;
        u32 ap_sc_id;
-       int err;
        int i;
 
-       /* Here we create an SoC device for the root node */
-       root = of_find_node_by_path("/");
-       if (!root)
-               return;
-
-       syscon = of_find_matching_node(root, ap_syscon_match);
+       syscon = of_find_matching_node(NULL, ap_syscon_match);
        if (!syscon)
                return;
-       ebi = of_find_matching_node(root, ebi_match);
+       ebi = of_find_matching_node(NULL, ebi_match);
        if (!ebi)
                return;
 
@@ -509,19 +502,17 @@ static void __init ap_init_of(void)
        if (!ebi_base)
                return;
 
+       of_platform_populate(NULL, of_default_bus_match_table,
+                       ap_auxdata_lookup, NULL);
+
        ap_sc_id = readl(ap_syscon_base);
 
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
        if (!soc_dev_attr)
                return;
 
-       err = of_property_read_string(root, "compatible",
-                                     &soc_dev_attr->soc_id);
-       if (err)
-               return;
-       err = of_property_read_string(root, "model", &soc_dev_attr->machine);
-       if (err)
-               return;
+       soc_dev_attr->soc_id = "XVC";
+       soc_dev_attr->machine = "Integrator/AP";
        soc_dev_attr->family = "Integrator";
        soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
                                           'A' + (ap_sc_id & 0x0f));
@@ -536,9 +527,6 @@ static void __init ap_init_of(void)
        parent = soc_device_to_device(soc_dev);
        integrator_init_sysfs(parent, ap_sc_id);
 
-       of_platform_populate(root, of_default_bus_match_table,
-                       ap_auxdata_lookup, parent);
-
        sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
        for (i = 0; i < 4; i++) {
                struct lm_device *lmdev;
index a938242..0e57f8f 100644 (file)
@@ -279,20 +279,13 @@ static const struct of_device_id intcp_syscon_match[] = {
 
 static void __init intcp_init_of(void)
 {
-       struct device_node *root;
        struct device_node *cpcon;
        struct device *parent;
        struct soc_device *soc_dev;
        struct soc_device_attribute *soc_dev_attr;
        u32 intcp_sc_id;
-       int err;
 
-       /* Here we create an SoC device for the root node */
-       root = of_find_node_by_path("/");
-       if (!root)
-               return;
-
-       cpcon = of_find_matching_node(root, intcp_syscon_match);
+       cpcon = of_find_matching_node(NULL, intcp_syscon_match);
        if (!cpcon)
                return;
 
@@ -300,19 +293,17 @@ static void __init intcp_init_of(void)
        if (!intcp_con_base)
                return;
 
+       of_platform_populate(NULL, of_default_bus_match_table,
+                            intcp_auxdata_lookup, NULL);
+
        intcp_sc_id = readl(intcp_con_base);
 
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
        if (!soc_dev_attr)
                return;
 
-       err = of_property_read_string(root, "compatible",
-                                     &soc_dev_attr->soc_id);
-       if (err)
-               return;
-       err = of_property_read_string(root, "model", &soc_dev_attr->machine);
-       if (err)
-               return;
+       soc_dev_attr->soc_id = "XCV";
+       soc_dev_attr->machine = "Integrator/CP";
        soc_dev_attr->family = "Integrator";
        soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
                                           'A' + (intcp_sc_id & 0x0f));
@@ -326,8 +317,6 @@ static void __init intcp_init_of(void)
 
        parent = soc_device_to_device(soc_dev);
        integrator_init_sysfs(parent, intcp_sc_id);
-       of_platform_populate(root, of_default_bus_match_table,
-                       intcp_auxdata_lookup, parent);
 }
 
 static const char * intcp_dt_board_compat[] = {
index f50bc93..98a156a 100644 (file)
@@ -1,6 +1,7 @@
 config ARCH_KEYSTONE
        bool "Texas Instruments Keystone Devices"
        depends on ARCH_MULTI_V7
+       depends on ARM_PATCH_PHYS_VIRT
        select ARM_GIC
        select HAVE_ARM_ARCH_TIMER
        select CLKSRC_MMIO
index 82a4ba8..f49328c 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_MOXART
+menuconfig ARCH_MOXART
        bool "MOXA ART SoC" if ARCH_MULTI_V4
        select CPU_FA526
        select ARM_DMA_MEM_BUFFERABLE
index 6090b9e..b9bc599 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_MVEBU
+menuconfig ARCH_MVEBU
        bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V5)
        select ARCH_SUPPORTS_BIG_ENDIAN
        select CLKSRC_MMIO
@@ -10,15 +10,15 @@ config ARCH_MVEBU
        select ZONE_DMA if ARM_LPAE
        select ARCH_REQUIRE_GPIOLIB
        select PCI_QUIRKS if PCI
+       select OF_ADDRESS_PCI
 
 if ARCH_MVEBU
 
-menu "Marvell EBU SoC variants"
-
 config MACH_MVEBU_V7
        bool
        select ARMADA_370_XP_TIMER
        select CACHE_L2X0
+       select ARM_CPU_SUSPEND
 
 config MACH_ARMADA_370
        bool "Marvell Armada 370 boards" if ARCH_MULTI_V7
@@ -84,7 +84,6 @@ config MACH_DOVE
 
 config MACH_KIRKWOOD
        bool "Marvell Kirkwood boards" if ARCH_MULTI_V5
-       select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select CPU_FEROCEON
        select KIRKWOOD_CLK
@@ -97,6 +96,4 @@ config MACH_KIRKWOOD
          Say 'Y' here if you want your kernel to support boards based
          on the Marvell Kirkwood device tree.
 
-endmenu
-
 endif
index 486d301..3c61096 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_NOMADIK
+menuconfig ARCH_NOMADIK
        bool "ST-Ericsson Nomadik"
        depends on ARCH_MULTI_V5
        select ARCH_REQUIRE_GPIOLIB
@@ -15,7 +15,6 @@ config ARCH_NOMADIK
          Support for the Nomadik platform by ST-Ericsson
 
 if ARCH_NOMADIK
-menu "Nomadik boards"
 
 config MACH_NOMADIK_8815NHK
        bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
@@ -24,7 +23,6 @@ config MACH_NOMADIK_8815NHK
        select I2C_ALGOBIT
        select I2C_NOMADIK
 
-endmenu
 endif
 
 config NOMADIK_8815
index 0ba4826..1c1ed73 100644 (file)
@@ -1,3 +1,6 @@
+menu "TI OMAP/AM/DM/DRA Family"
+       depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
+
 config ARCH_OMAP
        bool
 
@@ -28,12 +31,11 @@ config ARCH_OMAP4
        select ARM_CPU_SUSPEND if PM
        select ARM_ERRATA_720789
        select ARM_GIC
-       select CACHE_L2X0
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select OMAP_INTERCONNECT
-       select PL310_ERRATA_588369
-       select PL310_ERRATA_727915
+       select PL310_ERRATA_588369 if CACHE_L2X0
+       select PL310_ERRATA_727915 if CACHE_L2X0
        select PM_OPP if PM
        select PM_RUNTIME if CPU_IDLE
        select ARM_ERRATA_754322
@@ -80,7 +82,6 @@ config SOC_DRA7XX
 config ARCH_OMAP2PLUS
        bool
        select ARCH_HAS_BANDGAP
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_OMAP
        select ARCH_REQUIRE_GPIOLIB
@@ -343,3 +344,5 @@ config OMAP4_ERRATA_I688
 endmenu
 
 endif
+
+endmenu
index ff02973..a373d50 100644 (file)
@@ -91,7 +91,14 @@ extern void omap3_sync32k_timer_init(void);
 extern void omap3_secure_sync32k_timer_init(void);
 extern void omap3_gptimer_timer_init(void);
 extern void omap4_local_timer_init(void);
+#ifdef CONFIG_CACHE_L2X0
 int omap_l2_cache_init(void);
+#else
+static inline int omap_l2_cache_init(void)
+{
+       return 0;
+}
+#endif
 extern void omap5_realtime_timer_init(void);
 
 void omap2420_init_early(void);
index e4e505f..042f693 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_SIRF
+menuconfig ARCH_SIRF
        bool "CSR SiRF" if ARCH_MULTI_V7
        select ARCH_HAS_RESET_CONTROLLER
        select ARCH_REQUIRE_GPIOLIB
@@ -11,7 +11,7 @@ config ARCH_SIRF
 
 if ARCH_SIRF
 
-menu "CSR SiRF atlas6/primaII/Marco/Polo Specific Features"
+comment "CSR SiRF atlas6/primaII/Marco/Polo Specific Features"
 
 config ARCH_ATLAS6
        bool "CSR SiRFSoC ATLAS6 ARM Cortex A9 Platform"
@@ -37,8 +37,6 @@ config ARCH_MARCO
        help
           Support for CSR SiRFSoC ARM Cortex A9 Platform
 
-endmenu
-
 config SIRF_IRQ
        bool
 
index fd2b99d..ee5697b 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_QCOM
+menuconfig ARCH_QCOM
        bool "Qualcomm Support" if ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select ARM_GIC
@@ -11,8 +11,6 @@ config ARCH_QCOM
 
 if ARCH_QCOM
 
-menu "Qualcomm SoC Selection"
-
 config ARCH_MSM8X60
        bool "Enable support for MSM8X60"
        select CLKSRC_QCOM
@@ -25,8 +23,6 @@ config ARCH_MSM8974
        bool "Enable support for MSM8974"
        select HAVE_ARM_ARCH_TIMER
 
-endmenu
-
 config QCOM_SCM
        bool
 
index 04284de..ad5316a 100644 (file)
@@ -117,7 +117,7 @@ config S3C24XX_SETUP_TS
          Compile in platform device definition for Samsung TouchScreen.
 
 config S3C24XX_DMA
-       bool "S3C2410 DMA support"
+       bool "S3C2410 DMA support (deprecated)"
        select S3C_DMA
        help
          S3C2410 DMA support. This is needed for drivers like sound which
index 3136d86..26ca242 100644 (file)
@@ -18,9 +18,9 @@ config CPU_S3C6410
          Enable S3C6410 CPU support
 
 config S3C64XX_PL080
-       bool "S3C64XX DMA using generic PL08x driver"
+       def_bool DMADEVICES
+       select ARM_AMBA
        select AMBA_PL08X
-       select SAMSUNG_DMADEV
 
 config S3C64XX_SETUP_SDHCI
        bool
index bb2111b..26003e2 100644 (file)
@@ -9,16 +9,18 @@ if ARCH_S5P64X0
 
 config CPU_S5P6440
        bool
+       select ARM_AMBA
+       select PL330_DMA if DMADEVICES
        select S5P_SLEEP if PM
-       select SAMSUNG_DMADEV
        select SAMSUNG_WAKEMASK if PM
        help
          Enable S5P6440 CPU support
 
 config CPU_S5P6450
        bool
+       select ARM_AMBA
+       select PL330_DMA if DMADEVICES
        select S5P_SLEEP if PM
-       select SAMSUNG_DMADEV
        select SAMSUNG_WAKEMASK if PM
        help
          Enable S5P6450 CPU support
index 15170be..c5e3a96 100644 (file)
@@ -9,8 +9,9 @@ if ARCH_S5PC100
 
 config CPU_S5PC100
        bool
+       select ARM_AMBA
+       select PL330_DMA if DMADEVICES
        select S5P_EXT_INT
-       select SAMSUNG_DMADEV
        help
          Enable S5PC100 CPU support
 
index 8c3abe5..f60f286 100644 (file)
@@ -11,10 +11,11 @@ if ARCH_S5PV210
 
 config CPU_S5PV210
        bool
+       select ARM_AMBA
+       select PL330_DMA if DMADEVICES
        select S5P_EXT_INT
        select S5P_PM if PM
        select S5P_SLEEP if PM
-       select SAMSUNG_DMADEV
        help
          Enable S5PV210 CPU support
 
index f9874ba..108939f 100644 (file)
@@ -329,6 +329,11 @@ static struct mtd_partition collie_partitions[] = {
                .name           = "rootfs",
                .offset         = MTDPART_OFS_APPEND,
                .size           = 0x00e20000,
+       }, {
+               .name           = "bootblock",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 0x00020000,
+               .mask_flags     = MTD_WRITEABLE
        }
 };
 
@@ -356,7 +361,7 @@ static void collie_flash_exit(void)
 }
 
 static struct flash_platform_data collie_flash_data = {
-       .map_name       = "jedec_probe",
+       .map_name       = "cfi_probe",
        .init           = collie_flash_init,
        .set_vpp        = collie_set_vpp,
        .exit           = collie_flash_exit,
index dbd954e..7980730 100644 (file)
@@ -1,7 +1,7 @@
 config ARCH_SHMOBILE
        bool
 
-config ARCH_SHMOBILE_MULTI
+menuconfig ARCH_SHMOBILE_MULTI
        bool "Renesas ARM SoCs" if ARCH_MULTI_V7
        depends on MMU
        select ARCH_SHMOBILE
@@ -15,7 +15,7 @@ config ARCH_SHMOBILE_MULTI
 
 if ARCH_SHMOBILE_MULTI
 
-comment "Renesas ARM SoCs System Type"
+#comment "Renesas ARM SoCs System Type"
 
 config ARCH_EMEV2
        bool "Emma Mobile EV2"
@@ -85,7 +85,6 @@ config ARCH_R8A73A4
        select CPU_V7
        select SH_CLK_CPG
        select RENESAS_IRQC
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select SYS_SUPPORTS_SH_CMT
        select SYS_SUPPORTS_SH_TMU
@@ -264,7 +263,6 @@ config MACH_KOELSCH
 config MACH_KZM9G
        bool "KZM-A9-GT board"
        depends on ARCH_SH73A0
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select ARCH_REQUIRE_GPIOLIB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
index 0786249..6fd4dc8 100644 (file)
@@ -14,12 +14,13 @@ if PLAT_SPEAR
 config ARCH_SPEAR13XX
        bool "ST SPEAr13xx"
        depends on ARCH_MULTI_V7 || PLAT_SPEAR_SINGLE
-       select ARCH_HAS_CPUFREQ
        select ARM_GIC
        select GPIO_SPEAR_SPICS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select PINCTRL
+       select MFD_SYSCON
+       select MIGHT_HAVE_PCI
        help
          Supports for ARM's SPEAR13XX family
 
@@ -28,12 +29,14 @@ if ARCH_SPEAR13XX
 config MACH_SPEAR1310
        bool "SPEAr1310 Machine support with Device Tree"
        select PINCTRL_SPEAR1310
+       select PHY_ST_SPEAR1310_MIPHY
        help
          Supports ST SPEAr1310 machine configured via the device-tree
 
 config MACH_SPEAR1340
        bool "SPEAr1340 Machine support with Device Tree"
        select PINCTRL_SPEAR1340
+       select PHY_ST_SPEAR1340_MIPHY
        help
          Supports ST SPEAr1340 machine configured via the device-tree
 
index 5cdc53d..f2d6a01 100644 (file)
 #ifdef CONFIG_ARCH_SPEAR13XX
 
 #define PERIP_GRP2_BASE                                UL(0xB3000000)
-#define VA_PERIP_GRP2_BASE                     IOMEM(0xFE000000)
+#define VA_PERIP_GRP2_BASE                     IOMEM(0xF9000000)
 #define MCIF_SDHCI_BASE                                UL(0xB3000000)
 #define SYSRAM0_BASE                           UL(0xB3800000)
-#define VA_SYSRAM0_BASE                                IOMEM(0xFE800000)
+#define VA_SYSRAM0_BASE                                IOMEM(0xF9800000)
 #define SYS_LOCATION                           (VA_SYSRAM0_BASE + 0x600)
 
 #define PERIP_GRP1_BASE                                UL(0xE0000000)
index 7b6bff7..3f3c0f1 100644 (file)
 
 #define pr_fmt(fmt) "SPEAr1340: " fmt
 
-#include <linux/ahci_platform.h>
-#include <linux/amba/serial.h>
-#include <linux/delay.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include "generic.h"
-#include <mach/spear.h>
-
-/* FIXME: Move SATA PHY code into a standalone driver */
-
-/* Base addresses */
-#define SPEAR1340_SATA_BASE                    UL(0xB1000000)
-
-/* Power Management Registers */
-#define SPEAR1340_PCM_CFG                      (VA_MISC_BASE + 0x100)
-#define SPEAR1340_PCM_WKUP_CFG                 (VA_MISC_BASE + 0x104)
-#define SPEAR1340_SWITCH_CTR                   (VA_MISC_BASE + 0x108)
-
-#define SPEAR1340_PERIP1_SW_RST                        (VA_MISC_BASE + 0x318)
-#define SPEAR1340_PERIP2_SW_RST                        (VA_MISC_BASE + 0x31C)
-#define SPEAR1340_PERIP3_SW_RST                        (VA_MISC_BASE + 0x320)
-
-/* PCIE - SATA configuration registers */
-#define SPEAR1340_PCIE_SATA_CFG                        (VA_MISC_BASE + 0x424)
-       /* PCIE CFG MASks */
-       #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT       (1 << 11)
-       #define SPEAR1340_PCIE_CFG_POWERUP_RESET        (1 << 10)
-       #define SPEAR1340_PCIE_CFG_CORE_CLK_EN          (1 << 9)
-       #define SPEAR1340_PCIE_CFG_AUX_CLK_EN           (1 << 8)
-       #define SPEAR1340_SATA_CFG_TX_CLK_EN            (1 << 4)
-       #define SPEAR1340_SATA_CFG_RX_CLK_EN            (1 << 3)
-       #define SPEAR1340_SATA_CFG_POWERUP_RESET        (1 << 2)
-       #define SPEAR1340_SATA_CFG_PM_CLK_EN            (1 << 1)
-       #define SPEAR1340_PCIE_SATA_SEL_PCIE            (0)
-       #define SPEAR1340_PCIE_SATA_SEL_SATA            (1)
-       #define SPEAR1340_SATA_PCIE_CFG_MASK            0xF1F
-       #define SPEAR1340_PCIE_CFG_VAL  (SPEAR1340_PCIE_SATA_SEL_PCIE | \
-                       SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
-                       SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
-                       SPEAR1340_PCIE_CFG_POWERUP_RESET | \
-                       SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
-       #define SPEAR1340_SATA_CFG_VAL  (SPEAR1340_PCIE_SATA_SEL_SATA | \
-                       SPEAR1340_SATA_CFG_PM_CLK_EN | \
-                       SPEAR1340_SATA_CFG_POWERUP_RESET | \
-                       SPEAR1340_SATA_CFG_RX_CLK_EN | \
-                       SPEAR1340_SATA_CFG_TX_CLK_EN)
-
-#define SPEAR1340_PCIE_MIPHY_CFG               (VA_MISC_BASE + 0x428)
-       #define SPEAR1340_MIPHY_OSC_BYPASS_EXT          (1 << 31)
-       #define SPEAR1340_MIPHY_CLK_REF_DIV2            (1 << 27)
-       #define SPEAR1340_MIPHY_CLK_REF_DIV4            (2 << 27)
-       #define SPEAR1340_MIPHY_CLK_REF_DIV8            (3 << 27)
-       #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)        (x << 0)
-       #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
-                       (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
-                       SPEAR1340_MIPHY_CLK_REF_DIV2 | \
-                       SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
-       #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
-                       (SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
-       #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
-                       (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
-                       SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
-
-/* SATA device registration */
-static int sata_miphy_init(struct device *dev, void __iomem *addr)
-{
-       writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
-       writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
-                       SPEAR1340_PCIE_MIPHY_CFG);
-       /* Switch on sata power domain */
-       writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
-       msleep(20);
-       /* Disable PCIE SATA Controller reset */
-       writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
-                       SPEAR1340_PERIP1_SW_RST);
-       msleep(20);
-
-       return 0;
-}
-
-void sata_miphy_exit(struct device *dev)
-{
-       writel(0, SPEAR1340_PCIE_SATA_CFG);
-       writel(0, SPEAR1340_PCIE_MIPHY_CFG);
-
-       /* Enable PCIE SATA Controller reset */
-       writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
-                       SPEAR1340_PERIP1_SW_RST);
-       msleep(20);
-       /* Switch off sata power domain */
-       writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
-       msleep(20);
-}
-
-int sata_suspend(struct device *dev)
-{
-       if (dev->power.power_state.event == PM_EVENT_FREEZE)
-               return 0;
-
-       sata_miphy_exit(dev);
-
-       return 0;
-}
-
-int sata_resume(struct device *dev)
-{
-       if (dev->power.power_state.event == PM_EVENT_THAW)
-               return 0;
-
-       return sata_miphy_init(dev, NULL);
-}
-
-static struct ahci_platform_data sata_pdata = {
-       .init = sata_miphy_init,
-       .exit = sata_miphy_exit,
-       .suspend = sata_suspend,
-       .resume = sata_resume,
-};
-
-/* Add SPEAr1340 auxdata to pass platform data */
-static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
-                       &sata_pdata),
-       {}
-};
 
 static void __init spear1340_dt_init(void)
 {
-       of_platform_populate(NULL, of_default_bus_match_table,
-                       spear1340_auxdata_lookup, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
        platform_device_register_simple("spear-cpufreq", -1, NULL, 0);
 }
 
index c9897ea..53a7614 100644 (file)
@@ -52,7 +52,7 @@ void __init spear13xx_l2x0_init(void)
 /*
  * Following will create 16MB static virtual/physical mappings
  * PHYSICAL            VIRTUAL
- * 0xB3000000          0xFE000000
+ * 0xB3000000          0xF9000000
  * 0xE0000000          0xFD000000
  * 0xEC000000          0xFC000000
  * 0xED000000          0xFB000000
index abf9ee9..878e9ec 100644 (file)
@@ -1,5 +1,5 @@
 menuconfig ARCH_STI
-       bool "STMicroelectronics Consumer Electronics SOCs with Device Trees" if ARCH_MULTI_V7
+       bool "STMicroelectronics Consumer Electronics SOCs" if ARCH_MULTI_V7
        select ARM_GIC
        select ARM_GLOBAL_TIMER
        select PINCTRL
@@ -11,8 +11,8 @@ menuconfig ARCH_STI
        select ARM_ERRATA_754322
        select ARM_ERRATA_764369 if SMP
        select ARM_ERRATA_775420
-       select PL310_ERRATA_753970 if CACHE_PL310
-       select PL310_ERRATA_769419 if CACHE_PL310
+       select PL310_ERRATA_753970 if CACHE_L2X0
+       select PL310_ERRATA_769419 if CACHE_L2X0
        help
          Include support for STiH41x SOCs like STiH415/416 using the device tree
          for discovery
index e16999e..0953996 100644 (file)
@@ -1,6 +1,5 @@
-config ARCH_TEGRA
+menuconfig ARCH_TEGRA
        bool "NVIDIA Tegra" if ARCH_MULTI_V7
-       select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
        select ARM_GIC
@@ -16,8 +15,7 @@ config ARCH_TEGRA
        help
          This enables support for NVIDIA Tegra based systems.
 
-menu "NVIDIA Tegra options"
-       depends on ARCH_TEGRA
+if ARCH_TEGRA
 
 config ARCH_TEGRA_2x_SOC
        bool "Enable support for Tegra20 family"
@@ -69,4 +67,4 @@ config TEGRA_AHB
          which controls AHB bus master arbitration and some
          performance parameters(priority, prefech size).
 
-endmenu
+endif
index e3a96d7..bc51a71 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_U300
+menuconfig ARCH_U300
        bool "ST-Ericsson U300 Series" if ARCH_MULTI_V5
        depends on MMU
        select ARCH_REQUIRE_GPIOLIB
@@ -16,8 +16,6 @@ config ARCH_U300
 
 if ARCH_U300
 
-menu "ST-Ericsson AB U300/U335 Platform"
-
 config MACH_U300
        depends on ARCH_U300
        bool "U300"
@@ -43,6 +41,4 @@ config MACH_U300_SPIDUMMY
                you don't need it. Selecting this will activate the
                SPI framework and ARM PL022 support.
 
-endmenu
-
 endif
index b41a42d..699e860 100644 (file)
@@ -1,9 +1,8 @@
-config ARCH_U8500
+menuconfig ARCH_U8500
        bool "ST-Ericsson U8500 Series" if ARCH_MULTI_V7
        depends on MMU
        select AB8500_CORE
        select ABX500_CORE
-       select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select ARM_ERRATA_754322
@@ -16,7 +15,7 @@ config ARCH_U8500
        select PINCTRL
        select PINCTRL_ABX500
        select PINCTRL_NOMADIK
-       select PL310_ERRATA_753970 if CACHE_PL310
+       select PL310_ERRATA_753970 if CACHE_L2X0
        help
          Support for ST-Ericsson's Ux500 architecture
 
@@ -34,8 +33,6 @@ config UX500_SOC_DB8500
        select REGULATOR
        select REGULATOR_DB8500_PRCMU
 
-menu "Ux500 target platform (boards)"
-
 config MACH_MOP500
        bool "U8500 Development platform, MOP500 versions"
        select I2C
@@ -68,8 +65,6 @@ config UX500_AUTO_PLATFORM
          a working kernel. If everything else is disabled, this
          automatically enables MACH_MOP500.
 
-endmenu
-
 config UX500_DEBUG_UART
        int "Ux500 UART to use for low-level debug"
        default 2
index 90249cf..d8b9330 100644 (file)
@@ -1,4 +1,4 @@
-config ARCH_VEXPRESS
+menuconfig ARCH_VEXPRESS
        bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_SUPPORTS_BIG_ENDIAN
@@ -37,14 +37,13 @@ config ARCH_VEXPRESS
          platforms. The traditional (ATAGs) boot method is not usable on
          these boards with this option.
 
-menu "Versatile Express platform type"
-       depends on ARCH_VEXPRESS
+if ARCH_VEXPRESS
 
 config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
        bool "Enable A5 and A9 only errata work-arounds"
        default y
        select ARM_ERRATA_720789
-       select PL310_ERRATA_753970 if CACHE_PL310
+       select PL310_ERRATA_753970 if CACHE_L2X0
        help
          Provides common dependencies for Versatile Express platforms
          based on Cortex-A5 and Cortex-A9 processors. In order to
@@ -65,7 +64,6 @@ config ARCH_VEXPRESS_DCSCB
 
 config ARCH_VEXPRESS_SPC
        bool "Versatile Express Serial Power Controller (SPC)"
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select PM_OPP
        help
@@ -83,4 +81,4 @@ config ARCH_VEXPRESS_TC2_PM
          Support for CPU and cluster power management on Versatile Express
          with a TC2 (A15x2 A7x3) big.LITTLE core tile.
 
-endmenu
+endif
index 08f56a4..aaaa24f 100644 (file)
@@ -1,6 +1,5 @@
 config ARCH_VT8500
        bool
-       select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select CLKDEV_LOOKUP
        select VT8500_TIMER
index 573e0db..0c164f8 100644 (file)
@@ -1,6 +1,5 @@
 config ARCH_ZYNQ
        bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
-       select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_AMBA
index eda0dd0..c348eae 100644 (file)
@@ -889,9 +889,10 @@ config CACHE_L2X0
        help
          This option enables the L2x0 PrimeCell.
 
+if CACHE_L2X0
+
 config CACHE_PL310
        bool
-       depends on CACHE_L2X0
        default y if CPU_V7 && !(CPU_V6 || CPU_V6K)
        help
          This option enables optimisations for the PL310 cache
@@ -899,7 +900,6 @@ config CACHE_PL310
 
 config PL310_ERRATA_588369
        bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
-       depends on CACHE_L2X0
        help
           The PL310 L2 cache controller implements three types of Clean &
           Invalidate maintenance operations: by Physical Address
@@ -912,7 +912,6 @@ config PL310_ERRATA_588369
 
 config PL310_ERRATA_727915
        bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
-       depends on CACHE_L2X0
        help
          PL310 implements the Clean & Invalidate by Way L2 cache maintenance
          operation (offset 0x7FC). This operation runs in background so that
@@ -923,7 +922,6 @@ config PL310_ERRATA_727915
 
 config PL310_ERRATA_753970
        bool "PL310 errata: cache sync operation may be faulty"
-       depends on CACHE_PL310
        help
          This option enables the workaround for the 753970 PL310 (r3p0) erratum.
 
@@ -938,7 +936,6 @@ config PL310_ERRATA_753970
 
 config PL310_ERRATA_769419
        bool "PL310 errata: no automatic Store Buffer drain"
-       depends on CACHE_L2X0
        help
          On revisions of the PL310 prior to r3p2, the Store Buffer does
          not automatically drain. This can cause normal, non-cacheable
@@ -948,6 +945,8 @@ config PL310_ERRATA_769419
          on systems with an outer cache, the store buffer is drained
          explicitly.
 
+endif
+
 config CACHE_TAUROS2
        bool "Enable the Tauros2 L2 cache controller"
        depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
index efc5cab..076172b 100644 (file)
@@ -1068,6 +1068,33 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
        },
 };
 
+/*
+ * This is a variant of the of_l2c310_data with .sync set to
+ * NULL. Outer sync operations are not needed when the system is I/O
+ * coherent, and potentially harmful in certain situations (PCIe/PL310
+ * deadlock on Armada 375/38x due to hardware I/O coherency). The
+ * other operations are kept because they are infrequent (therefore do
+ * not cause the deadlock in practice) and needed for secondary CPU
+ * boot and other power management activities.
+ */
+static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
+       .type = "L2C-310 Coherent",
+       .way_size_0 = SZ_8K,
+       .num_lock = 8,
+       .of_parse = l2c310_of_parse,
+       .enable = l2c310_enable,
+       .fixup = l2c310_fixup,
+       .save  = l2c310_save,
+       .outer_cache = {
+               .inv_range   = l2c210_inv_range,
+               .clean_range = l2c210_clean_range,
+               .flush_range = l2c210_flush_range,
+               .flush_all   = l2c210_flush_all,
+               .disable     = l2c310_disable,
+               .resume      = l2c310_resume,
+       },
+};
+
 /*
  * Note that the end addresses passed to Linux primitives are
  * noninclusive, while the hardware cache range operations use
@@ -1487,6 +1514,10 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 
        data = of_match_node(l2x0_ids, np)->data;
 
+       if (of_device_is_compatible(np, "arm,pl310-cache") &&
+           of_property_read_bool(np, "arm,io-coherent"))
+               data = &of_l2c310_coherent_data;
+
        old_aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
        if (old_aux != ((old_aux & aux_mask) | aux_val)) {
                pr_warn("L2C: platform modifies aux control register: 0x%08x -> 0x%08x\n",
index da1874f..a014dfa 100644 (file)
@@ -300,6 +300,7 @@ void __init sanity_check_meminfo(void)
        sanity_check_meminfo_mpu();
        end = memblock_end_of_DRAM();
        high_memory = __va(end - 1) + 1;
+       memblock_set_current_limit(end);
 }
 
 /*
index 97448c3..ba0d58e 100644 (file)
@@ -502,6 +502,7 @@ __\name\()_proc_info:
        .long   \cpu_val
        .long   \cpu_mask
        .long   PMD_TYPE_SECT | \
+               PMD_SECT_CACHEABLE | \
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
index 243dfcb..301b892 100644 (file)
@@ -35,27 +35,15 @@ config SAMSUNG_PM
          Base platform power management code for samsung code
 
 if PLAT_SAMSUNG
+menu "Samsung Common options"
 
 # boot configurations
 
 comment "Boot options"
 
-config S3C_BOOT_ERROR_RESET
-       bool "S3C Reboot on decompression error"
-       help
-         Say y here to use the watchdog to reset the system if the
-         kernel decompressor detects an error during decompression.
-
-config S3C_BOOT_UART_FORCE_FIFO
-       bool "Force UART FIFO on during boot process"
-       default y
-       help
-         Say Y here to force the UART FIFOs on during the kernel
-        uncompressor
-
-
 config S3C_LOWLEVEL_UART_PORT
        int "S3C UART to use for low-level messages"
+       depends on ARCH_S3C64XX
        default 0
        help
          Choice of which UART port to use for the low-level messages,
@@ -407,17 +395,16 @@ config SAMSUNG_PM_GPIO
          Include legacy GPIO power management code for platforms not using
          pinctrl-samsung driver.
 
-endif
-
 config SAMSUNG_DMADEV
-       bool
-       select ARM_AMBA
+       bool "Use legacy Samsung DMA abstraction"
+       depends on CPU_S5PV210 || CPU_S5PC100 || ARCH_S5P64X0 || ARCH_S3C64XX
        select DMADEVICES
-       select PL330_DMA if (ARCH_EXYNOS5 || ARCH_EXYNOS4 || CPU_S5PV210 || CPU_S5PC100 || \
-                                       CPU_S5P6450 || CPU_S5P6440)
+       default y
        help
          Use DMA device engine for PL330 DMAC.
 
+endif
+
 config S5P_DEV_MFC
        bool
        help
@@ -503,4 +490,5 @@ config DEBUG_S3C_UART
        default "2" if DEBUG_S3C_UART2
        default "3" if DEBUG_S3C_UART3
 
+endmenu
 endif
index 7295419..a474de3 100644 (file)
@@ -1,8 +1,9 @@
 config ARM64
        def_bool y
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
-       select ARCH_USE_CMPXCHG_LOCKREF
+       select ARCH_HAS_OPP
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+       select ARCH_USE_CMPXCHG_LOCKREF
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
        select ARCH_WANT_FRAME_POINTERS
index 1247ca1..6541962 100644 (file)
@@ -24,3 +24,7 @@
                reg = < 0x1 0x00000000 0x0 0x80000000 >; /* Updated by bootloader */
        };
 };
+
+&serial0 {
+       status = "ok";
+};
index c5f0a47..40aa96c 100644 (file)
                };
 
                serial0: serial@1c020000 {
+                       status = "disabled";
                        device_type = "serial";
-                       compatible = "ns16550";
+                       compatible = "ns16550a";
                        reg = <0 0x1c020000 0x0 0x1000>;
                        reg-shift = <2>;
                        clock-frequency = <10000000>; /* Updated by bootloader */
                        interrupts = <0x0 0x4c 0x4>;
                };
 
+               serial1: serial@1c021000 {
+                       status = "disabled";
+                       device_type = "serial";
+                       compatible = "ns16550a";
+                       reg = <0 0x1c021000 0x0 0x1000>;
+                       reg-shift = <2>;
+                       clock-frequency = <10000000>; /* Updated by bootloader */
+                       interrupt-parent = <&gic>;
+                       interrupts = <0x0 0x4d 0x4>;
+               };
+
+               serial2: serial@1c022000 {
+                       status = "disabled";
+                       device_type = "serial";
+                       compatible = "ns16550a";
+                       reg = <0 0x1c022000 0x0 0x1000>;
+                       reg-shift = <2>;
+                       clock-frequency = <10000000>; /* Updated by bootloader */
+                       interrupt-parent = <&gic>;
+                       interrupts = <0x0 0x4e 0x4>;
+               };
+
+               serial3: serial@1c023000 {
+                       status = "disabled";
+                       device_type = "serial";
+                       compatible = "ns16550a";
+                       reg = <0 0x1c023000 0x0 0x1000>;
+                       reg-shift = <2>;
+                       clock-frequency = <10000000>; /* Updated by bootloader */
+                       interrupt-parent = <&gic>;
+                       interrupts = <0x0 0x4f 0x4>;
+               };
+
                phy1: phy@1f21a000 {
                        compatible = "apm,xgene-phy";
                        reg = <0x0 0x1f21a000 0x0 0x100>;
index 157e1d8..3421f31 100644 (file)
@@ -6,9 +6,18 @@ CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_CGROUP_HUGETLB=y
 # CONFIG_UTS_NS is not set
 # CONFIG_IPC_NS is not set
 # CONFIG_PID_NS is not set
@@ -27,6 +36,7 @@ CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_XGENE=y
 CONFIG_SMP=y
 CONFIG_PREEMPT=y
+CONFIG_KSM=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=y
 CONFIG_CMDLINE="console=ttyAMA0"
@@ -45,6 +55,7 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DMA_CMA=y
+CONFIG_BLK_DEV_LOOP=y
 CONFIG_VIRTIO_BLK=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
@@ -53,6 +64,7 @@ CONFIG_ATA=y
 CONFIG_PATA_PLATFORM=y
 CONFIG_PATA_OF_PLATFORM=y
 CONFIG_NETDEVICES=y
+CONFIG_TUN=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
 # CONFIG_WLAN is not set
@@ -85,6 +97,8 @@ CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
 CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=y
 CONFIG_VFAT_FS=y
@@ -104,6 +118,7 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_LOCKUP_DETECTOR=y
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_FTRACE is not set
+CONFIG_SECURITY=y
 CONFIG_CRYPTO_ANSI_CPRNG=y
 CONFIG_ARM64_CRYPTO=y
 CONFIG_CRYPTO_SHA1_ARM64_CE=y
index b9e6eaf..dc45701 100644 (file)
@@ -3,14 +3,6 @@
  *
  * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  *
- * Based on arch/x86/crypto/ghash-pmullni-intel_asm.S
- *
- * Copyright (c) 2009 Intel Corp.
- *   Author: Huang Ying <ying.huang@intel.com>
- *           Vinodh Gopal
- *           Erdinc Ozturk
- *           Deniz Karakoyunlu
- *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
  * by the Free Software Foundation.
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
-       DATA    .req    v0
-       SHASH   .req    v1
-       IN1     .req    v2
+       SHASH   .req    v0
+       SHASH2  .req    v1
        T1      .req    v2
        T2      .req    v3
-       T3      .req    v4
-       VZR     .req    v5
+       MASK    .req    v4
+       XL      .req    v5
+       XM      .req    v6
+       XH      .req    v7
+       IN1     .req    v7
 
        .text
        .arch           armv8-a+crypto
         *                         struct ghash_key const *k, const char *head)
         */
 ENTRY(pmull_ghash_update)
-       ld1             {DATA.16b}, [x1]
        ld1             {SHASH.16b}, [x3]
-       eor             VZR.16b, VZR.16b, VZR.16b
+       ld1             {XL.16b}, [x1]
+       movi            MASK.16b, #0xe1
+       ext             SHASH2.16b, SHASH.16b, SHASH.16b, #8
+       shl             MASK.2d, MASK.2d, #57
+       eor             SHASH2.16b, SHASH2.16b, SHASH.16b
 
        /* do the head block first, if supplied */
        cbz             x4, 0f
-       ld1             {IN1.2d}, [x4]
+       ld1             {T1.2d}, [x4]
        b               1f
 
-0:     ld1             {IN1.2d}, [x2], #16
+0:     ld1             {T1.2d}, [x2], #16
        sub             w0, w0, #1
-1:     ext             IN1.16b, IN1.16b, IN1.16b, #8
-CPU_LE(        rev64           IN1.16b, IN1.16b        )
-       eor             DATA.16b, DATA.16b, IN1.16b
 
-       /* multiply DATA by SHASH in GF(2^128) */
-       ext             T2.16b, DATA.16b, DATA.16b, #8
-       ext             T3.16b, SHASH.16b, SHASH.16b, #8
-       eor             T2.16b, T2.16b, DATA.16b
-       eor             T3.16b, T3.16b, SHASH.16b
+1:     /* multiply XL by SHASH in GF(2^128) */
+CPU_LE(        rev64           T1.16b, T1.16b  )
 
-       pmull2          T1.1q, SHASH.2d, DATA.2d        // a1 * b1
-       pmull           DATA.1q, SHASH.1d, DATA.1d      // a0 * b0
-       pmull           T2.1q, T2.1d, T3.1d             // (a1 + a0)(b1 + b0)
-       eor             T2.16b, T2.16b, T1.16b          // (a0 * b1) + (a1 * b0)
-       eor             T2.16b, T2.16b, DATA.16b
+       ext             T2.16b, XL.16b, XL.16b, #8
+       ext             IN1.16b, T1.16b, T1.16b, #8
+       eor             T1.16b, T1.16b, T2.16b
+       eor             XL.16b, XL.16b, IN1.16b
 
-       ext             T3.16b, VZR.16b, T2.16b, #8
-       ext             T2.16b, T2.16b, VZR.16b, #8
-       eor             DATA.16b, DATA.16b, T3.16b
-       eor             T1.16b, T1.16b, T2.16b  // <T1:DATA> is result of
-                                               // carry-less multiplication
+       pmull2          XH.1q, SHASH.2d, XL.2d          // a1 * b1
+       eor             T1.16b, T1.16b, XL.16b
+       pmull           XL.1q, SHASH.1d, XL.1d          // a0 * b0
+       pmull           XM.1q, SHASH2.1d, T1.1d         // (a1 + a0)(b1 + b0)
 
-       /* first phase of the reduction */
-       shl             T3.2d, DATA.2d, #1
-       eor             T3.16b, T3.16b, DATA.16b
-       shl             T3.2d, T3.2d, #5
-       eor             T3.16b, T3.16b, DATA.16b
-       shl             T3.2d, T3.2d, #57
-       ext             T2.16b, VZR.16b, T3.16b, #8
-       ext             T3.16b, T3.16b, VZR.16b, #8
-       eor             DATA.16b, DATA.16b, T2.16b
-       eor             T1.16b, T1.16b, T3.16b
+       ext             T1.16b, XL.16b, XH.16b, #8
+       eor             T2.16b, XL.16b, XH.16b
+       eor             XM.16b, XM.16b, T1.16b
+       eor             XM.16b, XM.16b, T2.16b
+       pmull           T2.1q, XL.1d, MASK.1d
 
-       /* second phase of the reduction */
-       ushr            T2.2d, DATA.2d, #5
-       eor             T2.16b, T2.16b, DATA.16b
-       ushr            T2.2d, T2.2d, #1
-       eor             T2.16b, T2.16b, DATA.16b
-       ushr            T2.2d, T2.2d, #1
-       eor             T1.16b, T1.16b, T2.16b
-       eor             DATA.16b, DATA.16b, T1.16b
+       mov             XH.d[0], XM.d[1]
+       mov             XM.d[1], XL.d[0]
+
+       eor             XL.16b, XM.16b, T2.16b
+       ext             T2.16b, XL.16b, XL.16b, #8
+       pmull           XL.1q, XL.1d, MASK.1d
+       eor             T2.16b, T2.16b, XH.16b
+       eor             XL.16b, XL.16b, T2.16b
 
        cbnz            w0, 0b
 
-       st1             {DATA.16b}, [x1]
+       st1             {XL.16b}, [x1]
        ret
 ENDPROC(pmull_ghash_update)
index b92baf3..833ec1e 100644 (file)
@@ -67,11 +67,12 @@ static int ghash_update(struct shash_desc *desc, const u8 *src,
                blocks = len / GHASH_BLOCK_SIZE;
                len %= GHASH_BLOCK_SIZE;
 
-               kernel_neon_begin_partial(6);
+               kernel_neon_begin_partial(8);
                pmull_ghash_update(blocks, ctx->digest, src, key,
                                   partial ? ctx->buf : NULL);
                kernel_neon_end();
                src += blocks * GHASH_BLOCK_SIZE;
+               partial = 0;
        }
        if (len)
                memcpy(ctx->buf + partial, src, len);
@@ -88,7 +89,7 @@ static int ghash_final(struct shash_desc *desc, u8 *dst)
 
                memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial);
 
-               kernel_neon_begin_partial(6);
+               kernel_neon_begin_partial(8);
                pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL);
                kernel_neon_end();
        }
index 42c7eec..0b3fcf8 100644 (file)
@@ -30,7 +30,6 @@ generic-y += msgbuf.h
 generic-y += mutex.h
 generic-y += pci.h
 generic-y += poll.h
-generic-y += posix_types.h
 generic-y += preempt.h
 generic-y += resource.h
 generic-y += rwsem.h
index 3a4572e..dc82e52 100644 (file)
@@ -26,8 +26,6 @@
 #include <xen/xen.h>
 #include <asm/xen/hypervisor.h>
 
-#define ARCH_HAS_DMA_GET_REQUIRED_MASK
-
 #define DMA_ERROR_CODE (~(dma_addr_t)0)
 extern struct dma_map_ops *dma_ops;
 extern struct dma_map_ops coherent_swiotlb_dma_ops;
index 598cc38..5797020 100644 (file)
@@ -246,7 +246,7 @@ static inline pmd_t pte_pmd(pte_t pte)
 #define pmd_mkwrite(pmd)       pte_pmd(pte_mkwrite(pmd_pte(pmd)))
 #define pmd_mkdirty(pmd)       pte_pmd(pte_mkdirty(pmd_pte(pmd)))
 #define pmd_mkyoung(pmd)       pte_pmd(pte_mkyoung(pmd_pte(pmd)))
-#define pmd_mknotpresent(pmd)  (__pmd(pmd_val(pmd) &= ~PMD_TYPE_MASK))
+#define pmd_mknotpresent(pmd)  (__pmd(pmd_val(pmd) & ~PMD_TYPE_MASK))
 
 #define __HAVE_ARCH_PMD_WRITE
 #define pmd_write(pmd)         pte_write(pmd_pte(pmd))
diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
new file mode 100644 (file)
index 0000000..7985ff6
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __ASM_POSIX_TYPES_H
+#define __ASM_POSIX_TYPES_H
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+#define __kernel_old_uid_t __kernel_old_uid_t
+
+#include <asm-generic/posix_types.h>
+
+#endif /*  __ASM_POSIX_TYPES_H */
index b72cf40..ee469be 100644 (file)
@@ -58,7 +58,7 @@ struct fpsimd_context {
 
 struct esr_context {
        struct _aarch64_ctx head;
-       u64 esr;
+       __u64 esr;
 };
 
 #endif /* _UAPI__ASM_SIGCONTEXT_H */
index b051871..aa5f9fc 100644 (file)
@@ -205,7 +205,7 @@ ENDPROC(ftrace_graph_caller)
  *
  * Run ftrace_return_to_handler() before going back to parent.
  * @fp is checked against the value passed by ftrace_graph_caller()
- * only when CONFIG_FUNCTION_GRAPH_FP_TEST is enabled.
+ * only when CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST is enabled.
  */
 ENTRY(return_to_handler)
        str     x0, [sp, #-16]!
index bf017f4..9ce04ba 100644 (file)
@@ -279,7 +279,6 @@ el1_sp_pc:
         */
        mrs     x0, far_el1
        enable_dbg
-       mov     x1, x25
        mov     x2, sp
        b       do_sp_pc_abort
 el1_undef:
index 3e926b9..9fde010 100644 (file)
@@ -655,11 +655,16 @@ static int compat_gpr_get(struct task_struct *target,
                        reg = task_pt_regs(target)->regs[idx];
                }
 
-               ret = copy_to_user(ubuf, &reg, sizeof(reg));
-               if (ret)
-                       break;
-
-               ubuf += sizeof(reg);
+               if (kbuf) {
+                       memcpy(kbuf, &reg, sizeof(reg));
+                       kbuf += sizeof(reg);
+               } else {
+                       ret = copy_to_user(ubuf, &reg, sizeof(reg));
+                       if (ret)
+                               break;
+
+                       ubuf += sizeof(reg);
+               }
        }
 
        return ret;
@@ -689,11 +694,16 @@ static int compat_gpr_set(struct task_struct *target,
                unsigned int idx = start + i;
                compat_ulong_t reg;
 
-               ret = copy_from_user(&reg, ubuf, sizeof(reg));
-               if (ret)
-                       return ret;
+               if (kbuf) {
+                       memcpy(&reg, kbuf, sizeof(reg));
+                       kbuf += sizeof(reg);
+               } else {
+                       ret = copy_from_user(&reg, ubuf, sizeof(reg));
+                       if (ret)
+                               return ret;
 
-               ubuf += sizeof(reg);
+                       ubuf += sizeof(reg);
+               }
 
                switch (idx) {
                case 15:
@@ -827,6 +837,7 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
                                    compat_ulong_t val)
 {
        int ret;
+       mm_segment_t old_fs = get_fs();
 
        if (off & 3 || off >= COMPAT_USER_SZ)
                return -EIO;
@@ -834,10 +845,13 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
        if (off >= sizeof(compat_elf_gregset_t))
                return 0;
 
+       set_fs(KERNEL_DS);
        ret = copy_regset_from_user(tsk, &user_aarch32_view,
                                    REGSET_COMPAT_GPR, off,
                                    sizeof(compat_ulong_t),
                                    &val);
+       set_fs(old_fs);
+
        return ret;
 }
 
index 091d428..f43db8a 100644 (file)
@@ -71,7 +71,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
        /* 4GB maximum for 32-bit only capable devices */
        if (IS_ENABLED(CONFIG_ZONE_DMA)) {
                unsigned long max_dma_phys =
-                       (unsigned long)dma_to_phys(NULL, DMA_BIT_MASK(32) + 1);
+                       (unsigned long)(dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1);
                max_dma = max(min, min(max, max_dma_phys >> PAGE_SHIFT));
                zone_size[ZONE_DMA] = max_dma - min;
        }
@@ -126,6 +126,8 @@ static void arm64_memory_present(void)
 
 void __init arm64_memblock_init(void)
 {
+       phys_addr_t dma_phys_limit = 0;
+
        /* Register the kernel text, kernel data and initrd with memblock */
        memblock_reserve(__pa(_text), _end - _text);
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -141,7 +143,11 @@ void __init arm64_memblock_init(void)
        memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE);
 
        early_init_fdt_scan_reserved_mem();
-       dma_contiguous_reserve(0);
+
+       /* 4GB maximum for 32-bit only capable devices */
+       if (IS_ENABLED(CONFIG_ZONE_DMA))
+               dma_phys_limit = dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1;
+       dma_contiguous_reserve(dma_phys_limit);
 
        memblock_allow_resize();
        memblock_dump_all();
index 1ba09e4..91146b4 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/types.h>
 #include <linux/fb.h>
 #include <linux/leds.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/atmel_serial.h>
@@ -155,21 +157,28 @@ static struct platform_device rmt_ts_device = {
 
 #ifdef CONFIG_BOARD_MRMT_BL_PWM
 /* PWM LEDs: LCD Backlight, etc */
-static struct gpio_led rmt_pwm_led[] = {
-       /* here the "gpio" is actually a PWM channel */
-       { .name = "backlight",  .gpio = PWM_CH_BL, },
+static struct pwm_lookup pwm_lookup[] = {
+       PWM_LOOKUP("at91sam9rl-pwm", PWM_CH_BL, "leds_pwm", "ds1",
+                  5000, PWM_POLARITY_INVERSED),
 };
 
-static struct gpio_led_platform_data rmt_pwm_led_data = {
-       .num_leds       = ARRAY_SIZE(rmt_pwm_led),
-       .leds           = rmt_pwm_led,
+static struct led_pwm pwm_leds[] = {
+       {
+               .name = "backlight",
+               .max_brightness = 255,
+       },
+};
+
+static struct led_pwm_platform_data pwm_data = {
+       .num_leds       = ARRAY_SIZE(pwm_leds),
+       .leds           = pwm_leds,
 };
 
-static struct platform_device rmt_pwm_led_dev = {
-       .name           = "leds-atmel-pwm",
-       .id             = -1,
-       .dev            = {
-               .platform_data  = &rmt_pwm_led_data,
+static struct platform_device leds_pwm = {
+       .name   = "leds_pwm",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &pwm_data,
        },
 };
 #endif
@@ -325,7 +334,8 @@ static int __init mrmt1_init(void)
 #ifdef CONFIG_BOARD_MRMT_BL_PWM
        /* Use PWM for Backlight controls */
        at32_add_device_pwm(1 << PWM_CH_BL);
-       platform_device_register(&rmt_pwm_led_dev);
+       pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
+       platform_device_register(&leds_pwm);
 #else
        /* Backlight always on */
        udelay( 1 );
index 1f12149..234cb07 100644 (file)
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/atmel-mci.h>
-#include <linux/atmel-pwm-bl.h>
+#include <linux/pwm.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
@@ -33,6 +36,8 @@
 #include <mach/board.h>
 #include <mach/portmux.h>
 
+#define PWM_BL_CH 2
+
 /* Oscillator frequencies. These are board-specific */
 unsigned long at32_board_osc_rates[3] = {
        [0] = 32768,    /* 32.768 kHz on RTC osc */
@@ -227,29 +232,36 @@ void __init favr32_setup_leds(void)
        platform_device_register(&favr32_led_dev);
 }
 
-static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
-       .pwm_channel            = 2,
-       .pwm_frequency          = 200000,
-       .pwm_compare_max        = 345,
-       .pwm_duty_max           = 345,
-       .pwm_duty_min           = 90,
-       .pwm_active_low         = 1,
-       .gpio_on                = GPIO_PIN_PA(28),
-       .on_active_low          = 0,
+static struct pwm_lookup pwm_lookup[] = {
+       PWM_LOOKUP("at91sam9rl-pwm", PWM_BL_CH, "pwm-backlight.0", NULL,
+                  5000, PWM_POLARITY_INVERSED),
 };
 
-static struct platform_device atmel_pwm_bl_dev = {
-       .name           = "atmel-pwm-bl",
-       .id             = 0,
-       .dev            = {
-               .platform_data = &atmel_pwm_bl_pdata,
+static struct regulator_consumer_supply fixed_power_consumers[] = {
+       REGULATOR_SUPPLY("power", "pwm-backlight.0"),
+};
+
+static struct platform_pwm_backlight_data pwm_bl_data = {
+       .enable_gpio            = GPIO_PIN_PA(28),
+       .max_brightness         = 255,
+       .dft_brightness         = 255,
+       .lth_brightness         = 50,
+};
+
+static struct platform_device pwm_bl_device = {
+       .name = "pwm-backlight",
+       .dev = {
+               .platform_data = &pwm_bl_data,
        },
 };
 
 static void __init favr32_setup_atmel_pwm_bl(void)
 {
-       platform_device_register(&atmel_pwm_bl_dev);
-       at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
+       pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
+       regulator_register_always_on(0, "fixed", fixed_power_consumers,
+                                   ARRAY_SIZE(fixed_power_consumers), 3300000);
+       platform_device_register(&pwm_bl_device);
+       at32_select_gpio(pwm_bl_data.enable_gpio, 0);
 }
 
 void __init setup_board(void)
@@ -339,7 +351,7 @@ static int __init favr32_init(void)
 
        set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
 
-       at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
+       at32_add_device_pwm(1 << PWM_BL_CH);
        at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
        at32_add_device_mci(0, &mci0_data);
        at32_add_device_usba(0, NULL);
index ed137e3..83d896c 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/irq.h>
 #include <linux/fb.h>
 #include <linux/atmel-mci.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
 
 #include <asm/io.h>
 #include <asm/setup.h>
@@ -167,24 +169,29 @@ static struct i2c_board_info __initdata i2c_info[] = {
        },
 };
 
-#ifdef CONFIG_LEDS_ATMEL_PWM
-static struct gpio_led stk_pwm_led[] = {
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+static struct pwm_lookup pwm_lookup[] = {
+       PWM_LOOKUP("at91sam9rl-pwm", 0, "leds_pwm", "backlight",
+                  5000, PWM_POLARITY_NORMAL),
+};
+
+static struct led_pwm pwm_leds[] = {
        {
                .name   = "backlight",
-               .gpio   = 0,            /* PWM channel 0 (LCD backlight) */
+               .max_brightness = 255,
        },
 };
 
-static struct gpio_led_platform_data stk_pwm_led_data = {
-       .num_leds       = ARRAY_SIZE(stk_pwm_led),
-       .leds           = stk_pwm_led,
+static struct led_pwm_platform_data pwm_data = {
+       .num_leds       = ARRAY_SIZE(pwm_leds),
+       .leds           = pwm_leds,
 };
 
-static struct platform_device stk_pwm_led_dev = {
-       .name   = "leds-atmel-pwm",
-       .id     = -1,
-       .dev    = {
-               .platform_data  = &stk_pwm_led_data,
+static struct platform_device leds_pwm = {
+       .name   = "leds_pwm",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &pwm_data,
        },
 };
 #endif
@@ -278,9 +285,10 @@ static int __init merisc_init(void)
 
        at32_add_device_mci(0, &mci0_data);
 
-#ifdef CONFIG_LEDS_ATMEL_PWM
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+       pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
        at32_add_device_pwm((1 << 0) | (1 << 2));
-       platform_device_register(&stk_pwm_led_dev);
+       platform_device_register(&leds_pwm);
 #else
        at32_add_device_pwm((1 << 2));
 #endif
index 9a57da4..6838781 100644 (file)
@@ -56,7 +56,6 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_DATAFLASH=y
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_ATMEL_PWM=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MACB=y
@@ -104,8 +103,8 @@ CONFIG_MMC=y
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=y
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -114,6 +113,8 @@ CONFIG_RTC_DRV_S35390A=m
 CONFIG_RTC_DRV_AT32AP700X=m
 CONFIG_DMADEVICES=y
 CONFIG_UIO=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
index 2813dd2..b056820 100644 (file)
@@ -64,7 +64,6 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=m
 CONFIG_MISC_DEVICES=y
-CONFIG_ATMEL_PWM=m
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_SSC=m
 # CONFIG_SCSI_PROC_FS is not set
@@ -133,14 +132,16 @@ CONFIG_MMC_TEST=m
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=m
 CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_PWM=m
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT32AP700X=y
 CONFIG_DMADEVICES=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
index f8ff3a3..0cd23a3 100644 (file)
@@ -53,7 +53,6 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=m
 CONFIG_MISC_DEVICES=y
-CONFIG_ATMEL_PWM=m
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_SSC=m
 # CONFIG_SCSI_PROC_FS is not set
@@ -112,14 +111,16 @@ CONFIG_MMC_TEST=m
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=m
 CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_PWM=m
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT32AP700X=y
 CONFIG_DMADEVICES=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
index 992228e..ac1041f 100644 (file)
@@ -53,7 +53,6 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=m
 CONFIG_MISC_DEVICES=y
-CONFIG_ATMEL_PWM=m
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_SSC=m
 # CONFIG_SCSI_PROC_FS is not set
@@ -111,14 +110,16 @@ CONFIG_MMC_TEST=m
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=m
 CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_PWM=m
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT32AP700X=y
 CONFIG_DMADEVICES=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
index b8e698b..ea4f670 100644 (file)
@@ -67,7 +67,6 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=m
 CONFIG_MISC_DEVICES=y
-CONFIG_ATMEL_PWM=m
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_SSC=m
 # CONFIG_SCSI_PROC_FS is not set
@@ -136,14 +135,16 @@ CONFIG_MMC_TEST=m
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=m
 CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_PWM=m
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT32AP700X=y
 CONFIG_DMADEVICES=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
index 07bed3f..b3eb67d 100644 (file)
@@ -67,7 +67,6 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=m
-CONFIG_ATMEL_PWM=m
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_SSC=m
 CONFIG_NETDEVICES=y
@@ -108,7 +107,7 @@ CONFIG_FB=y
 CONFIG_FB_ATMEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_ATMEL_PWM=m
+CONFIG_BACKLIGHT_PWM=m
 CONFIG_SOUND=m
 CONFIG_SOUND_PRIME=m
 # CONFIG_HID_SUPPORT is not set
@@ -123,7 +122,6 @@ CONFIG_MMC=y
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=m
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
@@ -132,6 +130,8 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT32AP700X=y
 CONFIG_DMADEVICES=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
index 91df6b2..b9ef4cc 100644 (file)
@@ -55,7 +55,6 @@ CONFIG_MTD_ABSENT=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_BLOCK2MTD=y
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_ATMEL_PWM=y
 CONFIG_ATMEL_SSC=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
@@ -103,12 +102,14 @@ CONFIG_MMC=y
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=y
+CONFIG_LEDS_PWM=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_HCTOSYS is not set
 CONFIG_RTC_DRV_PCF8563=y
 CONFIG_DMADEVICES=y
 CONFIG_UIO=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=m
 CONFIG_EXT2_FS=y
 # CONFIG_DNOTIFY is not set
 CONFIG_FUSE_FS=y
index a1f4d1e..db85b5e 100644 (file)
@@ -1553,7 +1553,7 @@ static struct resource atmel_pwm0_resource[] __initdata = {
        IRQ(24),
 };
 static struct clk atmel_pwm0_mck = {
-       .name           = "pwm_clk",
+       .name           = "at91sam9rl-pwm",
        .parent         = &pbb_clk,
        .mode           = pbb_clk_mode,
        .get_rate       = pbb_clk_get_rate,
@@ -1568,7 +1568,7 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
        if (!mask)
                return NULL;
 
-       pdev = platform_device_alloc("atmel_pwm", 0);
+       pdev = platform_device_alloc("at91sam9rl-pwm", 0);
        if (!pdev)
                return NULL;
 
@@ -1576,9 +1576,6 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
                                ARRAY_SIZE(atmel_pwm0_resource)))
                goto out_free_pdev;
 
-       if (platform_device_add_data(pdev, &mask, sizeof(mask)))
-               goto out_free_pdev;
-
        pin_mask = 0;
        if (mask & (1 << 0))
                pin_mask |= (1 << 28);
index 1a871b7..344387a 100644 (file)
@@ -242,7 +242,7 @@ struct ioc {
        struct pci_dev  *sac_only_dev;
 };
 
-static struct ioc *ioc_list;
+static struct ioc *ioc_list, *ioc_found;
 static int reserve_sba_gart = 1;
 
 static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
@@ -1809,20 +1809,13 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = {
        { SX2000_IOC_ID, "sx2000", NULL },
 };
 
-static struct ioc *
-ioc_init(unsigned long hpa, void *handle)
+static void ioc_init(unsigned long hpa, struct ioc *ioc)
 {
-       struct ioc *ioc;
        struct ioc_iommu *info;
 
-       ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
-       if (!ioc)
-               return NULL;
-
        ioc->next = ioc_list;
        ioc_list = ioc;
 
-       ioc->handle = handle;
        ioc->ioc_hpa = ioremap(hpa, 0x1000);
 
        ioc->func_id = READ_REG(ioc->ioc_hpa + IOC_FUNC_ID);
@@ -1863,8 +1856,6 @@ ioc_init(unsigned long hpa, void *handle)
                "%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
                ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
                hpa, ioc->iov_size >> 20, ioc->ibase);
-
-       return ioc;
 }
 
 
@@ -2031,22 +2022,21 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
 #endif
 }
 
-static int
-acpi_sba_ioc_add(struct acpi_device *device,
-                const struct acpi_device_id *not_used)
+static void acpi_sba_ioc_add(struct ioc *ioc)
 {
-       struct ioc *ioc;
+       acpi_handle handle = ioc->handle;
        acpi_status status;
        u64 hpa, length;
        struct acpi_device_info *adi;
 
-       status = hp_acpi_csr_space(device->handle, &hpa, &length);
+       ioc_found = ioc->next;
+       status = hp_acpi_csr_space(handle, &hpa, &length);
        if (ACPI_FAILURE(status))
-               return 1;
+               goto err;
 
-       status = acpi_get_object_info(device->handle, &adi);
+       status = acpi_get_object_info(handle, &adi);
        if (ACPI_FAILURE(status))
-               return 1;
+               goto err;
 
        /*
         * For HWP0001, only SBA appears in ACPI namespace.  It encloses the PCI
@@ -2067,13 +2057,13 @@ acpi_sba_ioc_add(struct acpi_device *device,
        if (!iovp_shift)
                iovp_shift = 12;
 
-       ioc = ioc_init(hpa, device->handle);
-       if (!ioc)
-               return 1;
-
+       ioc_init(hpa, ioc);
        /* setup NUMA node association */
-       sba_map_ioc_to_node(ioc, device->handle);
-       return 0;
+       sba_map_ioc_to_node(ioc, handle);
+       return;
+
+ err:
+       kfree(ioc);
 }
 
 static const struct acpi_device_id hp_ioc_iommu_device_ids[] = {
@@ -2081,9 +2071,26 @@ static const struct acpi_device_id hp_ioc_iommu_device_ids[] = {
        {"HWP0004", 0},
        {"", 0},
 };
+
+static int acpi_sba_ioc_attach(struct acpi_device *device,
+                              const struct acpi_device_id *not_used)
+{
+       struct ioc *ioc;
+
+       ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
+       if (!ioc)
+               return -ENOMEM;
+
+       ioc->next = ioc_found;
+       ioc_found = ioc;
+       ioc->handle = device->handle;
+       return 1;
+}
+
+
 static struct acpi_scan_handler acpi_sba_ioc_handler = {
        .ids    = hp_ioc_iommu_device_ids,
-       .attach = acpi_sba_ioc_add,
+       .attach = acpi_sba_ioc_attach,
 };
 
 static int __init acpi_sba_ioc_init_acpi(void)
@@ -2118,9 +2125,12 @@ sba_init(void)
 #endif
 
        /*
-        * ioc_list should be populated by the acpi_sba_ioc_handler's .attach()
+        * ioc_found should be populated by the acpi_sba_ioc_handler's .attach()
         * routine, but that only happens if acpi_scan_init() has already run.
         */
+       while (ioc_found)
+               acpi_sba_ioc_add(ioc_found);
+
        if (!ioc_list) {
 #ifdef CONFIG_IA64_GENERIC
                /*
index 1dd275d..7b48587 100644 (file)
@@ -8,6 +8,7 @@
 #define force_o_largefile()    \
                (personality(current->personality) != PER_LINUX32)
 
+#include <linux/personality.h>
 #include <asm-generic/fcntl.h>
 
 #endif /* _ASM_IA64_FCNTL_H */
index 7a469ac..4e238e6 100644 (file)
@@ -269,6 +269,7 @@ config LANTIQ
 config LASAT
        bool "LASAT Networks platforms"
        select CEVT_R4K
+       select CRC32
        select CSRC_R4K
        select DMA_NONCOHERENT
        select SYS_HAS_EARLY_PRINTK
index f54bdbe..eeeb0f4 100644 (file)
@@ -32,8 +32,6 @@ struct sigcontext32 {
        __u32           sc_lo2;
        __u32           sc_hi3;
        __u32           sc_lo3;
-       __u64           sc_msaregs[32]; /* Most significant 64 bits */
-       __u32           sc_msa_csr;
 };
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
 #endif /* _ASM_SIGCONTEXT_H */
index f8d63b3..708c5d4 100644 (file)
@@ -67,6 +67,9 @@ void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
 #define Ip_u2s3u1(op)                                                  \
 void ISAOPC(op)(u32 **buf, unsigned int a, signed int b, unsigned int c)
 
+#define Ip_s3s1s2(op)                                                  \
+void ISAOPC(op)(u32 **buf, int a, int b, int c)
+
 #define Ip_u2u1s3(op)                                                  \
 void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
 
@@ -147,6 +150,7 @@ Ip_u2s3u1(_scd);
 Ip_u2s3u1(_sd);
 Ip_u2u1u3(_sll);
 Ip_u3u2u1(_sllv);
+Ip_s3s1s2(_slt);
 Ip_u2u1s3(_sltiu);
 Ip_u3u1u2(_sltu);
 Ip_u2u1u3(_sra);
index 4b71602..4bfdb9d 100644 (file)
@@ -273,6 +273,7 @@ enum mm_32a_minor_op {
        mm_and_op = 0x250,
        mm_or32_op = 0x290,
        mm_xor32_op = 0x310,
+       mm_slt_op = 0x350,
        mm_sltu_op = 0x390,
 };
 
index 681c176..6c9906f 100644 (file)
 #include <linux/types.h>
 #include <asm/sgidefs.h>
 
-/* Bits which may be set in sc_used_math */
-#define USEDMATH_FP    (1 << 0)
-#define USEDMATH_MSA   (1 << 1)
-
 #if _MIPS_SIM == _MIPS_SIM_ABI32
 
 /*
@@ -41,8 +37,6 @@ struct sigcontext {
        unsigned long           sc_lo2;
        unsigned long           sc_hi3;
        unsigned long           sc_lo3;
-       unsigned long long      sc_msaregs[32]; /* Most significant 64 bits */
-       unsigned long           sc_msa_csr;
 };
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
@@ -76,8 +70,6 @@ struct sigcontext {
        __u32   sc_used_math;
        __u32   sc_dsp;
        __u32   sc_reserved;
-       __u64   sc_msaregs[32];
-       __u32   sc_msa_csr;
 };
 
 
index 02f075d..4bb5107 100644 (file)
@@ -293,7 +293,6 @@ void output_sc_defines(void)
        OFFSET(SC_LO2, sigcontext, sc_lo2);
        OFFSET(SC_HI3, sigcontext, sc_hi3);
        OFFSET(SC_LO3, sigcontext, sc_lo3);
-       OFFSET(SC_MSAREGS, sigcontext, sc_msaregs);
        BLANK();
 }
 #endif
@@ -308,7 +307,6 @@ void output_sc_defines(void)
        OFFSET(SC_MDLO, sigcontext, sc_mdlo);
        OFFSET(SC_PC, sigcontext, sc_pc);
        OFFSET(SC_FPC_CSR, sigcontext, sc_fpc_csr);
-       OFFSET(SC_MSAREGS, sigcontext, sc_msaregs);
        BLANK();
 }
 #endif
@@ -320,7 +318,6 @@ void output_sc32_defines(void)
        OFFSET(SC32_FPREGS, sigcontext32, sc_fpregs);
        OFFSET(SC32_FPC_CSR, sigcontext32, sc_fpc_csr);
        OFFSET(SC32_FPC_EIR, sigcontext32, sc_fpc_eir);
-       OFFSET(SC32_MSAREGS, sigcontext32, sc_msaregs);
        BLANK();
 }
 #endif
index 4858642..a734b2c 100644 (file)
@@ -126,7 +126,7 @@ void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqma
 
        board_bind_eic_interrupt = &msc_bind_eic_interrupt;
 
-       for (; nirq >= 0; nirq--, imp++) {
+       for (; nirq > 0; nirq--, imp++) {
                int n = imp->im_irq;
 
                switch (imp->im_type) {
index 5aa4c6f..c4c2069 100644 (file)
@@ -101,7 +101,7 @@ static void coupled_barrier(atomic_t *a, unsigned online)
        if (!coupled_coherence)
                return;
 
-       smp_mb__before_atomic_inc();
+       smp_mb__before_atomic();
        atomic_inc(a);
 
        while (atomic_read(a) < online)
@@ -158,7 +158,7 @@ int cps_pm_enter_state(enum cps_pm_state state)
 
        /* Indicate that this CPU might not be coherent */
        cpumask_clear_cpu(cpu, &cpu_coherent_mask);
-       smp_mb__after_clear_bit();
+       smp_mb__after_atomic();
 
        /* Create a non-coherent mapping of the core ready_count */
        core_ready_count = per_cpu(ready_count, core);
index 7181427..8352523 100644 (file)
@@ -13,7 +13,6 @@
  * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
  */
 #include <asm/asm.h>
-#include <asm/asmmacro.h>
 #include <asm/errno.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
@@ -246,218 +245,6 @@ LEAF(_restore_fp_context32)
        END(_restore_fp_context32)
 #endif
 
-#ifdef CONFIG_CPU_HAS_MSA
-
-       .macro  save_sc_msareg  wr, off, sc, tmp
-#ifdef CONFIG_64BIT
-       copy_u_d \tmp, \wr, 1
-       EX sd   \tmp, (\off+(\wr*8))(\sc)
-#elif defined(CONFIG_CPU_LITTLE_ENDIAN)
-       copy_u_w \tmp, \wr, 2
-       EX sw   \tmp, (\off+(\wr*8)+0)(\sc)
-       copy_u_w \tmp, \wr, 3
-       EX sw   \tmp, (\off+(\wr*8)+4)(\sc)
-#else /* CONFIG_CPU_BIG_ENDIAN */
-       copy_u_w \tmp, \wr, 2
-       EX sw   \tmp, (\off+(\wr*8)+4)(\sc)
-       copy_u_w \tmp, \wr, 3
-       EX sw   \tmp, (\off+(\wr*8)+0)(\sc)
-#endif
-       .endm
-
-/*
- * int _save_msa_context(struct sigcontext *sc)
- *
- * Save the upper 64 bits of each vector register along with the MSA_CSR
- * register into sc. Returns zero on success, else non-zero.
- */
-LEAF(_save_msa_context)
-       save_sc_msareg  0, SC_MSAREGS, a0, t0
-       save_sc_msareg  1, SC_MSAREGS, a0, t0
-       save_sc_msareg  2, SC_MSAREGS, a0, t0
-       save_sc_msareg  3, SC_MSAREGS, a0, t0
-       save_sc_msareg  4, SC_MSAREGS, a0, t0
-       save_sc_msareg  5, SC_MSAREGS, a0, t0
-       save_sc_msareg  6, SC_MSAREGS, a0, t0
-       save_sc_msareg  7, SC_MSAREGS, a0, t0
-       save_sc_msareg  8, SC_MSAREGS, a0, t0
-       save_sc_msareg  9, SC_MSAREGS, a0, t0
-       save_sc_msareg  10, SC_MSAREGS, a0, t0
-       save_sc_msareg  11, SC_MSAREGS, a0, t0
-       save_sc_msareg  12, SC_MSAREGS, a0, t0
-       save_sc_msareg  13, SC_MSAREGS, a0, t0
-       save_sc_msareg  14, SC_MSAREGS, a0, t0
-       save_sc_msareg  15, SC_MSAREGS, a0, t0
-       save_sc_msareg  16, SC_MSAREGS, a0, t0
-       save_sc_msareg  17, SC_MSAREGS, a0, t0
-       save_sc_msareg  18, SC_MSAREGS, a0, t0
-       save_sc_msareg  19, SC_MSAREGS, a0, t0
-       save_sc_msareg  20, SC_MSAREGS, a0, t0
-       save_sc_msareg  21, SC_MSAREGS, a0, t0
-       save_sc_msareg  22, SC_MSAREGS, a0, t0
-       save_sc_msareg  23, SC_MSAREGS, a0, t0
-       save_sc_msareg  24, SC_MSAREGS, a0, t0
-       save_sc_msareg  25, SC_MSAREGS, a0, t0
-       save_sc_msareg  26, SC_MSAREGS, a0, t0
-       save_sc_msareg  27, SC_MSAREGS, a0, t0
-       save_sc_msareg  28, SC_MSAREGS, a0, t0
-       save_sc_msareg  29, SC_MSAREGS, a0, t0
-       save_sc_msareg  30, SC_MSAREGS, a0, t0
-       save_sc_msareg  31, SC_MSAREGS, a0, t0
-       jr      ra
-        li     v0, 0
-       END(_save_msa_context)
-
-#ifdef CONFIG_MIPS32_COMPAT
-
-/*
- * int _save_msa_context32(struct sigcontext32 *sc)
- *
- * Save the upper 64 bits of each vector register along with the MSA_CSR
- * register into sc. Returns zero on success, else non-zero.
- */
-LEAF(_save_msa_context32)
-       save_sc_msareg  0, SC32_MSAREGS, a0, t0
-       save_sc_msareg  1, SC32_MSAREGS, a0, t0
-       save_sc_msareg  2, SC32_MSAREGS, a0, t0
-       save_sc_msareg  3, SC32_MSAREGS, a0, t0
-       save_sc_msareg  4, SC32_MSAREGS, a0, t0
-       save_sc_msareg  5, SC32_MSAREGS, a0, t0
-       save_sc_msareg  6, SC32_MSAREGS, a0, t0
-       save_sc_msareg  7, SC32_MSAREGS, a0, t0
-       save_sc_msareg  8, SC32_MSAREGS, a0, t0
-       save_sc_msareg  9, SC32_MSAREGS, a0, t0
-       save_sc_msareg  10, SC32_MSAREGS, a0, t0
-       save_sc_msareg  11, SC32_MSAREGS, a0, t0
-       save_sc_msareg  12, SC32_MSAREGS, a0, t0
-       save_sc_msareg  13, SC32_MSAREGS, a0, t0
-       save_sc_msareg  14, SC32_MSAREGS, a0, t0
-       save_sc_msareg  15, SC32_MSAREGS, a0, t0
-       save_sc_msareg  16, SC32_MSAREGS, a0, t0
-       save_sc_msareg  17, SC32_MSAREGS, a0, t0
-       save_sc_msareg  18, SC32_MSAREGS, a0, t0
-       save_sc_msareg  19, SC32_MSAREGS, a0, t0
-       save_sc_msareg  20, SC32_MSAREGS, a0, t0
-       save_sc_msareg  21, SC32_MSAREGS, a0, t0
-       save_sc_msareg  22, SC32_MSAREGS, a0, t0
-       save_sc_msareg  23, SC32_MSAREGS, a0, t0
-       save_sc_msareg  24, SC32_MSAREGS, a0, t0
-       save_sc_msareg  25, SC32_MSAREGS, a0, t0
-       save_sc_msareg  26, SC32_MSAREGS, a0, t0
-       save_sc_msareg  27, SC32_MSAREGS, a0, t0
-       save_sc_msareg  28, SC32_MSAREGS, a0, t0
-       save_sc_msareg  29, SC32_MSAREGS, a0, t0
-       save_sc_msareg  30, SC32_MSAREGS, a0, t0
-       save_sc_msareg  31, SC32_MSAREGS, a0, t0
-       jr      ra
-        li     v0, 0
-       END(_save_msa_context32)
-
-#endif /* CONFIG_MIPS32_COMPAT */
-
-       .macro restore_sc_msareg        wr, off, sc, tmp
-#ifdef CONFIG_64BIT
-       EX ld   \tmp, (\off+(\wr*8))(\sc)
-       insert_d \wr, 1, \tmp
-#elif defined(CONFIG_CPU_LITTLE_ENDIAN)
-       EX lw   \tmp, (\off+(\wr*8)+0)(\sc)
-       insert_w \wr, 2, \tmp
-       EX lw   \tmp, (\off+(\wr*8)+4)(\sc)
-       insert_w \wr, 3, \tmp
-#else /* CONFIG_CPU_BIG_ENDIAN */
-       EX lw   \tmp, (\off+(\wr*8)+4)(\sc)
-       insert_w \wr, 2, \tmp
-       EX lw   \tmp, (\off+(\wr*8)+0)(\sc)
-       insert_w \wr, 3, \tmp
-#endif
-       .endm
-
-/*
- * int _restore_msa_context(struct sigcontext *sc)
- */
-LEAF(_restore_msa_context)
-       restore_sc_msareg       0, SC_MSAREGS, a0, t0
-       restore_sc_msareg       1, SC_MSAREGS, a0, t0
-       restore_sc_msareg       2, SC_MSAREGS, a0, t0
-       restore_sc_msareg       3, SC_MSAREGS, a0, t0
-       restore_sc_msareg       4, SC_MSAREGS, a0, t0
-       restore_sc_msareg       5, SC_MSAREGS, a0, t0
-       restore_sc_msareg       6, SC_MSAREGS, a0, t0
-       restore_sc_msareg       7, SC_MSAREGS, a0, t0
-       restore_sc_msareg       8, SC_MSAREGS, a0, t0
-       restore_sc_msareg       9, SC_MSAREGS, a0, t0
-       restore_sc_msareg       10, SC_MSAREGS, a0, t0
-       restore_sc_msareg       11, SC_MSAREGS, a0, t0
-       restore_sc_msareg       12, SC_MSAREGS, a0, t0
-       restore_sc_msareg       13, SC_MSAREGS, a0, t0
-       restore_sc_msareg       14, SC_MSAREGS, a0, t0
-       restore_sc_msareg       15, SC_MSAREGS, a0, t0
-       restore_sc_msareg       16, SC_MSAREGS, a0, t0
-       restore_sc_msareg       17, SC_MSAREGS, a0, t0
-       restore_sc_msareg       18, SC_MSAREGS, a0, t0
-       restore_sc_msareg       19, SC_MSAREGS, a0, t0
-       restore_sc_msareg       20, SC_MSAREGS, a0, t0
-       restore_sc_msareg       21, SC_MSAREGS, a0, t0
-       restore_sc_msareg       22, SC_MSAREGS, a0, t0
-       restore_sc_msareg       23, SC_MSAREGS, a0, t0
-       restore_sc_msareg       24, SC_MSAREGS, a0, t0
-       restore_sc_msareg       25, SC_MSAREGS, a0, t0
-       restore_sc_msareg       26, SC_MSAREGS, a0, t0
-       restore_sc_msareg       27, SC_MSAREGS, a0, t0
-       restore_sc_msareg       28, SC_MSAREGS, a0, t0
-       restore_sc_msareg       29, SC_MSAREGS, a0, t0
-       restore_sc_msareg       30, SC_MSAREGS, a0, t0
-       restore_sc_msareg       31, SC_MSAREGS, a0, t0
-       jr      ra
-        li     v0, 0
-       END(_restore_msa_context)
-
-#ifdef CONFIG_MIPS32_COMPAT
-
-/*
- * int _restore_msa_context32(struct sigcontext32 *sc)
- */
-LEAF(_restore_msa_context32)
-       restore_sc_msareg       0, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       1, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       2, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       3, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       4, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       5, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       6, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       7, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       8, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       9, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       10, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       11, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       12, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       13, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       14, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       15, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       16, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       17, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       18, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       19, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       20, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       21, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       22, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       23, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       24, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       25, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       26, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       27, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       28, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       29, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       30, SC32_MSAREGS, a0, t0
-       restore_sc_msareg       31, SC32_MSAREGS, a0, t0
-       jr      ra
-        li     v0, 0
-       END(_restore_msa_context32)
-
-#endif /* CONFIG_MIPS32_COMPAT */
-
-#endif /* CONFIG_CPU_HAS_MSA */
-
        .set    reorder
 
        .type   fault@function
index 33133d3..9e60d11 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/fpu.h>
-#include <asm/msa.h>
 #include <asm/sim.h>
 #include <asm/ucontext.h>
 #include <asm/cpu-features.h>
@@ -48,9 +47,6 @@ static int (*restore_fp_context)(struct sigcontext __user *sc);
 extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
 extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
 
-extern asmlinkage int _save_msa_context(struct sigcontext __user *sc);
-extern asmlinkage int _restore_msa_context(struct sigcontext __user *sc);
-
 struct sigframe {
        u32 sf_ass[4];          /* argument save space for o32 */
        u32 sf_pad[2];          /* Was: signal trampoline */
@@ -99,61 +95,21 @@ static int copy_fp_from_sigcontext(struct sigcontext __user *sc)
        return err;
 }
 
-/*
- * These functions will save only the upper 64 bits of the vector registers,
- * since the lower 64 bits have already been saved as the scalar FP context.
- */
-static int copy_msa_to_sigcontext(struct sigcontext __user *sc)
-{
-       int i;
-       int err = 0;
-
-       for (i = 0; i < NUM_FPU_REGS; i++) {
-               err |=
-                   __put_user(get_fpr64(&current->thread.fpu.fpr[i], 1),
-                              &sc->sc_msaregs[i]);
-       }
-       err |= __put_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
-
-       return err;
-}
-
-static int copy_msa_from_sigcontext(struct sigcontext __user *sc)
-{
-       int i;
-       int err = 0;
-       u64 val;
-
-       for (i = 0; i < NUM_FPU_REGS; i++) {
-               err |= __get_user(val, &sc->sc_msaregs[i]);
-               set_fpr64(&current->thread.fpu.fpr[i], 1, val);
-       }
-       err |= __get_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
-
-       return err;
-}
-
 /*
  * Helper routines
  */
-static int protected_save_fp_context(struct sigcontext __user *sc,
-                                    unsigned used_math)
+static int protected_save_fp_context(struct sigcontext __user *sc)
 {
        int err;
-       bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
 #ifndef CONFIG_EVA
        while (1) {
                lock_fpu_owner();
                if (is_fpu_owner()) {
                        err = save_fp_context(sc);
-                       if (save_msa && !err)
-                               err = _save_msa_context(sc);
                        unlock_fpu_owner();
                } else {
                        unlock_fpu_owner();
                        err = copy_fp_to_sigcontext(sc);
-                       if (save_msa && !err)
-                               err = copy_msa_to_sigcontext(sc);
                }
                if (likely(!err))
                        break;
@@ -169,38 +125,24 @@ static int protected_save_fp_context(struct sigcontext __user *sc,
         * EVA does not have FPU EVA instructions so saving fpu context directly
         * does not work.
         */
-       disable_msa();
        lose_fpu(1);
        err = save_fp_context(sc); /* this might fail */
-       if (save_msa && !err)
-               err = copy_msa_to_sigcontext(sc);
 #endif
        return err;
 }
 
-static int protected_restore_fp_context(struct sigcontext __user *sc,
-                                       unsigned used_math)
+static int protected_restore_fp_context(struct sigcontext __user *sc)
 {
        int err, tmp __maybe_unused;
-       bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
 #ifndef CONFIG_EVA
        while (1) {
                lock_fpu_owner();
                if (is_fpu_owner()) {
                        err = restore_fp_context(sc);
-                       if (restore_msa && !err) {
-                               enable_msa();
-                               err = _restore_msa_context(sc);
-                       } else {
-                               /* signal handler may have used MSA */
-                               disable_msa();
-                       }
                        unlock_fpu_owner();
                } else {
                        unlock_fpu_owner();
                        err = copy_fp_from_sigcontext(sc);
-                       if (!err && (used_math & USEDMATH_MSA))
-                               err = copy_msa_from_sigcontext(sc);
                }
                if (likely(!err))
                        break;
@@ -216,11 +158,8 @@ static int protected_restore_fp_context(struct sigcontext __user *sc,
         * EVA does not have FPU EVA instructions so restoring fpu context
         * directly does not work.
         */
-       enable_msa();
        lose_fpu(0);
        err = restore_fp_context(sc); /* this might fail */
-       if (restore_msa && !err)
-               err = copy_msa_from_sigcontext(sc);
 #endif
        return err;
 }
@@ -252,8 +191,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
                err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
        }
 
-       used_math = used_math() ? USEDMATH_FP : 0;
-       used_math |= thread_msa_context_live() ? USEDMATH_MSA : 0;
+       used_math = !!used_math();
        err |= __put_user(used_math, &sc->sc_used_math);
 
        if (used_math) {
@@ -261,7 +199,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
                 * Save FPU state to signal context. Signal handler
                 * will "inherit" current FPU state.
                 */
-               err |= protected_save_fp_context(sc, used_math);
+               err |= protected_save_fp_context(sc);
        }
        return err;
 }
@@ -286,14 +224,14 @@ int fpcsr_pending(unsigned int __user *fpcsr)
 }
 
 static int
-check_and_restore_fp_context(struct sigcontext __user *sc, unsigned used_math)
+check_and_restore_fp_context(struct sigcontext __user *sc)
 {
        int err, sig;
 
        err = sig = fpcsr_pending(&sc->sc_fpc_csr);
        if (err > 0)
                err = 0;
-       err |= protected_restore_fp_context(sc, used_math);
+       err |= protected_restore_fp_context(sc);
        return err ?: sig;
 }
 
@@ -333,10 +271,9 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
        if (used_math) {
                /* restore fpu context if we have used it before */
                if (!err)
-                       err = check_and_restore_fp_context(sc, used_math);
+                       err = check_and_restore_fp_context(sc);
        } else {
-               /* signal handler may have used FPU or MSA. Disable them. */
-               disable_msa();
+               /* signal handler may have used FPU.  Give it up. */
                lose_fpu(0);
        }
 
index 299f956..bae2e6e 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/sim.h>
 #include <asm/ucontext.h>
 #include <asm/fpu.h>
-#include <asm/msa.h>
 #include <asm/war.h>
 #include <asm/vdso.h>
 #include <asm/dsp.h>
@@ -43,9 +42,6 @@ static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
 extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
 
-extern asmlinkage int _save_msa_context32(struct sigcontext32 __user *sc);
-extern asmlinkage int _restore_msa_context32(struct sigcontext32 __user *sc);
-
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
@@ -114,60 +110,20 @@ static int copy_fp_from_sigcontext32(struct sigcontext32 __user *sc)
        return err;
 }
 
-/*
- * These functions will save only the upper 64 bits of the vector registers,
- * since the lower 64 bits have already been saved as the scalar FP context.
- */
-static int copy_msa_to_sigcontext32(struct sigcontext32 __user *sc)
-{
-       int i;
-       int err = 0;
-
-       for (i = 0; i < NUM_FPU_REGS; i++) {
-               err |=
-                   __put_user(get_fpr64(&current->thread.fpu.fpr[i], 1),
-                              &sc->sc_msaregs[i]);
-       }
-       err |= __put_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
-
-       return err;
-}
-
-static int copy_msa_from_sigcontext32(struct sigcontext32 __user *sc)
-{
-       int i;
-       int err = 0;
-       u64 val;
-
-       for (i = 0; i < NUM_FPU_REGS; i++) {
-               err |= __get_user(val, &sc->sc_msaregs[i]);
-               set_fpr64(&current->thread.fpu.fpr[i], 1, val);
-       }
-       err |= __get_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
-
-       return err;
-}
-
 /*
  * sigcontext handlers
  */
-static int protected_save_fp_context32(struct sigcontext32 __user *sc,
-                                      unsigned used_math)
+static int protected_save_fp_context32(struct sigcontext32 __user *sc)
 {
        int err;
-       bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
        while (1) {
                lock_fpu_owner();
                if (is_fpu_owner()) {
                        err = save_fp_context32(sc);
-                       if (save_msa && !err)
-                               err = _save_msa_context32(sc);
                        unlock_fpu_owner();
                } else {
                        unlock_fpu_owner();
                        err = copy_fp_to_sigcontext32(sc);
-                       if (save_msa && !err)
-                               err = copy_msa_to_sigcontext32(sc);
                }
                if (likely(!err))
                        break;
@@ -181,28 +137,17 @@ static int protected_save_fp_context32(struct sigcontext32 __user *sc,
        return err;
 }
 
-static int protected_restore_fp_context32(struct sigcontext32 __user *sc,
-                                         unsigned used_math)
+static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
 {
        int err, tmp __maybe_unused;
-       bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
        while (1) {
                lock_fpu_owner();
                if (is_fpu_owner()) {
                        err = restore_fp_context32(sc);
-                       if (restore_msa && !err) {
-                               enable_msa();
-                               err = _restore_msa_context32(sc);
-                       } else {
-                               /* signal handler may have used MSA */
-                               disable_msa();
-                       }
                        unlock_fpu_owner();
                } else {
                        unlock_fpu_owner();
                        err = copy_fp_from_sigcontext32(sc);
-                       if (restore_msa && !err)
-                               err = copy_msa_from_sigcontext32(sc);
                }
                if (likely(!err))
                        break;
@@ -241,8 +186,7 @@ static int setup_sigcontext32(struct pt_regs *regs,
                err |= __put_user(mflo3(), &sc->sc_lo3);
        }
 
-       used_math = used_math() ? USEDMATH_FP : 0;
-       used_math |= thread_msa_context_live() ? USEDMATH_MSA : 0;
+       used_math = !!used_math();
        err |= __put_user(used_math, &sc->sc_used_math);
 
        if (used_math) {
@@ -250,21 +194,20 @@ static int setup_sigcontext32(struct pt_regs *regs,
                 * Save FPU state to signal context.  Signal handler
                 * will "inherit" current FPU state.
                 */
-               err |= protected_save_fp_context32(sc, used_math);
+               err |= protected_save_fp_context32(sc);
        }
        return err;
 }
 
 static int
-check_and_restore_fp_context32(struct sigcontext32 __user *sc,
-                              unsigned used_math)
+check_and_restore_fp_context32(struct sigcontext32 __user *sc)
 {
        int err, sig;
 
        err = sig = fpcsr_pending(&sc->sc_fpc_csr);
        if (err > 0)
                err = 0;
-       err |= protected_restore_fp_context32(sc, used_math);
+       err |= protected_restore_fp_context32(sc);
        return err ?: sig;
 }
 
@@ -301,10 +244,9 @@ static int restore_sigcontext32(struct pt_regs *regs,
        if (used_math) {
                /* restore fpu context if we have used it before */
                if (!err)
-                       err = check_and_restore_fp_context32(sc, used_math);
+                       err = check_and_restore_fp_context32(sc);
        } else {
-               /* signal handler may have used FPU or MSA. Disable them. */
-               disable_msa();
+               /* signal handler may have used FPU.  Give it up. */
                lose_fpu(0);
        }
 
index df0598d..949f2c6 100644 (file)
@@ -301,7 +301,7 @@ static int cps_cpu_disable(void)
 
        core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core];
        atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask);
-       smp_mb__after_atomic_dec();
+       smp_mb__after_atomic();
        set_cpu_online(cpu, false);
        cpu_clear(cpu, cpu_callin_map);
 
index 53f1d22..8e97acb 100644 (file)
  * Special constants
  */
 
-#define DPCNST(s, b, m)                                                        \
+/*
+ * Older GCC requires the inner braces for initialization of union ieee754dp's
+ * anonymous struct member.  Without an error will result.
+ */
+#define xPCNST(s, b, m, ebias)                                         \
 {                                                                      \
-       .sign   = (s),                                                  \
-       .bexp   = (b) + DP_EBIAS,                                       \
-       .mant   = (m)                                                   \
+       {                                                               \
+               .sign   = (s),                                          \
+               .bexp   = (b) + ebias,                                  \
+               .mant   = (m)                                           \
+       }                                                               \
 }
 
+#define DPCNST(s, b, m)                                                        \
+       xPCNST(s, b, m, DP_EBIAS)
+
 const union ieee754dp __ieee754dp_spcvals[] = {
        DPCNST(0, DP_EMIN - 1, 0x0000000000000ULL),     /* + zero   */
        DPCNST(1, DP_EMIN - 1, 0x0000000000000ULL),     /* - zero   */
@@ -62,11 +71,7 @@ const union ieee754dp __ieee754dp_spcvals[] = {
 };
 
 #define SPCNST(s, b, m)                                                        \
-{                                                                      \
-       .sign   = (s),                                                  \
-       .bexp   = (b) + SP_EBIAS,                                       \
-       .mant   = (m)                                                   \
-}
+       xPCNST(s, b, m, SP_EBIAS)
 
 const union ieee754sp __ieee754sp_spcvals[] = {
        SPCNST(0, SP_EMIN - 1, 0x000000),       /* + zero   */
index 775c280..8399ddf 100644 (file)
@@ -102,6 +102,7 @@ static struct insn insn_table_MM[] = {
        { insn_sd, 0, 0 },
        { insn_sll, M(mm_pool32a_op, 0, 0, 0, 0, mm_sll32_op), RT | RS | RD },
        { insn_sllv, M(mm_pool32a_op, 0, 0, 0, 0, mm_sllv32_op), RT | RS | RD },
+       { insn_slt, M(mm_pool32a_op, 0, 0, 0, 0, mm_slt_op), RT | RS | RD },
        { insn_sltiu, M(mm_sltiu32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
        { insn_sltu, M(mm_pool32a_op, 0, 0, 0, 0, mm_sltu_op), RT | RS | RD },
        { insn_sra, M(mm_pool32a_op, 0, 0, 0, 0, mm_sra_op), RT | RS | RD },
index 38792c2..6708a2d 100644 (file)
@@ -89,7 +89,7 @@ static struct insn insn_table[] = {
        { insn_lb, M(lb_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
        { insn_ld,  M(ld_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
-       { insn_lh,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
+       { insn_lh,  M(lh_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_lld,  M(lld_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_ll,  M(ll_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_lui,  M(lui_op, 0, 0, 0, 0, 0),  RT | SIMM },
@@ -110,6 +110,7 @@ static struct insn insn_table[] = {
        { insn_sd,  M(sd_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_sll,  M(spec_op, 0, 0, 0, 0, sll_op),  RT | RD | RE },
        { insn_sllv,  M(spec_op, 0, 0, 0, 0, sllv_op),  RS | RT | RD },
+       { insn_slt,  M(spec_op, 0, 0, 0, 0, slt_op),  RS | RT | RD },
        { insn_sltiu, M(sltiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
        { insn_sltu, M(spec_op, 0, 0, 0, 0, sltu_op), RS | RT | RD },
        { insn_sra,  M(spec_op, 0, 0, 0, 0, sra_op),  RT | RD | RE },
index 0051580..a01b0d6 100644 (file)
@@ -53,7 +53,7 @@ enum opcode {
        insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw,
        insn_lwx, insn_mfc0, insn_mfhi, insn_mflo, insn_mtc0, insn_mul,
        insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd,
-       insn_sd, insn_sll, insn_sllv, insn_sltiu, insn_sltu, insn_sra,
+       insn_sd, insn_sll, insn_sllv, insn_slt, insn_sltiu, insn_sltu, insn_sra,
        insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall,
        insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh,
        insn_xor, insn_xori, insn_yield,
@@ -139,6 +139,13 @@ Ip_u1u2u3(op)                                              \
 }                                                      \
 UASM_EXPORT_SYMBOL(uasm_i##op);
 
+#define I_s3s1s2(op)                                   \
+Ip_s3s1s2(op)                                          \
+{                                                      \
+       build_insn(buf, insn##op, b, c, a);             \
+}                                                      \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
 #define I_u2u1u3(op)                                   \
 Ip_u2u1u3(op)                                          \
 {                                                      \
@@ -289,6 +296,7 @@ I_u2s3u1(_scd)
 I_u2s3u1(_sd)
 I_u2u1u3(_sll)
 I_u3u2u1(_sllv)
+I_s3s1s2(_slt)
 I_u2u1s3(_sltiu)
 I_u3u1u2(_sltu)
 I_u2u1u3(_sra)
index a67b975..b87390a 100644 (file)
 /* Arguments used by JIT */
 #define ARGS_USED_BY_JIT       2 /* only applicable to 64-bit */
 
-#define FLAG_NEED_X_RESET      (1 << 0)
-
 #define SBIT(x)                        (1 << (x)) /* Signed version of BIT() */
 
 /**
@@ -153,6 +151,8 @@ static inline int optimize_div(u32 *k)
        return 0;
 }
 
+static inline void emit_jit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx);
+
 /* Simply emit the instruction if the JIT memory space has been allocated */
 #define emit_instr(ctx, func, ...)                     \
 do {                                                   \
@@ -166,9 +166,7 @@ do {                                                        \
 /* Determine if immediate is within the 16-bit signed range */
 static inline bool is_range16(s32 imm)
 {
-       if (imm >= SBIT(15) || imm < -SBIT(15))
-               return true;
-       return false;
+       return !(imm >= SBIT(15) || imm < -SBIT(15));
 }
 
 static inline void emit_addu(unsigned int dst, unsigned int src1,
@@ -187,7 +185,7 @@ static inline void emit_load_imm(unsigned int dst, u32 imm, struct jit_ctx *ctx)
 {
        if (ctx->target != NULL) {
                /* addiu can only handle s16 */
-               if (is_range16(imm)) {
+               if (!is_range16(imm)) {
                        u32 *p = &ctx->target[ctx->idx];
                        uasm_i_lui(&p, r_tmp_imm, (s32)imm >> 16);
                        p = &ctx->target[ctx->idx + 1];
@@ -199,7 +197,7 @@ static inline void emit_load_imm(unsigned int dst, u32 imm, struct jit_ctx *ctx)
        }
        ctx->idx++;
 
-       if (is_range16(imm))
+       if (!is_range16(imm))
                ctx->idx++;
 }
 
@@ -240,7 +238,7 @@ static inline void emit_daddiu(unsigned int dst, unsigned int src,
 static inline void emit_addiu(unsigned int dst, unsigned int src,
                              u32 imm, struct jit_ctx *ctx)
 {
-       if (is_range16(imm)) {
+       if (!is_range16(imm)) {
                emit_load_imm(r_tmp, imm, ctx);
                emit_addu(dst, r_tmp, src, ctx);
        } else {
@@ -313,8 +311,11 @@ static inline void emit_sll(unsigned int dst, unsigned int src,
                            unsigned int sa, struct jit_ctx *ctx)
 {
        /* sa is 5-bits long */
-       BUG_ON(sa >= BIT(5));
-       emit_instr(ctx, sll, dst, src, sa);
+       if (sa >= BIT(5))
+               /* Shifting >= 32 results in zero */
+               emit_jit_reg_move(dst, r_zero, ctx);
+       else
+               emit_instr(ctx, sll, dst, src, sa);
 }
 
 static inline void emit_srlv(unsigned int dst, unsigned int src,
@@ -327,8 +328,17 @@ static inline void emit_srl(unsigned int dst, unsigned int src,
                            unsigned int sa, struct jit_ctx *ctx)
 {
        /* sa is 5-bits long */
-       BUG_ON(sa >= BIT(5));
-       emit_instr(ctx, srl, dst, src, sa);
+       if (sa >= BIT(5))
+               /* Shifting >= 32 results in zero */
+               emit_jit_reg_move(dst, r_zero, ctx);
+       else
+               emit_instr(ctx, srl, dst, src, sa);
+}
+
+static inline void emit_slt(unsigned int dst, unsigned int src1,
+                           unsigned int src2, struct jit_ctx *ctx)
+{
+       emit_instr(ctx, slt, dst, src1, src2);
 }
 
 static inline void emit_sltu(unsigned int dst, unsigned int src1,
@@ -341,7 +351,7 @@ static inline void emit_sltiu(unsigned dst, unsigned int src,
                              unsigned int imm, struct jit_ctx *ctx)
 {
        /* 16 bit immediate */
-       if (is_range16((s32)imm)) {
+       if (!is_range16((s32)imm)) {
                emit_load_imm(r_tmp, imm, ctx);
                emit_sltu(dst, src, r_tmp, ctx);
        } else {
@@ -408,7 +418,7 @@ static inline void emit_div(unsigned int dst, unsigned int src,
                u32 *p = &ctx->target[ctx->idx];
                uasm_i_divu(&p, dst, src);
                p = &ctx->target[ctx->idx + 1];
-               uasm_i_mfhi(&p, dst);
+               uasm_i_mflo(&p, dst);
        }
        ctx->idx += 2; /* 2 insts */
 }
@@ -443,6 +453,17 @@ static inline void emit_wsbh(unsigned int dst, unsigned int src,
        emit_instr(ctx, wsbh, dst, src);
 }
 
+/* load pointer to register */
+static inline void emit_load_ptr(unsigned int dst, unsigned int src,
+                                    int imm, struct jit_ctx *ctx)
+{
+       /* src contains the base addr of the 32/64-pointer */
+       if (config_enabled(CONFIG_64BIT))
+               emit_instr(ctx, ld, dst, imm, src);
+       else
+               emit_instr(ctx, lw, dst, imm, src);
+}
+
 /* load a function pointer to register */
 static inline void emit_load_func(unsigned int reg, ptr imm,
                                  struct jit_ctx *ctx)
@@ -545,29 +566,13 @@ static inline u16 align_sp(unsigned int num)
        return num;
 }
 
-static inline void update_on_xread(struct jit_ctx *ctx)
-{
-       if (!(ctx->flags & SEEN_X))
-               ctx->flags |= FLAG_NEED_X_RESET;
-
-       ctx->flags |= SEEN_X;
-}
-
 static bool is_load_to_a(u16 inst)
 {
        switch (inst) {
-       case BPF_S_LD_W_LEN:
-       case BPF_S_LD_W_ABS:
-       case BPF_S_LD_H_ABS:
-       case BPF_S_LD_B_ABS:
-       case BPF_S_ANC_CPU:
-       case BPF_S_ANC_IFINDEX:
-       case BPF_S_ANC_MARK:
-       case BPF_S_ANC_PROTOCOL:
-       case BPF_S_ANC_RXHASH:
-       case BPF_S_ANC_VLAN_TAG:
-       case BPF_S_ANC_VLAN_TAG_PRESENT:
-       case BPF_S_ANC_QUEUE:
+       case BPF_LD | BPF_W | BPF_LEN:
+       case BPF_LD | BPF_W | BPF_ABS:
+       case BPF_LD | BPF_H | BPF_ABS:
+       case BPF_LD | BPF_B | BPF_ABS:
                return true;
        default:
                return false;
@@ -618,7 +623,10 @@ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
        if (ctx->flags & SEEN_MEM) {
                if (real_off % (RSIZE * 2))
                        real_off += RSIZE;
-               emit_addiu(r_M, r_sp, real_off, ctx);
+               if (config_enabled(CONFIG_64BIT))
+                       emit_daddiu(r_M, r_sp, real_off, ctx);
+               else
+                       emit_addiu(r_M, r_sp, real_off, ctx);
        }
 }
 
@@ -705,11 +713,11 @@ static void build_prologue(struct jit_ctx *ctx)
        if (ctx->flags & SEEN_SKB)
                emit_reg_move(r_skb, MIPS_R_A0, ctx);
 
-       if (ctx->flags & FLAG_NEED_X_RESET)
+       if (ctx->flags & SEEN_X)
                emit_jit_reg_move(r_X, r_zero, ctx);
 
        /* Do not leak kernel data to userspace */
-       if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst)))
+       if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
                emit_jit_reg_move(r_A, r_zero, ctx);
 }
 
@@ -757,13 +765,17 @@ static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
        return (u64)err << 32 | ntohl(ret);
 }
 
-#define PKT_TYPE_MAX 7
+#ifdef __BIG_ENDIAN_BITFIELD
+#define PKT_TYPE_MAX   (7 << 5)
+#else
+#define PKT_TYPE_MAX   7
+#endif
 static int pkt_type_offset(void)
 {
        struct sk_buff skb_probe = {
                .pkt_type = ~0,
        };
-       char *ct = (char *)&skb_probe;
+       u8 *ct = (u8 *)&skb_probe;
        unsigned int off;
 
        for (off = 0; off < sizeof(struct sk_buff); off++) {
@@ -783,46 +795,62 @@ static int build_body(struct jit_ctx *ctx)
        u32 k, b_off __maybe_unused;
 
        for (i = 0; i < prog->len; i++) {
+               u16 code;
+
                inst = &(prog->insns[i]);
                pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n",
                         __func__, inst->code, inst->jt, inst->jf, inst->k);
                k = inst->k;
+               code = bpf_anc_helper(inst);
 
                if (ctx->target == NULL)
                        ctx->offsets[i] = ctx->idx * 4;
 
-               switch (inst->code) {
-               case BPF_S_LD_IMM:
+               switch (code) {
+               case BPF_LD | BPF_IMM:
                        /* A <- k ==> li r_A, k */
                        ctx->flags |= SEEN_A;
                        emit_load_imm(r_A, k, ctx);
                        break;
-               case BPF_S_LD_W_LEN:
+               case BPF_LD | BPF_W | BPF_LEN:
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
                        /* A <- len ==> lw r_A, offset(skb) */
                        ctx->flags |= SEEN_SKB | SEEN_A;
                        off = offsetof(struct sk_buff, len);
                        emit_load(r_A, r_skb, off, ctx);
                        break;
-               case BPF_S_LD_MEM:
+               case BPF_LD | BPF_MEM:
                        /* A <- M[k] ==> lw r_A, offset(M) */
                        ctx->flags |= SEEN_MEM | SEEN_A;
                        emit_load(r_A, r_M, SCRATCH_OFF(k), ctx);
                        break;
-               case BPF_S_LD_W_ABS:
+               case BPF_LD | BPF_W | BPF_ABS:
                        /* A <- P[k:4] */
                        load_order = 2;
                        goto load;
-               case BPF_S_LD_H_ABS:
+               case BPF_LD | BPF_H | BPF_ABS:
                        /* A <- P[k:2] */
                        load_order = 1;
                        goto load;
-               case BPF_S_LD_B_ABS:
+               case BPF_LD | BPF_B | BPF_ABS:
                        /* A <- P[k:1] */
                        load_order = 0;
 load:
+                       /* the interpreter will deal with the negative K */
+                       if ((int)k < 0)
+                               return -ENOTSUPP;
+
                        emit_load_imm(r_off, k, ctx);
 load_common:
+                       /*
+                        * We may got here from the indirect loads so
+                        * return if offset is negative.
+                        */
+                       emit_slt(r_s0, r_off, r_zero, ctx);
+                       emit_bcond(MIPS_COND_NE, r_s0, r_zero,
+                                  b_imm(prog->len, ctx), ctx);
+                       emit_reg_move(r_ret, r_zero, ctx);
+
                        ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 |
                                SEEN_SKB | SEEN_A;
 
@@ -852,39 +880,42 @@ load_common:
                        emit_b(b_imm(prog->len, ctx), ctx);
                        emit_reg_move(r_ret, r_zero, ctx);
                        break;
-               case BPF_S_LD_W_IND:
+               case BPF_LD | BPF_W | BPF_IND:
                        /* A <- P[X + k:4] */
                        load_order = 2;
                        goto load_ind;
-               case BPF_S_LD_H_IND:
+               case BPF_LD | BPF_H | BPF_IND:
                        /* A <- P[X + k:2] */
                        load_order = 1;
                        goto load_ind;
-               case BPF_S_LD_B_IND:
+               case BPF_LD | BPF_B | BPF_IND:
                        /* A <- P[X + k:1] */
                        load_order = 0;
 load_ind:
-                       update_on_xread(ctx);
                        ctx->flags |= SEEN_OFF | SEEN_X;
                        emit_addiu(r_off, r_X, k, ctx);
                        goto load_common;
-               case BPF_S_LDX_IMM:
+               case BPF_LDX | BPF_IMM:
                        /* X <- k */
                        ctx->flags |= SEEN_X;
                        emit_load_imm(r_X, k, ctx);
                        break;
-               case BPF_S_LDX_MEM:
+               case BPF_LDX | BPF_MEM:
                        /* X <- M[k] */
                        ctx->flags |= SEEN_X | SEEN_MEM;
                        emit_load(r_X, r_M, SCRATCH_OFF(k), ctx);
                        break;
-               case BPF_S_LDX_W_LEN:
+               case BPF_LDX | BPF_W | BPF_LEN:
                        /* X <- len */
                        ctx->flags |= SEEN_X | SEEN_SKB;
                        off = offsetof(struct sk_buff, len);
                        emit_load(r_X, r_skb, off, ctx);
                        break;
-               case BPF_S_LDX_B_MSH:
+               case BPF_LDX | BPF_B | BPF_MSH:
+                       /* the interpreter will deal with the negative K */
+                       if ((int)k < 0)
+                               return -ENOTSUPP;
+
                        /* X <- 4 * (P[k:1] & 0xf) */
                        ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
                        /* Load offset to a1 */
@@ -917,50 +948,49 @@ load_ind:
                        emit_b(b_imm(prog->len, ctx), ctx);
                        emit_load_imm(r_ret, 0, ctx); /* delay slot */
                        break;
-               case BPF_S_ST:
+               case BPF_ST:
                        /* M[k] <- A */
                        ctx->flags |= SEEN_MEM | SEEN_A;
                        emit_store(r_A, r_M, SCRATCH_OFF(k), ctx);
                        break;
-               case BPF_S_STX:
+               case BPF_STX:
                        /* M[k] <- X */
                        ctx->flags |= SEEN_MEM | SEEN_X;
                        emit_store(r_X, r_M, SCRATCH_OFF(k), ctx);
                        break;
-               case BPF_S_ALU_ADD_K:
+               case BPF_ALU | BPF_ADD | BPF_K:
                        /* A += K */
                        ctx->flags |= SEEN_A;
                        emit_addiu(r_A, r_A, k, ctx);
                        break;
-               case BPF_S_ALU_ADD_X:
+               case BPF_ALU | BPF_ADD | BPF_X:
                        /* A += X */
                        ctx->flags |= SEEN_A | SEEN_X;
                        emit_addu(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_SUB_K:
+               case BPF_ALU | BPF_SUB | BPF_K:
                        /* A -= K */
                        ctx->flags |= SEEN_A;
                        emit_addiu(r_A, r_A, -k, ctx);
                        break;
-               case BPF_S_ALU_SUB_X:
+               case BPF_ALU | BPF_SUB | BPF_X:
                        /* A -= X */
                        ctx->flags |= SEEN_A | SEEN_X;
                        emit_subu(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_MUL_K:
+               case BPF_ALU | BPF_MUL | BPF_K:
                        /* A *= K */
                        /* Load K to scratch register before MUL */
                        ctx->flags |= SEEN_A | SEEN_S0;
                        emit_load_imm(r_s0, k, ctx);
                        emit_mul(r_A, r_A, r_s0, ctx);
                        break;
-               case BPF_S_ALU_MUL_X:
+               case BPF_ALU | BPF_MUL | BPF_X:
                        /* A *= X */
-                       update_on_xread(ctx);
                        ctx->flags |= SEEN_A | SEEN_X;
                        emit_mul(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_DIV_K:
+               case BPF_ALU | BPF_DIV | BPF_K:
                        /* A /= k */
                        if (k == 1)
                                break;
@@ -973,7 +1003,7 @@ load_ind:
                        emit_load_imm(r_s0, k, ctx);
                        emit_div(r_A, r_s0, ctx);
                        break;
-               case BPF_S_ALU_MOD_K:
+               case BPF_ALU | BPF_MOD | BPF_K:
                        /* A %= k */
                        if (k == 1 || optimize_div(&k)) {
                                ctx->flags |= SEEN_A;
@@ -984,9 +1014,8 @@ load_ind:
                                emit_mod(r_A, r_s0, ctx);
                        }
                        break;
-               case BPF_S_ALU_DIV_X:
+               case BPF_ALU | BPF_DIV | BPF_X:
                        /* A /= X */
-                       update_on_xread(ctx);
                        ctx->flags |= SEEN_X | SEEN_A;
                        /* Check if r_X is zero */
                        emit_bcond(MIPS_COND_EQ, r_X, r_zero,
@@ -994,9 +1023,8 @@ load_ind:
                        emit_load_imm(r_val, 0, ctx); /* delay slot */
                        emit_div(r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_MOD_X:
+               case BPF_ALU | BPF_MOD | BPF_X:
                        /* A %= X */
-                       update_on_xread(ctx);
                        ctx->flags |= SEEN_X | SEEN_A;
                        /* Check if r_X is zero */
                        emit_bcond(MIPS_COND_EQ, r_X, r_zero,
@@ -1004,94 +1032,89 @@ load_ind:
                        emit_load_imm(r_val, 0, ctx); /* delay slot */
                        emit_mod(r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_OR_K:
+               case BPF_ALU | BPF_OR | BPF_K:
                        /* A |= K */
                        ctx->flags |= SEEN_A;
                        emit_ori(r_A, r_A, k, ctx);
                        break;
-               case BPF_S_ALU_OR_X:
+               case BPF_ALU | BPF_OR | BPF_X:
                        /* A |= X */
-                       update_on_xread(ctx);
                        ctx->flags |= SEEN_A;
                        emit_ori(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_XOR_K:
+               case BPF_ALU | BPF_XOR | BPF_K:
                        /* A ^= k */
                        ctx->flags |= SEEN_A;
                        emit_xori(r_A, r_A, k, ctx);
                        break;
-               case BPF_S_ANC_ALU_XOR_X:
-               case BPF_S_ALU_XOR_X:
+               case BPF_ANC | SKF_AD_ALU_XOR_X:
+               case BPF_ALU | BPF_XOR | BPF_X:
                        /* A ^= X */
-                       update_on_xread(ctx);
                        ctx->flags |= SEEN_A;
                        emit_xor(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_AND_K:
+               case BPF_ALU | BPF_AND | BPF_K:
                        /* A &= K */
                        ctx->flags |= SEEN_A;
                        emit_andi(r_A, r_A, k, ctx);
                        break;
-               case BPF_S_ALU_AND_X:
+               case BPF_ALU | BPF_AND | BPF_X:
                        /* A &= X */
-                       update_on_xread(ctx);
                        ctx->flags |= SEEN_A | SEEN_X;
                        emit_and(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_LSH_K:
+               case BPF_ALU | BPF_LSH | BPF_K:
                        /* A <<= K */
                        ctx->flags |= SEEN_A;
                        emit_sll(r_A, r_A, k, ctx);
                        break;
-               case BPF_S_ALU_LSH_X:
+               case BPF_ALU | BPF_LSH | BPF_X:
                        /* A <<= X */
                        ctx->flags |= SEEN_A | SEEN_X;
-                       update_on_xread(ctx);
                        emit_sllv(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_RSH_K:
+               case BPF_ALU | BPF_RSH | BPF_K:
                        /* A >>= K */
                        ctx->flags |= SEEN_A;
                        emit_srl(r_A, r_A, k, ctx);
                        break;
-               case BPF_S_ALU_RSH_X:
+               case BPF_ALU | BPF_RSH | BPF_X:
                        ctx->flags |= SEEN_A | SEEN_X;
-                       update_on_xread(ctx);
                        emit_srlv(r_A, r_A, r_X, ctx);
                        break;
-               case BPF_S_ALU_NEG:
+               case BPF_ALU | BPF_NEG:
                        /* A = -A */
                        ctx->flags |= SEEN_A;
                        emit_neg(r_A, ctx);
                        break;
-               case BPF_S_JMP_JA:
+               case BPF_JMP | BPF_JA:
                        /* pc += K */
                        emit_b(b_imm(i + k + 1, ctx), ctx);
                        emit_nop(ctx);
                        break;
-               case BPF_S_JMP_JEQ_K:
+               case BPF_JMP | BPF_JEQ | BPF_K:
                        /* pc += ( A == K ) ? pc->jt : pc->jf */
                        condt = MIPS_COND_EQ | MIPS_COND_K;
                        goto jmp_cmp;
-               case BPF_S_JMP_JEQ_X:
+               case BPF_JMP | BPF_JEQ | BPF_X:
                        ctx->flags |= SEEN_X;
                        /* pc += ( A == X ) ? pc->jt : pc->jf */
                        condt = MIPS_COND_EQ | MIPS_COND_X;
                        goto jmp_cmp;
-               case BPF_S_JMP_JGE_K:
+               case BPF_JMP | BPF_JGE | BPF_K:
                        /* pc += ( A >= K ) ? pc->jt : pc->jf */
                        condt = MIPS_COND_GE | MIPS_COND_K;
                        goto jmp_cmp;
-               case BPF_S_JMP_JGE_X:
+               case BPF_JMP | BPF_JGE | BPF_X:
                        ctx->flags |= SEEN_X;
                        /* pc += ( A >= X ) ? pc->jt : pc->jf */
                        condt = MIPS_COND_GE | MIPS_COND_X;
                        goto jmp_cmp;
-               case BPF_S_JMP_JGT_K:
+               case BPF_JMP | BPF_JGT | BPF_K:
                        /* pc += ( A > K ) ? pc->jt : pc->jf */
                        condt = MIPS_COND_GT | MIPS_COND_K;
                        goto jmp_cmp;
-               case BPF_S_JMP_JGT_X:
+               case BPF_JMP | BPF_JGT | BPF_X:
                        ctx->flags |= SEEN_X;
                        /* pc += ( A > X ) ? pc->jt : pc->jf */
                        condt = MIPS_COND_GT | MIPS_COND_X;
@@ -1109,7 +1132,7 @@ jmp_cmp:
                                }
                                /* A < (K|X) ? r_scrach = 1 */
                                b_off = b_imm(i + inst->jf + 1, ctx);
-                               emit_bcond(MIPS_COND_GT, r_s0, r_zero, b_off,
+                               emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off,
                                           ctx);
                                emit_nop(ctx);
                                /* A > (K|X) ? scratch = 0 */
@@ -1167,7 +1190,7 @@ jmp_cmp:
                                }
                        }
                        break;
-               case BPF_S_JMP_JSET_K:
+               case BPF_JMP | BPF_JSET | BPF_K:
                        ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A;
                        /* pc += (A & K) ? pc -> jt : pc -> jf */
                        emit_load_imm(r_s1, k, ctx);
@@ -1181,7 +1204,7 @@ jmp_cmp:
                        emit_b(b_off, ctx);
                        emit_nop(ctx);
                        break;
-               case BPF_S_JMP_JSET_X:
+               case BPF_JMP | BPF_JSET | BPF_X:
                        ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A;
                        /* pc += (A & X) ? pc -> jt : pc -> jf */
                        emit_and(r_s0, r_A, r_X, ctx);
@@ -1194,7 +1217,7 @@ jmp_cmp:
                        emit_b(b_off, ctx);
                        emit_nop(ctx);
                        break;
-               case BPF_S_RET_A:
+               case BPF_RET | BPF_A:
                        ctx->flags |= SEEN_A;
                        if (i != prog->len - 1)
                                /*
@@ -1204,7 +1227,7 @@ jmp_cmp:
                                emit_b(b_imm(prog->len, ctx), ctx);
                        emit_reg_move(r_ret, r_A, ctx); /* delay slot */
                        break;
-               case BPF_S_RET_K:
+               case BPF_RET | BPF_K:
                        /*
                         * It can emit two instructions so it does not fit on
                         * the delay slot.
@@ -1219,19 +1242,18 @@ jmp_cmp:
                                emit_nop(ctx);
                        }
                        break;
-               case BPF_S_MISC_TAX:
+               case BPF_MISC | BPF_TAX:
                        /* X = A */
                        ctx->flags |= SEEN_X | SEEN_A;
                        emit_jit_reg_move(r_X, r_A, ctx);
                        break;
-               case BPF_S_MISC_TXA:
+               case BPF_MISC | BPF_TXA:
                        /* A = X */
                        ctx->flags |= SEEN_A | SEEN_X;
-                       update_on_xread(ctx);
                        emit_jit_reg_move(r_A, r_X, ctx);
                        break;
                /* AUX */
-               case BPF_S_ANC_PROTOCOL:
+               case BPF_ANC | SKF_AD_PROTOCOL:
                        /* A = ntohs(skb->protocol */
                        ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A;
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
@@ -1256,7 +1278,7 @@ jmp_cmp:
                        }
 #endif
                        break;
-               case BPF_S_ANC_CPU:
+               case BPF_ANC | SKF_AD_CPU:
                        ctx->flags |= SEEN_A | SEEN_OFF;
                        /* A = current_thread_info()->cpu */
                        BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info,
@@ -1265,11 +1287,12 @@ jmp_cmp:
                        /* $28/gp points to the thread_info struct */
                        emit_load(r_A, 28, off, ctx);
                        break;
-               case BPF_S_ANC_IFINDEX:
+               case BPF_ANC | SKF_AD_IFINDEX:
                        /* A = skb->dev->ifindex */
                        ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0;
                        off = offsetof(struct sk_buff, dev);
-                       emit_load(r_s0, r_skb, off, ctx);
+                       /* Load *dev pointer */
+                       emit_load_ptr(r_s0, r_skb, off, ctx);
                        /* error (0) in the delay slot */
                        emit_bcond(MIPS_COND_EQ, r_s0, r_zero,
                                   b_imm(prog->len, ctx), ctx);
@@ -1279,31 +1302,36 @@ jmp_cmp:
                        off = offsetof(struct net_device, ifindex);
                        emit_load(r_A, r_s0, off, ctx);
                        break;
-               case BPF_S_ANC_MARK:
+               case BPF_ANC | SKF_AD_MARK:
                        ctx->flags |= SEEN_SKB | SEEN_A;
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
                        off = offsetof(struct sk_buff, mark);
                        emit_load(r_A, r_skb, off, ctx);
                        break;
-               case BPF_S_ANC_RXHASH:
+               case BPF_ANC | SKF_AD_RXHASH:
                        ctx->flags |= SEEN_SKB | SEEN_A;
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
                        off = offsetof(struct sk_buff, hash);
                        emit_load(r_A, r_skb, off, ctx);
                        break;
-               case BPF_S_ANC_VLAN_TAG:
-               case BPF_S_ANC_VLAN_TAG_PRESENT:
+               case BPF_ANC | SKF_AD_VLAN_TAG:
+               case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
                        ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A;
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
                                                  vlan_tci) != 2);
                        off = offsetof(struct sk_buff, vlan_tci);
                        emit_half_load(r_s0, r_skb, off, ctx);
-                       if (inst->code == BPF_S_ANC_VLAN_TAG)
-                               emit_and(r_A, r_s0, VLAN_VID_MASK, ctx);
-                       else
-                               emit_and(r_A, r_s0, VLAN_TAG_PRESENT, ctx);
+                       if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) {
+                               emit_andi(r_A, r_s0, (u16)~VLAN_TAG_PRESENT, ctx);
+                       } else {
+                               emit_andi(r_A, r_s0, VLAN_TAG_PRESENT, ctx);
+                               /* return 1 if present */
+                               emit_sltu(r_A, r_zero, r_A, ctx);
+                       }
                        break;
-               case BPF_S_ANC_PKTTYPE:
+               case BPF_ANC | SKF_AD_PKTTYPE:
+                       ctx->flags |= SEEN_SKB;
+
                        off = pkt_type_offset();
 
                        if (off < 0)
@@ -1311,8 +1339,12 @@ jmp_cmp:
                        emit_load_byte(r_tmp, r_skb, off, ctx);
                        /* Keep only the last 3 bits */
                        emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx);
+#ifdef __BIG_ENDIAN_BITFIELD
+                       /* Get the actual packet type to the lower 3 bits */
+                       emit_srl(r_A, r_A, 5, ctx);
+#endif
                        break;
-               case BPF_S_ANC_QUEUE:
+               case BPF_ANC | SKF_AD_QUEUE:
                        ctx->flags |= SEEN_SKB | SEEN_A;
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
                                                  queue_mapping) != 2);
@@ -1322,8 +1354,8 @@ jmp_cmp:
                        emit_half_load(r_A, r_skb, off, ctx);
                        break;
                default:
-                       pr_warn("%s: Unhandled opcode: 0x%02x\n", __FILE__,
-                               inst->code);
+                       pr_debug("%s: Unhandled opcode: 0x%02x\n", __FILE__,
+                                inst->code);
                        return -1;
                }
        }
index 790352f..35d16bd 100644 (file)
@@ -303,7 +303,6 @@ config PPC_EARLY_DEBUG_OPAL_VTERMNO
          This correspond to which /dev/hvcN you want to use for early
          debug.
 
-         On OPAL v1 (takeover) this should always be 0
          On OPAL v2, this will be 0 for network console and 1 or 2 for
          the machine built-in serial ports.
 
index 37991e1..840a550 100644 (file)
@@ -88,4 +88,15 @@ static inline unsigned long ppc_function_entry(void *func)
 #endif
 }
 
+static inline unsigned long ppc_global_function_entry(void *func)
+{
+#if defined(CONFIG_PPC64) && defined(_CALL_ELF) && _CALL_ELF == 2
+       /* PPC64 ABIv2 the global entry point is at the address */
+       return (unsigned long)func;
+#else
+       /* All other cases there is no change vs ppc_function_entry() */
+       return ppc_function_entry(func);
+#endif
+}
+
 #endif /* _ASM_POWERPC_CODE_PATCHING_H */
index 4600188..0da1dbd 100644 (file)
 #ifndef __OPAL_H
 #define __OPAL_H
 
-/****** Takeover interface ********/
-
-/* PAPR H-Call used to querty the HAL existence and/or instanciate
- * it from within pHyp (tech preview only).
- *
- * This is exclusively used in prom_init.c
- */
-
 #ifndef __ASSEMBLY__
-
-struct opal_takeover_args {
-       u64     k_image;                /* r4 */
-       u64     k_size;                 /* r5 */
-       u64     k_entry;                /* r6 */
-       u64     k_entry2;               /* r7 */
-       u64     hal_addr;               /* r8 */
-       u64     rd_image;               /* r9 */
-       u64     rd_size;                /* r10 */
-       u64     rd_loc;                 /* r11 */
-};
-
 /*
  * SG entry
  *
@@ -55,15 +35,6 @@ struct opal_sg_list {
 /* We calculate number of sg entries based on PAGE_SIZE */
 #define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry))
 
-extern long opal_query_takeover(u64 *hal_size, u64 *hal_align);
-
-extern long opal_do_takeover(struct opal_takeover_args *args);
-
-struct rtas_args;
-extern int opal_enter_rtas(struct rtas_args *args,
-                          unsigned long data,
-                          unsigned long entry);
-
 #endif /* __ASSEMBLY__ */
 
 /****** OPAL APIs ******/
index b9bd1ca..96f59de 100644 (file)
@@ -9,10 +9,6 @@
 
 #include <uapi/asm/swab.h>
 
-#ifdef __GNUC__
-#ifndef __powerpc64__
-#endif /* __powerpc64__ */
-
 static __inline__ __u16 ld_le16(const volatile __u16 *addr)
 {
        __u16 val;
@@ -20,19 +16,12 @@ static __inline__ __u16 ld_le16(const volatile __u16 *addr)
        __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
        return val;
 }
-#define __arch_swab16p ld_le16
 
 static __inline__ void st_le16(volatile __u16 *addr, const __u16 val)
 {
        __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
 }
 
-static inline void __arch_swab16s(__u16 *addr)
-{
-       st_le16(addr, *addr);
-}
-#define __arch_swab16s __arch_swab16s
-
 static __inline__ __u32 ld_le32(const volatile __u32 *addr)
 {
        __u32 val;
@@ -40,42 +29,10 @@ static __inline__ __u32 ld_le32(const volatile __u32 *addr)
        __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
        return val;
 }
-#define __arch_swab32p ld_le32
 
 static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
 {
        __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
 }
 
-static inline void __arch_swab32s(__u32 *addr)
-{
-       st_le32(addr, *addr);
-}
-#define __arch_swab32s __arch_swab32s
-
-static inline __attribute_const__ __u16 __arch_swab16(__u16 value)
-{
-       __u16 result;
-
-       __asm__("rlwimi %0,%1,8,16,23"
-           : "=r" (result)
-           : "r" (value), "0" (value >> 8));
-       return result;
-}
-#define __arch_swab16 __arch_swab16
-
-static inline __attribute_const__ __u32 __arch_swab32(__u32 value)
-{
-       __u32 result;
-
-       __asm__("rlwimi %0,%1,24,16,23\n\t"
-           "rlwimi %0,%1,8,8,15\n\t"
-           "rlwimi %0,%1,24,0,7"
-           : "=r" (result)
-           : "r" (value), "0" (value >> 24));
-       return result;
-}
-#define __arch_swab32 __arch_swab32
-
-#endif /* __GNUC__ */
 #endif /* _ASM_POWERPC_SWAB_H */
index f202d07..d178834 100644 (file)
@@ -10,6 +10,8 @@
  *
  */
 
+#define pr_fmt(fmt) "ftrace-powerpc: " fmt
+
 #include <linux/spinlock.h>
 #include <linux/hardirq.h>
 #include <linux/uaccess.h>
@@ -105,7 +107,7 @@ __ftrace_make_nop(struct module *mod,
                  struct dyn_ftrace *rec, unsigned long addr)
 {
        unsigned int op;
-       unsigned long ptr;
+       unsigned long entry, ptr;
        unsigned long ip = rec->ip;
        void *tramp;
 
@@ -115,7 +117,7 @@ __ftrace_make_nop(struct module *mod,
 
        /* Make sure that that this is still a 24bit jump */
        if (!is_bl_op(op)) {
-               printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
+               pr_err("Not expected bl: opcode is %x\n", op);
                return -EINVAL;
        }
 
@@ -125,21 +127,21 @@ __ftrace_make_nop(struct module *mod,
        pr_devel("ip:%lx jumps to %p", ip, tramp);
 
        if (!is_module_trampoline(tramp)) {
-               printk(KERN_ERR "Not a trampoline\n");
+               pr_err("Not a trampoline\n");
                return -EINVAL;
        }
 
        if (module_trampoline_target(mod, tramp, &ptr)) {
-               printk(KERN_ERR "Failed to get trampoline target\n");
+               pr_err("Failed to get trampoline target\n");
                return -EFAULT;
        }
 
        pr_devel("trampoline target %lx", ptr);
 
+       entry = ppc_global_function_entry((void *)addr);
        /* This should match what was called */
-       if (ptr != ppc_function_entry((void *)addr)) {
-               printk(KERN_ERR "addr %lx does not match expected %lx\n",
-                       ptr, ppc_function_entry((void *)addr));
+       if (ptr != entry) {
+               pr_err("addr %lx does not match expected %lx\n", ptr, entry);
                return -EINVAL;
        }
 
@@ -179,7 +181,7 @@ __ftrace_make_nop(struct module *mod,
 
        /* Make sure that that this is still a 24bit jump */
        if (!is_bl_op(op)) {
-               printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
+               pr_err("Not expected bl: opcode is %x\n", op);
                return -EINVAL;
        }
 
@@ -198,7 +200,7 @@ __ftrace_make_nop(struct module *mod,
 
        /* Find where the trampoline jumps to */
        if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
-               printk(KERN_ERR "Failed to read %lx\n", tramp);
+               pr_err("Failed to read %lx\n", tramp);
                return -EFAULT;
        }
 
@@ -209,7 +211,7 @@ __ftrace_make_nop(struct module *mod,
            ((jmp[1] & 0xffff0000) != 0x398c0000) ||
            (jmp[2] != 0x7d8903a6) ||
            (jmp[3] != 0x4e800420)) {
-               printk(KERN_ERR "Not a trampoline\n");
+               pr_err("Not a trampoline\n");
                return -EINVAL;
        }
 
@@ -221,8 +223,7 @@ __ftrace_make_nop(struct module *mod,
        pr_devel(" %lx ", tramp);
 
        if (tramp != addr) {
-               printk(KERN_ERR
-                      "Trampoline location %08lx does not match addr\n",
+               pr_err("Trampoline location %08lx does not match addr\n",
                       tramp);
                return -EINVAL;
        }
@@ -263,15 +264,13 @@ int ftrace_make_nop(struct module *mod,
         */
        if (!rec->arch.mod) {
                if (!mod) {
-                       printk(KERN_ERR "No module loaded addr=%lx\n",
-                              addr);
+                       pr_err("No module loaded addr=%lx\n", addr);
                        return -EFAULT;
                }
                rec->arch.mod = mod;
        } else if (mod) {
                if (mod != rec->arch.mod) {
-                       printk(KERN_ERR
-                              "Record mod %p not equal to passed in mod %p\n",
+                       pr_err("Record mod %p not equal to passed in mod %p\n",
                               rec->arch.mod, mod);
                        return -EINVAL;
                }
@@ -307,26 +306,25 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
         * The load offset is different depending on the ABI. For simplicity
         * just mask it out when doing the compare.
         */
-       if ((op[0] != 0x48000008) || ((op[1] & 0xffff00000) != 0xe8410000)) {
-               printk(KERN_ERR "Unexpected call sequence: %x %x\n",
-                       op[0], op[1]);
+       if ((op[0] != 0x48000008) || ((op[1] & 0xffff0000) != 0xe8410000)) {
+               pr_err("Unexpected call sequence: %x %x\n", op[0], op[1]);
                return -EINVAL;
        }
 
        /* If we never set up a trampoline to ftrace_caller, then bail */
        if (!rec->arch.mod->arch.tramp) {
-               printk(KERN_ERR "No ftrace trampoline\n");
+               pr_err("No ftrace trampoline\n");
                return -EINVAL;
        }
 
        /* Ensure branch is within 24 bits */
-       if (create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
-               printk(KERN_ERR "Branch out of range");
+       if (!create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
+               pr_err("Branch out of range\n");
                return -EINVAL;
        }
 
        if (patch_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
-               printk(KERN_ERR "REL24 out of range!\n");
+               pr_err("REL24 out of range!\n");
                return -EINVAL;
        }
 
@@ -345,13 +343,13 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 
        /* It should be pointing to a nop */
        if (op != PPC_INST_NOP) {
-               printk(KERN_ERR "Expected NOP but have %x\n", op);
+               pr_err("Expected NOP but have %x\n", op);
                return -EINVAL;
        }
 
        /* If we never set up a trampoline to ftrace_caller, then bail */
        if (!rec->arch.mod->arch.tramp) {
-               printk(KERN_ERR "No ftrace trampoline\n");
+               pr_err("No ftrace trampoline\n");
                return -EINVAL;
        }
 
@@ -359,7 +357,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
        op = create_branch((unsigned int *)ip,
                           rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
        if (!op) {
-               printk(KERN_ERR "REL24 out of range!\n");
+               pr_err("REL24 out of range!\n");
                return -EINVAL;
        }
 
@@ -397,7 +395,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
         * already have a module defined.
         */
        if (!rec->arch.mod) {
-               printk(KERN_ERR "No module loaded\n");
+               pr_err("No module loaded\n");
                return -EINVAL;
        }
 
index b82227e..12e48d5 100644 (file)
@@ -23,7 +23,7 @@ unsigned int ioread16(void __iomem *addr)
 }
 unsigned int ioread16be(void __iomem *addr)
 {
-       return in_be16(addr);
+       return readw_be(addr);
 }
 unsigned int ioread32(void __iomem *addr)
 {
@@ -31,7 +31,7 @@ unsigned int ioread32(void __iomem *addr)
 }
 unsigned int ioread32be(void __iomem *addr)
 {
-       return in_be32(addr);
+       return readl_be(addr);
 }
 EXPORT_SYMBOL(ioread8);
 EXPORT_SYMBOL(ioread16);
@@ -49,7 +49,7 @@ void iowrite16(u16 val, void __iomem *addr)
 }
 void iowrite16be(u16 val, void __iomem *addr)
 {
-       out_be16(addr, val);
+       writew_be(val, addr);
 }
 void iowrite32(u32 val, void __iomem *addr)
 {
@@ -57,7 +57,7 @@ void iowrite32(u32 val, void __iomem *addr)
 }
 void iowrite32be(u32 val, void __iomem *addr)
 {
-       out_be32(addr, val);
+       writel_be(val, addr);
 }
 EXPORT_SYMBOL(iowrite8);
 EXPORT_SYMBOL(iowrite16);
@@ -75,15 +75,15 @@ EXPORT_SYMBOL(iowrite32be);
  */
 void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-       _insb((u8 __iomem *) addr, dst, count);
+       readsb(addr, dst, count);
 }
 void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-       _insw_ns((u16 __iomem *) addr, dst, count);
+       readsw(addr, dst, count);
 }
 void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-       _insl_ns((u32 __iomem *) addr, dst, count);
+       readsl(addr, dst, count);
 }
 EXPORT_SYMBOL(ioread8_rep);
 EXPORT_SYMBOL(ioread16_rep);
@@ -91,15 +91,15 @@ EXPORT_SYMBOL(ioread32_rep);
 
 void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-       _outsb((u8 __iomem *) addr, src, count);
+       writesb(addr, src, count);
 }
 void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-       _outsw_ns((u16 __iomem *) addr, src, count);
+       writesw(addr, src, count);
 }
 void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-       _outsl_ns((u32 __iomem *) addr, src, count);
+       writesl(addr, src, count);
 }
 EXPORT_SYMBOL(iowrite8_rep);
 EXPORT_SYMBOL(iowrite16_rep);
index 90fab64..2f72af8 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/kdebug.h>
 #include <linux/slab.h>
+#include <asm/code-patching.h>
 #include <asm/cacheflush.h>
 #include <asm/sstep.h>
 #include <asm/uaccess.h>
@@ -491,12 +492,10 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
        return ret;
 }
 
-#ifdef CONFIG_PPC64
 unsigned long arch_deref_entry_point(void *entry)
 {
-       return ((func_descr_t *)entry)->entry;
+       return ppc_global_function_entry(entry);
 }
-#endif
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
@@ -508,7 +507,11 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
        /* setup return addr to the jprobe handler routine */
        regs->nip = arch_deref_entry_point(jp->entry);
 #ifdef CONFIG_PPC64
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+       regs->gpr[12] = (unsigned long)jp->entry;
+#else
        regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
+#endif
 #endif
 
        return 1;
index 077d2ce..d807ee6 100644 (file)
@@ -315,8 +315,17 @@ static void dedotify_versions(struct modversion_info *vers,
        struct modversion_info *end;
 
        for (end = (void *)vers + size; vers < end; vers++)
-               if (vers->name[0] == '.')
+               if (vers->name[0] == '.') {
                        memmove(vers->name, vers->name+1, strlen(vers->name));
+#ifdef ARCH_RELOCATES_KCRCTAB
+                       /* The TOC symbol has no CRC computed. To avoid CRC
+                        * check failing, we must force it to the expected
+                        * value (see CRC check in module.c).
+                        */
+                       if (!strcmp(vers->name, "TOC."))
+                               vers->crc = -(unsigned long)reloc_start;
+#endif
+               }
 }
 
 /* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */
index 613a860..b694b07 100644 (file)
@@ -662,13 +662,6 @@ void __init early_init_devtree(void *params)
        of_scan_flat_dt(early_init_dt_scan_fw_dump, NULL);
 #endif
 
-       /* Pre-initialize the cmd_line with the content of boot_commmand_line,
-        * which will be empty except when the content of the variable has
-        * been overriden by a bootloading mechanism. This happens typically
-        * with HAL takeover
-        */
-       strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
-
        /* Retrieve various informations from the /chosen node of the
         * device-tree, including the platform type, initrd location and
         * size, TCE reserve, and more ...
index 078145a..1a85d8f 100644 (file)
@@ -1268,201 +1268,6 @@ static u64 __initdata prom_opal_base;
 static u64 __initdata prom_opal_entry;
 #endif
 
-#ifdef __BIG_ENDIAN__
-/* XXX Don't change this structure without updating opal-takeover.S */
-static struct opal_secondary_data {
-       s64                             ack;    /*  0 */
-       u64                             go;     /*  8 */
-       struct opal_takeover_args       args;   /* 16 */
-} opal_secondary_data;
-
-static u64 __initdata prom_opal_align;
-static u64 __initdata prom_opal_size;
-static int __initdata prom_rtas_start_cpu;
-static u64 __initdata prom_rtas_data;
-static u64 __initdata prom_rtas_entry;
-
-extern char opal_secondary_entry;
-
-static void __init prom_query_opal(void)
-{
-       long rc;
-
-       /* We must not query for OPAL presence on a machine that
-        * supports TNK takeover (970 blades), as this uses the same
-        * h-call with different arguments and will crash
-        */
-       if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
-                                   ADDR("/tnk-memory-map")))) {
-               prom_printf("TNK takeover detected, skipping OPAL check\n");
-               return;
-       }
-
-       prom_printf("Querying for OPAL presence... ");
-
-       rc = opal_query_takeover(&prom_opal_size,
-                                &prom_opal_align);
-       prom_debug("(rc = %ld) ", rc);
-       if (rc != 0) {
-               prom_printf("not there.\n");
-               return;
-       }
-       of_platform = PLATFORM_OPAL;
-       prom_printf(" there !\n");
-       prom_debug("  opal_size  = 0x%lx\n", prom_opal_size);
-       prom_debug("  opal_align = 0x%lx\n", prom_opal_align);
-       if (prom_opal_align < 0x10000)
-               prom_opal_align = 0x10000;
-}
-
-static int __init prom_rtas_call(int token, int nargs, int nret,
-                                int *outputs, ...)
-{
-       struct rtas_args rtas_args;
-       va_list list;
-       int i;
-
-       rtas_args.token = token;
-       rtas_args.nargs = nargs;
-       rtas_args.nret  = nret;
-       rtas_args.rets  = (rtas_arg_t *)&(rtas_args.args[nargs]);
-       va_start(list, outputs);
-       for (i = 0; i < nargs; ++i)
-               rtas_args.args[i] = va_arg(list, rtas_arg_t);
-       va_end(list);
-
-       for (i = 0; i < nret; ++i)
-               rtas_args.rets[i] = 0;
-
-       opal_enter_rtas(&rtas_args, prom_rtas_data,
-                       prom_rtas_entry);
-
-       if (nret > 1 && outputs != NULL)
-               for (i = 0; i < nret-1; ++i)
-                       outputs[i] = rtas_args.rets[i+1];
-       return (nret > 0)? rtas_args.rets[0]: 0;
-}
-
-static void __init prom_opal_hold_cpus(void)
-{
-       int i, cnt, cpu, rc;
-       long j;
-       phandle node;
-       char type[64];
-       u32 servers[8];
-       void *entry = (unsigned long *)&opal_secondary_entry;
-       struct opal_secondary_data *data = &opal_secondary_data;
-
-       prom_debug("prom_opal_hold_cpus: start...\n");
-       prom_debug("    - entry       = 0x%x\n", entry);
-       prom_debug("    - data        = 0x%x\n", data);
-
-       data->ack = -1;
-       data->go = 0;
-
-       /* look for cpus */
-       for (node = 0; prom_next_node(&node); ) {
-               type[0] = 0;
-               prom_getprop(node, "device_type", type, sizeof(type));
-               if (strcmp(type, "cpu") != 0)
-                       continue;
-
-               /* Skip non-configured cpus. */
-               if (prom_getprop(node, "status", type, sizeof(type)) > 0)
-                       if (strcmp(type, "okay") != 0)
-                               continue;
-
-               cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
-                            sizeof(servers));
-               if (cnt == PROM_ERROR)
-                       break;
-               cnt >>= 2;
-               for (i = 0; i < cnt; i++) {
-                       cpu = servers[i];
-                       prom_debug("CPU %d ... ", cpu);
-                       if (cpu == prom.cpu) {
-                               prom_debug("booted !\n");
-                               continue;
-                       }
-                       prom_debug("starting ... ");
-
-                       /* Init the acknowledge var which will be reset by
-                        * the secondary cpu when it awakens from its OF
-                        * spinloop.
-                        */
-                       data->ack = -1;
-                       rc = prom_rtas_call(prom_rtas_start_cpu, 3, 1,
-                                           NULL, cpu, entry, data);
-                       prom_debug("rtas rc=%d ...", rc);
-
-                       for (j = 0; j < 100000000 && data->ack == -1; j++) {
-                               HMT_low();
-                               mb();
-                       }
-                       HMT_medium();
-                       if (data->ack != -1)
-                               prom_debug("done, PIR=0x%x\n", data->ack);
-                       else
-                               prom_debug("timeout !\n");
-               }
-       }
-       prom_debug("prom_opal_hold_cpus: end...\n");
-}
-
-static void __init prom_opal_takeover(void)
-{
-       struct opal_secondary_data *data = &opal_secondary_data;
-       struct opal_takeover_args *args = &data->args;
-       u64 align = prom_opal_align;
-       u64 top_addr, opal_addr;
-
-       args->k_image   = (u64)_stext;
-       args->k_size    = _end - _stext;
-       args->k_entry   = 0;
-       args->k_entry2  = 0x60;
-
-       top_addr = _ALIGN_UP(args->k_size, align);
-
-       if (prom_initrd_start != 0) {
-               args->rd_image = prom_initrd_start;
-               args->rd_size = prom_initrd_end - args->rd_image;
-               args->rd_loc = top_addr;
-               top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
-       }
-
-       /* Pickup an address for the HAL. We want to go really high
-        * up to avoid problem with future kexecs. On the other hand
-        * we don't want to be all over the TCEs on P5IOC2 machines
-        * which are going to be up there too. We assume the machine
-        * has plenty of memory, and we ask for the HAL for now to
-        * be just below the 1G point, or above the initrd
-        */
-       opal_addr = _ALIGN_DOWN(0x40000000 - prom_opal_size, align);
-       if (opal_addr < top_addr)
-               opal_addr = top_addr;
-       args->hal_addr = opal_addr;
-
-       /* Copy the command line to the kernel image */
-       strlcpy(boot_command_line, prom_cmd_line,
-               COMMAND_LINE_SIZE);
-
-       prom_debug("  k_image    = 0x%lx\n", args->k_image);
-       prom_debug("  k_size     = 0x%lx\n", args->k_size);
-       prom_debug("  k_entry    = 0x%lx\n", args->k_entry);
-       prom_debug("  k_entry2   = 0x%lx\n", args->k_entry2);
-       prom_debug("  hal_addr   = 0x%lx\n", args->hal_addr);
-       prom_debug("  rd_image   = 0x%lx\n", args->rd_image);
-       prom_debug("  rd_size    = 0x%lx\n", args->rd_size);
-       prom_debug("  rd_loc     = 0x%lx\n", args->rd_loc);
-       prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
-       prom_close_stdin();
-       mb();
-       data->go = 1;
-       for (;;)
-               opal_do_takeover(args);
-}
-#endif /* __BIG_ENDIAN__ */
-
 /*
  * Allocate room for and instantiate OPAL
  */
@@ -1597,12 +1402,6 @@ static void __init prom_instantiate_rtas(void)
                         &val, sizeof(val)) != PROM_ERROR)
                rtas_has_query_cpu_stopped = true;
 
-#if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__)
-       /* PowerVN takeover hack */
-       prom_rtas_data = base;
-       prom_rtas_entry = entry;
-       prom_getprop(rtas_node, "start-cpu", &prom_rtas_start_cpu, 4);
-#endif
        prom_debug("rtas base     = 0x%x\n", base);
        prom_debug("rtas entry    = 0x%x\n", entry);
        prom_debug("rtas size     = 0x%x\n", (long)size);
@@ -3027,16 +2826,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
                prom_instantiate_rtas();
 
 #ifdef CONFIG_PPC_POWERNV
-#ifdef __BIG_ENDIAN__
-       /* Detect HAL and try instanciating it & doing takeover */
-       if (of_platform == PLATFORM_PSERIES_LPAR) {
-               prom_query_opal();
-               if (of_platform == PLATFORM_OPAL) {
-                       prom_opal_hold_cpus();
-                       prom_opal_takeover();
-               }
-       } else
-#endif /* __BIG_ENDIAN__ */
        if (of_platform == PLATFORM_OPAL)
                prom_instantiate_opal();
 #endif /* CONFIG_PPC_POWERNV */
index 77aa1e9..fe8e54b 100644 (file)
@@ -21,9 +21,7 @@ _end enter_prom memcpy memset reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
 reloc_got2 kernstart_addr memstart_addr linux_banner _stext
-opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry
-boot_command_line __prom_init_toc_start __prom_init_toc_end
-btext_setup_display TOC."
+__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC."
 
 NM="$1"
 OBJ="$2"
index e239df3..e5b022c 100644 (file)
@@ -469,9 +469,17 @@ void __init smp_setup_cpu_maps(void)
                }
 
                for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
+                       bool avail;
+
                        DBG("    thread %d -> cpu %d (hard id %d)\n",
                            j, cpu, be32_to_cpu(intserv[j]));
-                       set_cpu_present(cpu, of_device_is_available(dn));
+
+                       avail = of_device_is_available(dn);
+                       if (!avail)
+                               avail = !of_property_match_string(dn,
+                                               "enable-method", "spin-table");
+
+                       set_cpu_present(cpu, avail);
                        set_hard_smp_processor_id(cpu, be32_to_cpu(intserv[j]));
                        set_cpu_possible(cpu, true);
                        cpu++;
index 4e47db6..1bc5a17 100644 (file)
@@ -54,7 +54,6 @@
 
 #include "signal.h"
 
-#undef DEBUG_SIG
 
 #ifdef CONFIG_PPC64
 #define sys_rt_sigreturn       compat_sys_rt_sigreturn
@@ -1063,10 +1062,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
        return 1;
 
 badframe:
-#ifdef DEBUG_SIG
-       printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
-              regs, frame, newsp);
-#endif
        if (show_unhandled_signals)
                printk_ratelimited(KERN_INFO
                                   "%s[%d]: bad frame in handle_rt_signal32: "
@@ -1484,10 +1479,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
        return 1;
 
 badframe:
-#ifdef DEBUG_SIG
-       printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
-              regs, frame, newsp);
-#endif
        if (show_unhandled_signals)
                printk_ratelimited(KERN_INFO
                                   "%s[%d]: bad frame in handle_signal32: "
index d501dc4..97c1e4b 100644 (file)
@@ -38,7 +38,6 @@
 
 #include "signal.h"
 
-#define DEBUG_SIG 0
 
 #define GP_REGS_SIZE   min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
 #define FP_REGS_SIZE   sizeof(elf_fpregset_t)
@@ -700,10 +699,6 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
        return 0;
 
 badframe:
-#if DEBUG_SIG
-       printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
-              regs, uc, &uc->uc_mcontext);
-#endif
        if (show_unhandled_signals)
                printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
                                   current->comm, current->pid, "rt_sigreturn",
@@ -809,10 +804,6 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
        return 1;
 
 badframe:
-#if DEBUG_SIG
-       printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
-              regs, frame, newsp);
-#endif
        if (show_unhandled_signals)
                printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
                                   current->comm, current->pid, "setup_rt_frame",
index 94560db..2c15ff0 100644 (file)
@@ -125,7 +125,7 @@ static ssize_t show_throttle(struct cbe_pmd_regs __iomem *pmd_regs, char *buf, i
 static ssize_t store_throttle(struct cbe_pmd_regs __iomem *pmd_regs, const char *buf, size_t size, int pos)
 {
        u64 reg_value;
-       int temp;
+       unsigned int temp;
        u64 new_value;
        int ret;
 
index d55891f..4ad227d 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                  += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
+obj-y                  += setup.o opal-wrappers.o opal.o opal-async.o
 obj-y                  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
 obj-y                  += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
 obj-y                  += opal-msglog.o
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S
deleted file mode 100644 (file)
index 11a3169..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * PowerNV OPAL takeover assembly code, for use by prom_init.c
- *
- * Copyright 2011 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 <asm/ppc_asm.h>
-#include <asm/hvcall.h>
-#include <asm/asm-offsets.h>
-#include <asm/opal.h>
-
-#define H_HAL_TAKEOVER                 0x5124
-#define H_HAL_TAKEOVER_QUERY_MAGIC     -1
-
-       .text
-_GLOBAL(opal_query_takeover)
-       mfcr    r0
-       stw     r0,8(r1)
-       stdu    r1,-STACKFRAMESIZE(r1)
-       std     r3,STK_PARAM(R3)(r1)
-       std     r4,STK_PARAM(R4)(r1)
-       li      r3,H_HAL_TAKEOVER
-       li      r4,H_HAL_TAKEOVER_QUERY_MAGIC
-       HVSC
-       addi    r1,r1,STACKFRAMESIZE
-       ld      r10,STK_PARAM(R3)(r1)
-       std     r4,0(r10)
-       ld      r10,STK_PARAM(R4)(r1)
-       std     r5,0(r10)
-       lwz     r0,8(r1)
-       mtcrf   0xff,r0
-       blr
-
-_GLOBAL(opal_do_takeover)
-       mfcr    r0
-       stw     r0,8(r1)
-       mflr    r0
-       std     r0,16(r1)
-       bl      __opal_do_takeover
-       ld      r0,16(r1)
-       mtlr    r0
-       lwz     r0,8(r1)
-       mtcrf   0xff,r0
-       blr
-
-__opal_do_takeover:
-       ld      r4,0(r3)
-       ld      r5,0x8(r3)
-       ld      r6,0x10(r3)
-       ld      r7,0x18(r3)
-       ld      r8,0x20(r3)
-       ld      r9,0x28(r3)
-       ld      r10,0x30(r3)
-       ld      r11,0x38(r3)
-       li      r3,H_HAL_TAKEOVER
-       HVSC
-       blr
-
-       .globl opal_secondary_entry
-opal_secondary_entry:
-       mr      r31,r3
-       mfmsr   r11
-       li      r12,(MSR_SF | MSR_ISF)@highest
-       sldi    r12,r12,48
-       or      r11,r11,r12
-       mtmsrd  r11
-       isync
-       mfspr   r4,SPRN_PIR
-       std     r4,0(r3)
-1:     HMT_LOW
-       ld      r4,8(r3)
-       cmpli   cr0,r4,0
-       beq     1b
-       HMT_MEDIUM
-1:     addi    r3,r31,16
-       bl      __opal_do_takeover
-       b       1b
-
-_GLOBAL(opal_enter_rtas)
-       mflr    r0
-       std     r0,16(r1)
-        stdu   r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
-
-       /* Because PROM is running in 32b mode, it clobbers the high order half
-        * of all registers that it saves.  We therefore save those registers
-        * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
-       */
-       SAVE_GPR(2, r1)
-       SAVE_GPR(13, r1)
-       SAVE_8GPRS(14, r1)
-       SAVE_10GPRS(22, r1)
-       mfcr    r10
-       mfmsr   r11
-       std     r10,_CCR(r1)
-       std     r11,_MSR(r1)
-
-       /* Get the PROM entrypoint */
-       mtlr    r5
-
-       /* Switch MSR to 32 bits mode
-        */
-        li      r12,1
-        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
-        andc    r11,r11,r12
-        li      r12,1
-        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
-        andc    r11,r11,r12
-        mtmsrd  r11
-        isync
-
-       /* Enter RTAS here... */
-       blrl
-
-       /* Just make sure that r1 top 32 bits didn't get
-        * corrupt by OF
-        */
-       rldicl  r1,r1,0,32
-
-       /* Restore the MSR (back to 64 bits) */
-       ld      r0,_MSR(r1)
-       MTMSRD(r0)
-        isync
-
-       /* Restore other registers */
-       REST_GPR(2, r1)
-       REST_GPR(13, r1)
-       REST_8GPRS(14, r1)
-       REST_10GPRS(22, r1)
-       ld      r4,_CCR(r1)
-       mtcr    r4
-
-        addi   r1,r1,PROM_FRAME_SIZE
-       ld      r0,16(r1)
-       mtlr    r0
-       blr
index 62c47bb..9e5353f 100644 (file)
@@ -476,6 +476,11 @@ void __init alloc_dart_table(void)
         */
        dart_tablebase = (unsigned long)
                __va(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
+       /*
+        * The DART space is later unmapped from the kernel linear mapping and
+        * accessing dart_tablebase during kmemleak scanning will fault.
+        */
+       kmemleak_no_scan((void *)dart_tablebase);
 
        printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase);
 }
index 8df022c..fd09a10 100644 (file)
@@ -45,7 +45,8 @@ CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_CFQ_GROUP_IOSCHED=y
 CONFIG_DEFAULT_DEADLINE=y
-CONFIG_MARCH_Z9_109=y
+CONFIG_MARCH_Z196=y
+CONFIG_TUNE_ZEC12=y
 CONFIG_NR_CPUS=256
 CONFIG_PREEMPT=y
 CONFIG_HZ_100=y
@@ -240,7 +241,6 @@ CONFIG_IP_VS_PE_SIP=m
 CONFIG_NF_CONNTRACK_IPV4=m
 # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
 CONFIG_NF_TABLES_IPV4=m
-CONFIG_NFT_REJECT_IPV4=m
 CONFIG_NFT_CHAIN_ROUTE_IPV4=m
 CONFIG_NFT_CHAIN_NAT_IPV4=m
 CONFIG_NF_TABLES_ARP=m
@@ -456,6 +456,7 @@ CONFIG_TN3270_FS=y
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_WATCHDOG=m
+CONFIG_DIAG288_WATCHDOG=m
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_INFINIBAND=m
index c81a74e..b061180 100644 (file)
@@ -45,7 +45,8 @@ CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_CFQ_GROUP_IOSCHED=y
 CONFIG_DEFAULT_DEADLINE=y
-CONFIG_MARCH_Z9_109=y
+CONFIG_MARCH_Z196=y
+CONFIG_TUNE_ZEC12=y
 CONFIG_NR_CPUS=256
 CONFIG_HZ_100=y
 CONFIG_MEMORY_HOTPLUG=y
@@ -238,7 +239,6 @@ CONFIG_IP_VS_PE_SIP=m
 CONFIG_NF_CONNTRACK_IPV4=m
 # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
 CONFIG_NF_TABLES_IPV4=m
-CONFIG_NFT_REJECT_IPV4=m
 CONFIG_NFT_CHAIN_ROUTE_IPV4=m
 CONFIG_NFT_CHAIN_NAT_IPV4=m
 CONFIG_NF_TABLES_ARP=m
@@ -453,6 +453,7 @@ CONFIG_TN3270_FS=y
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_WATCHDOG=m
+CONFIG_DIAG288_WATCHDOG=m
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_INFINIBAND=m
index b5ba8fe..d279baa 100644 (file)
@@ -43,7 +43,8 @@ CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_CFQ_GROUP_IOSCHED=y
 CONFIG_DEFAULT_DEADLINE=y
-CONFIG_MARCH_Z9_109=y
+CONFIG_MARCH_Z196=y
+CONFIG_TUNE_ZEC12=y
 CONFIG_NR_CPUS=256
 CONFIG_HZ_100=y
 CONFIG_MEMORY_HOTPLUG=y
@@ -236,7 +237,6 @@ CONFIG_IP_VS_PE_SIP=m
 CONFIG_NF_CONNTRACK_IPV4=m
 # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
 CONFIG_NF_TABLES_IPV4=m
-CONFIG_NFT_REJECT_IPV4=m
 CONFIG_NFT_CHAIN_ROUTE_IPV4=m
 CONFIG_NFT_CHAIN_NAT_IPV4=m
 CONFIG_NF_TABLES_ARP=m
@@ -451,6 +451,7 @@ CONFIG_TN3270_FS=y
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_WATCHDOG=m
+CONFIG_DIAG288_WATCHDOG=m
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_INFINIBAND=m
index cef073c..948e0e0 100644 (file)
@@ -8,7 +8,8 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_DEFAULT_DEADLINE=y
-CONFIG_MARCH_Z9_109=y
+CONFIG_MARCH_Z196=y
+CONFIG_TUNE_ZEC12=y
 # CONFIG_COMPAT is not set
 CONFIG_NR_CPUS=2
 # CONFIG_HOTPLUG_CPU is not set
index 4557cb7..2e56498 100644 (file)
@@ -135,8 +135,8 @@ CONFIG_PROVE_LOCKING=y
 CONFIG_LOCK_STAT=y
 CONFIG_DEBUG_LOCKDEP=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_DEBUG_WRITECOUNT=y
 CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_PI_LIST=y
 CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_NOTIFIERS=y
 CONFIG_PROVE_RCU=y
@@ -199,4 +199,10 @@ CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_DES_S390=m
 CONFIG_CRYPTO_AES_S390=m
 CONFIG_CRC7=m
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_ARM is not set
+# CONFIG_XZ_DEC_ARMTHUMB is not set
+# CONFIG_XZ_DEC_SPARC is not set
 CONFIG_CMM=m
index c28f32a..3815bfe 100644 (file)
@@ -33,10 +33,9 @@ static inline int init_new_context(struct task_struct *tsk,
 
 static inline void set_user_asce(struct mm_struct *mm)
 {
-       pgd_t *pgd = mm->pgd;
-
-       S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
-       set_fs(current->thread.mm_segment);
+       S390_lowcore.user_asce = mm->context.asce_bits | __pa(mm->pgd);
+       if (current->thread.mm_segment.ar4)
+               __ctl_load(S390_lowcore.user_asce, 7, 7);
        set_cpu_flag(CIF_ASCE);
 }
 
@@ -70,12 +69,11 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
        /* Clear old ASCE by loading the kernel ASCE. */
        __ctl_load(S390_lowcore.kernel_asce, 1, 1);
        __ctl_load(S390_lowcore.kernel_asce, 7, 7);
-       /* Delay loading of the new ASCE to control registers CR1 & CR7 */
-       set_cpu_flag(CIF_ASCE);
        atomic_inc(&next->context.attach_count);
        atomic_dec(&prev->context.attach_count);
        if (MACHINE_HAS_TLB_LC)
                cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask);
+       S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd);
 }
 
 #define finish_arch_post_lock_switch finish_arch_post_lock_switch
@@ -84,17 +82,18 @@ static inline void finish_arch_post_lock_switch(void)
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
 
-       if (!mm)
-               return;
-       preempt_disable();
-       while (atomic_read(&mm->context.attach_count) >> 16)
-               cpu_relax();
-
-       cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
-       set_user_asce(mm);
-       if (mm->context.flush_mm)
-               __tlb_flush_mm(mm);
-       preempt_enable();
+       load_kernel_asce();
+       if (mm) {
+               preempt_disable();
+               while (atomic_read(&mm->context.attach_count) >> 16)
+                       cpu_relax();
+
+               cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+               if (mm->context.flush_mm)
+                       __tlb_flush_mm(mm);
+               preempt_enable();
+       }
+       set_fs(current->thread.mm_segment);
 }
 
 #define enter_lazy_tlb(mm,tsk) do { } while (0)
index 29c81f8..df38c70 100644 (file)
@@ -134,8 +134,4 @@ static inline void restore_access_regs(unsigned int *acrs)
        prev = __switch_to(prev,next);                                  \
 } while (0)
 
-#define finish_arch_switch(prev) do {                                       \
-       set_fs(current->thread.mm_segment);                                  \
-} while (0)
-
 #endif /* __ASM_SWITCH_TO_H */
index 200e063..3e077b2 100644 (file)
@@ -16,7 +16,9 @@ struct ucontext_extended {
        struct ucontext  *uc_link;
        stack_t           uc_stack;
        _sigregs          uc_mcontext;
-       unsigned long     uc_sigmask[2];
+       sigset_t          uc_sigmask;
+       /* Allow for uc_sigmask growth.  Glibc uses a 1024-bit sigset_t.  */
+       unsigned char     __unused[128 - sizeof(sigset_t)];
        unsigned long     uc_gprs_high[16];
 };
 
@@ -27,7 +29,9 @@ struct ucontext {
        struct ucontext  *uc_link;
        stack_t           uc_stack;
        _sigregs          uc_mcontext;
-       sigset_t          uc_sigmask;   /* mask last for extensibility */
+       sigset_t          uc_sigmask;
+       /* Allow for uc_sigmask growth.  Glibc uses a 1024-bit sigset_t.  */
+       unsigned char     __unused[128 - sizeof(sigset_t)];
 };
 
 #endif /* !_ASM_S390_UCONTEXT_H */
index 39ddfdb..70d4b7c 100644 (file)
@@ -69,7 +69,9 @@ struct ucontext32 {
        __u32                   uc_link;        /* pointer */   
        compat_stack_t          uc_stack;
        _sigregs32              uc_mcontext;
-       compat_sigset_t         uc_sigmask;     /* mask last for extensibility */
+       compat_sigset_t         uc_sigmask;
+       /* Allow for uc_sigmask growth.  Glibc uses a 1024-bit sigset_t.  */
+       unsigned char           __unused[128 - sizeof(compat_sigset_t)];
 };
 
 struct stat64_emu31;
index 503e6d9..df922f5 100644 (file)
@@ -124,7 +124,7 @@ extern void aes_sparc64_ctr_crypt_256(const u64 *key, const u64 *input,
                                      u64 *output, unsigned int len,
                                      u64 *iv);
 
-struct aes_ops aes128_ops = {
+static struct aes_ops aes128_ops = {
        .encrypt                = aes_sparc64_encrypt_128,
        .decrypt                = aes_sparc64_decrypt_128,
        .load_encrypt_keys      = aes_sparc64_load_encrypt_keys_128,
@@ -136,7 +136,7 @@ struct aes_ops aes128_ops = {
        .ctr_crypt              = aes_sparc64_ctr_crypt_128,
 };
 
-struct aes_ops aes192_ops = {
+static struct aes_ops aes192_ops = {
        .encrypt                = aes_sparc64_encrypt_192,
        .decrypt                = aes_sparc64_decrypt_192,
        .load_encrypt_keys      = aes_sparc64_load_encrypt_keys_192,
@@ -148,7 +148,7 @@ struct aes_ops aes192_ops = {
        .ctr_crypt              = aes_sparc64_ctr_crypt_192,
 };
 
-struct aes_ops aes256_ops = {
+static struct aes_ops aes256_ops = {
        .encrypt                = aes_sparc64_encrypt_256,
        .decrypt                = aes_sparc64_decrypt_256,
        .load_encrypt_keys      = aes_sparc64_load_encrypt_keys_256,
index f08fe51..7aed2be 100644 (file)
 
 #define ATOMIC_INIT(i)  { (i) }
 
-extern int __atomic_add_return(int, atomic_t *);
-extern int atomic_cmpxchg(atomic_t *, int, int);
+int __atomic_add_return(int, atomic_t *);
+int atomic_cmpxchg(atomic_t *, int, int);
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-extern int __atomic_add_unless(atomic_t *, int, int);
-extern void atomic_set(atomic_t *, int);
+int __atomic_add_unless(atomic_t *, int, int);
+void atomic_set(atomic_t *, int);
 
 #define atomic_read(v)          (*(volatile int *)&(v)->counter)
 
index 8b2f1bd..bb894c8 100644 (file)
 #define atomic_set(v, i)       (((v)->counter) = i)
 #define atomic64_set(v, i)     (((v)->counter) = i)
 
-extern void atomic_add(int, atomic_t *);
-extern void atomic64_add(long, atomic64_t *);
-extern void atomic_sub(int, atomic_t *);
-extern void atomic64_sub(long, atomic64_t *);
+void atomic_add(int, atomic_t *);
+void atomic64_add(long, atomic64_t *);
+void atomic_sub(int, atomic_t *);
+void atomic64_sub(long, atomic64_t *);
 
-extern int atomic_add_ret(int, atomic_t *);
-extern long atomic64_add_ret(long, atomic64_t *);
-extern int atomic_sub_ret(int, atomic_t *);
-extern long atomic64_sub_ret(long, atomic64_t *);
+int atomic_add_ret(int, atomic_t *);
+long atomic64_add_ret(long, atomic64_t *);
+int atomic_sub_ret(int, atomic_t *);
+long atomic64_sub_ret(long, atomic64_t *);
 
 #define atomic_dec_return(v) atomic_sub_ret(1, v)
 #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
@@ -107,6 +107,6 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
 
 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
 
-extern long atomic64_dec_if_positive(atomic64_t *v);
+long atomic64_dec_if_positive(atomic64_t *v);
 
 #endif /* !(__ARCH_SPARC64_ATOMIC__) */
index 13dc67f..3e09a07 100644 (file)
@@ -1,5 +1,12 @@
 #ifndef ___ASM_SPARC_AUXIO_H
 #define ___ASM_SPARC_AUXIO_H
+
+#ifndef __ASSEMBLY__
+
+extern void __iomem *auxio_register;
+
+#endif /* ifndef __ASSEMBLY__ */
+
 #if defined(__sparc__) && defined(__arch64__)
 #include <asm/auxio_64.h>
 #else
index 3a31977..5d685df 100644 (file)
@@ -34,8 +34,8 @@
  * NOTE: these routines are implementation dependent--
  * understand the hardware you are querying!
  */
-extern void set_auxio(unsigned char bits_on, unsigned char bits_off);
-extern unsigned char get_auxio(void); /* .../asm/floppy.h */
+void set_auxio(unsigned char bits_on, unsigned char bits_off);
+unsigned char get_auxio(void); /* .../asm/floppy.h */
 
 /*
  * The following routines are provided for driver-compatibility
@@ -78,7 +78,7 @@ do { \
 
 
 /* AUXIO2 (Power Off Control) */
-extern __volatile__ unsigned char * auxio_power_register;
+extern volatile u8 __iomem *auxio_power_register;
 
 #define        AUXIO_POWER_DETECT_FAILURE      32
 #define        AUXIO_POWER_CLEAR_FAILURE       2
index f61cd1e..6079e59 100644 (file)
@@ -75,8 +75,6 @@
 
 #ifndef __ASSEMBLY__
 
-extern void __iomem *auxio_register;
-
 #define AUXIO_LTE_ON   1
 #define AUXIO_LTE_OFF  0
 
@@ -84,7 +82,7 @@ extern void __iomem *auxio_register;
  *
  * on - AUXIO_LTE_ON or AUXIO_LTE_OFF
  */
-extern void auxio_set_lte(int on);
+void auxio_set_lte(int on);
 
 #define AUXIO_LED_ON   1
 #define AUXIO_LED_OFF  0
@@ -93,7 +91,7 @@ extern void auxio_set_lte(int on);
  *
  * on - AUXIO_LED_ON or AUXIO_LED_OFF
  */
-extern void auxio_set_led(int on);
+void auxio_set_led(int on);
 
 #endif /* ifndef __ASSEMBLY__ */
 
index 297b2f2..9c988bf 100644 (file)
@@ -20,8 +20,8 @@ struct bit_map {
        int num_colors;
 };
 
-extern int bit_map_string_get(struct bit_map *t, int len, int align);
-extern void bit_map_clear(struct bit_map *t, int offset, int len);
-extern void bit_map_init(struct bit_map *t, unsigned long *map, int size);
+int bit_map_string_get(struct bit_map *t, int len, int align);
+void bit_map_clear(struct bit_map *t, int offset, int len);
+void bit_map_init(struct bit_map *t, unsigned long *map, int size);
 
 #endif /* defined(_SPARC_BITEXT_H) */
index 88c9a96..600ed1d 100644 (file)
@@ -18,9 +18,9 @@
 #error only <linux/bitops.h> can be included directly
 #endif
 
-extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
-extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
-extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
+unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
+unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
+unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
 
 /*
  * Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
index f1a051c..2d52240 100644 (file)
 #include <asm/byteorder.h>
 #include <asm/barrier.h>
 
-extern int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
-extern int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
-extern int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
-extern void set_bit(unsigned long nr, volatile unsigned long *addr);
-extern void clear_bit(unsigned long nr, volatile unsigned long *addr);
-extern void change_bit(unsigned long nr, volatile unsigned long *addr);
+int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
+int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
+int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
+void set_bit(unsigned long nr, volatile unsigned long *addr);
+void clear_bit(unsigned long nr, volatile unsigned long *addr);
+void change_bit(unsigned long nr, volatile unsigned long *addr);
 
 #include <asm-generic/bitops/non-atomic.h>
 
@@ -30,8 +30,8 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr);
 
 #ifdef __KERNEL__
 
-extern int ffs(int x);
-extern unsigned long __ffs(unsigned long);
+int ffs(int x);
+unsigned long __ffs(unsigned long);
 
 #include <asm-generic/bitops/ffz.h>
 #include <asm-generic/bitops/sched.h>
@@ -41,10 +41,10 @@ extern unsigned long __ffs(unsigned long);
  * of bits set) of a N-bit word
  */
 
-extern unsigned long __arch_hweight64(__u64 w);
-extern unsigned int __arch_hweight32(unsigned int w);
-extern unsigned int __arch_hweight16(unsigned int w);
-extern unsigned int __arch_hweight8(unsigned int w);
+unsigned long __arch_hweight64(__u64 w);
+unsigned int __arch_hweight32(unsigned int w);
+unsigned int __arch_hweight16(unsigned int w);
+unsigned int __arch_hweight8(unsigned int w);
 
 #include <asm-generic/bitops/const_hweight.h>
 #include <asm-generic/bitops/lock.h>
index 9b2bc6b..75a32b1 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _SPARC_BTEXT_H
 #define _SPARC_BTEXT_H
 
-extern int btext_find_display(void);
+int btext_find_display(void);
 
 #endif /* _SPARC_BTEXT_H */
index 6bd9f43..eaa8f8d 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/compiler.h>
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void do_BUG(const char *file, int line);
+void do_BUG(const char *file, int line);
 #define BUG() do {                                     \
        do_BUG(__FILE__, __LINE__);                     \
        __builtin_trap();                               \
@@ -20,6 +20,6 @@ extern void do_BUG(const char *file, int line);
 #include <asm-generic/bug.h>
 
 struct pt_regs;
-extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
+void __noreturn die_if_kernel(char *str, struct pt_regs *regs);
 
 #endif
index bb014c2..1216400 100644 (file)
@@ -36,7 +36,7 @@
 #define flush_page_for_dma(addr) \
        sparc32_cachetlb_ops->page_for_dma(addr)
 
-extern void sparc_flush_page_to_ram(struct page *page);
+void sparc_flush_page_to_ram(struct page *page);
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 #define flush_dcache_page(page)                        sparc_flush_page_to_ram(page)
@@ -51,8 +51,8 @@ extern void sparc_flush_page_to_ram(struct page *page);
  * way the windows are all clean for the next process and the stack
  * frames are up to date.
  */
-extern void flush_user_windows(void);
-extern void kill_user_windows(void);
-extern void flushw_all(void);
+void flush_user_windows(void);
+void kill_user_windows(void);
+void flushw_all(void);
 
 #endif /* _SPARC_CACHEFLUSH_H */
index 301736d..3896537 100644 (file)
@@ -10,7 +10,7 @@
 /* Cache flush operations. */
 #define flushw_all()   __asm__ __volatile__("flushw")
 
-extern void __flushw_user(void);
+void __flushw_user(void);
 #define flushw_user() __flushw_user()
 
 #define flush_user_windows flushw_user
@@ -30,29 +30,29 @@ extern void __flushw_user(void);
  * use block commit stores (which invalidate icache lines) during
  * module load, so we need this.
  */
-extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void __flush_icache_page(unsigned long);
+void flush_icache_range(unsigned long start, unsigned long end);
+void __flush_icache_page(unsigned long);
 
-extern void __flush_dcache_page(void *addr, int flush_icache);
-extern void flush_dcache_page_impl(struct page *page);
+void __flush_dcache_page(void *addr, int flush_icache);
+void flush_dcache_page_impl(struct page *page);
 #ifdef CONFIG_SMP
-extern void smp_flush_dcache_page_impl(struct page *page, int cpu);
-extern void flush_dcache_page_all(struct mm_struct *mm, struct page *page);
+void smp_flush_dcache_page_impl(struct page *page, int cpu);
+void flush_dcache_page_all(struct mm_struct *mm, struct page *page);
 #else
 #define smp_flush_dcache_page_impl(page,cpu) flush_dcache_page_impl(page)
 #define flush_dcache_page_all(mm,page) flush_dcache_page_impl(page)
 #endif
 
-extern void __flush_dcache_range(unsigned long start, unsigned long end);
+void __flush_dcache_range(unsigned long start, unsigned long end);
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
-extern void flush_dcache_page(struct page *page);
+void flush_dcache_page(struct page *page);
 
 #define flush_icache_page(vma, pg)     do { } while(0)
 #define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
 
-extern void flush_ptrace_access(struct vm_area_struct *, struct page *,
-                               unsigned long uaddr, void *kaddr,
-                               unsigned long len, int write);
+void flush_ptrace_access(struct vm_area_struct *, struct page *,
+                        unsigned long uaddr, void *kaddr,
+                        unsigned long len, int write);
 
 #define copy_to_user_page(vma, page, vaddr, dst, src, len)             \
        do {                                                            \
index 04471dc..426b238 100644 (file)
@@ -29,7 +29,7 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+__wsum csum_partial(const void *buff, int len, __wsum sum);
 
 /* the same as csum_partial, but copies from fs:src while it
  * checksums
@@ -38,7 +38,7 @@ extern __wsum csum_partial(const void *buff, int len, __wsum sum);
  * better 64-bit) boundary
  */
 
-extern unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
+unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
 
 static inline __wsum
 csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
index 2ff81ae..b8779a6 100644 (file)
@@ -29,7 +29,7 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-extern __wsum csum_partial(const void * buff, int len, __wsum sum);
+__wsum csum_partial(const void * buff, int len, __wsum sum);
 
 /* the same as csum_partial, but copies from user space while it
  * checksums
@@ -37,12 +37,12 @@ extern __wsum csum_partial(const void * buff, int len, __wsum sum);
  * here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
-                                             int len, __wsum sum);
+__wsum csum_partial_copy_nocheck(const void *src, void *dst,
+                                int len, __wsum sum);
 
-extern long __csum_partial_copy_from_user(const void __user *src,
-                                         void *dst, int len,
-                                         __wsum sum);
+long __csum_partial_copy_from_user(const void __user *src,
+                                  void *dst, int len,
+                                  __wsum sum);
 
 static inline __wsum
 csum_partial_copy_from_user(const void __user *src,
@@ -59,9 +59,9 @@ csum_partial_copy_from_user(const void __user *src,
  *     Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-extern long __csum_partial_copy_to_user(const void *src,
-                                       void __user *dst, int len,
-                                         __wsum sum);
+long __csum_partial_copy_to_user(const void *src,
+                                void __user *dst, int len,
+                                __wsum sum);
 
 static inline __wsum
 csum_and_copy_to_user(const void *src,
@@ -77,7 +77,7 @@ csum_and_copy_to_user(const void *src,
 /* ihl is always 5 or greater, almost always is 5, and iph is word aligned
  * the majority of the time.
  */
-extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
 
 /* Fold a partial checksum without adding pseudo headers. */
 static inline __sum16 csum_fold(__wsum sum)
@@ -96,9 +96,9 @@ static inline __sum16 csum_fold(__wsum sum)
 }
 
 static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
-                                              unsigned int len,
-                                              unsigned short proto,
-                                              __wsum sum)
+                                       unsigned int len,
+                                       unsigned short proto,
+                                       __wsum sum)
 {
        __asm__ __volatile__(
 "      addcc           %1, %0, %0\n"
@@ -116,9 +116,9 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
  * returns a 16-bit checksum, already complemented
  */
 static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-                                                  unsigned short len,
-                                                  unsigned short proto,
-                                                  __wsum sum)
+                                       unsigned short len,
+                                       unsigned short proto,
+                                       __wsum sum)
 {
        return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
 }
index 1fae1a0..32c29a1 100644 (file)
@@ -20,7 +20,7 @@ static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned lon
        return val;
 }
 
-extern void __xchg_called_with_bad_pointer(void);
+void __xchg_called_with_bad_pointer(void);
 
 static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
 {
@@ -45,9 +45,9 @@ static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int
 #define __HAVE_ARCH_CMPXCHG    1
 
 /* bug catcher for when unsupported size is used - won't link */
-extern void __cmpxchg_called_with_bad_pointer(void);
+void __cmpxchg_called_with_bad_pointer(void);
 /* we only need to support cmpxchg of a u32 on sparc */
-extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
 
 /* don't worry...optimizer will get rid of most of this */
 static inline unsigned long
index 4adefe8..0e1ed6c 100644 (file)
@@ -42,7 +42,7 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long
 
 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 
-extern void __xchg_called_with_bad_pointer(void);
+void __xchg_called_with_bad_pointer(void);
 
 static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
                                       int size)
@@ -91,7 +91,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
 
 /* This function doesn't exist, so you'll get a linker error
    if something tries to do an invalid cmpxchg().  */
-extern void __cmpxchg_called_with_bad_pointer(void);
+void __cmpxchg_called_with_bad_pointer(void);
 
 static inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
index b5976de..128b56b 100644 (file)
@@ -1,5 +1,15 @@
 #ifndef ___ASM_SPARC_CPUDATA_H
 #define ___ASM_SPARC_CPUDATA_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/threads.h>
+#include <linux/percpu.h>
+
+extern const struct seq_operations cpuinfo_op;
+
+#endif /* !(__ASSEMBLY__) */
+
 #if defined(__sparc__) && defined(__arch64__)
 #include <asm/cpudata_64.h>
 #else
index 050ef35..0e59407 100644 (file)
@@ -8,9 +8,6 @@
 
 #ifndef __ASSEMBLY__
 
-#include <linux/percpu.h>
-#include <linux/threads.h>
-
 typedef struct {
        /* Dcache line 1 */
        unsigned int    __softirq_pending; /* must be 1st, see rtrap.S */
@@ -35,8 +32,6 @@ DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
 #define cpu_data(__cpu)                per_cpu(__cpu_data, (__cpu))
 #define local_cpu_data()       __get_cpu_var(__cpu_data)
 
-extern const struct seq_operations cpuinfo_op;
-
 #endif /* !(__ASSEMBLY__) */
 
 #include <asm/trap_block.h>
index bc9aba2..3fb8ca1 100644 (file)
@@ -20,8 +20,8 @@ static inline void __delay(unsigned long loops)
 }
 
 /* This is too messy with inline asm on the Sparc. */
-extern void __udelay(unsigned long usecs, unsigned long lpj);
-extern void __ndelay(unsigned long nsecs, unsigned long lpj);
+void __udelay(unsigned long usecs, unsigned long lpj);
+void __ndelay(unsigned long nsecs, unsigned long lpj);
 
 #ifdef CONFIG_SMP
 #define __udelay_val   cpu_data(smp_processor_id()).udelay_val
index a77aa62..0ba5424 100644 (file)
@@ -8,8 +8,8 @@
 
 #ifndef __ASSEMBLY__
 
-extern void __delay(unsigned long loops);
-extern void udelay(unsigned long usecs);
+void __delay(unsigned long loops);
+void udelay(unsigned long usecs);
 #define mdelay(n)      udelay((n) * 1000)
 
 #endif /* !__ASSEMBLY__ */
index daa6a8a..bb3f0b0 100644 (file)
@@ -19,7 +19,7 @@ struct dev_archdata {
        int                     numa_node;
 };
 
-extern void of_propagate_archdata(struct platform_device *bus);
+void of_propagate_archdata(struct platform_device *bus);
 
 struct pdev_archdata {
        struct resource         resource[PROMREG_MAX];
index 05fe53f..1ee0271 100644 (file)
@@ -7,7 +7,7 @@
 
 #define DMA_ERROR_CODE (~(dma_addr_t)0x0)
 
-extern int dma_supported(struct device *dev, u64 mask);
+int dma_supported(struct device *dev, u64 mask);
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
index f07a5b5..fcfb494 100644 (file)
@@ -22,14 +22,14 @@ struct ebus_dma_info {
        unsigned char   name[64];
 };
 
-extern int ebus_dma_register(struct ebus_dma_info *p);
-extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
-extern void ebus_dma_unregister(struct ebus_dma_info *p);
-extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
+int ebus_dma_register(struct ebus_dma_info *p);
+int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
+void ebus_dma_unregister(struct ebus_dma_info *p);
+int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
                            size_t len);
-extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
-extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
-extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
-extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
+void ebus_dma_prepare(struct ebus_dma_info *p, int write);
+unsigned int ebus_dma_residue(struct ebus_dma_info *p);
+unsigned int ebus_dma_addr(struct ebus_dma_info *p);
+void ebus_dma_enable(struct ebus_dma_info *p, int on);
 
 #endif /* __ASM_SPARC_EBUS_DMA_H */
index fb3f169..071b83e 100644 (file)
@@ -9,11 +9,12 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/idprom.h>
 #include <asm/oplib.h>
 #include <asm/auxio.h>
+#include <asm/setup.h>
+#include <asm/page.h>
 #include <asm/irq.h>
 
 /* We don't need no stinkin' I/O port allocation crap. */
@@ -49,7 +50,6 @@ struct sun_flpy_controller {
 
 /* You'll only ever find one controller on a SparcStation anyways. */
 static struct sun_flpy_controller *sun_fdc = NULL;
-extern volatile unsigned char *fdc_status;
 
 struct sun_floppy_ops {
        unsigned char (*fd_inb)(int port);
@@ -212,13 +212,6 @@ static void sun_82077_fd_outb(unsigned char value, int port)
  * underruns.  If non-zero, doing_pdma encodes the direction of
  * the transfer for debugging.  1=read 2=write
  */
-extern char *pdma_vaddr;
-extern unsigned long pdma_size;
-extern volatile int doing_pdma;
-
-/* This is software state */
-extern char *pdma_base;
-extern unsigned long pdma_areasize;
 
 /* Common routines to all controller types on the Sparc. */
 static inline void virtual_dma_init(void)
@@ -263,8 +256,7 @@ static inline void sun_fd_enable_dma(void)
        pdma_areasize = pdma_size;
 }
 
-extern int sparc_floppy_request_irq(unsigned int irq,
-                                    irq_handler_t irq_handler);
+int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler);
 
 static int sun_fd_request_irq(void)
 {
index 7c90c50..6257564 100644 (file)
@@ -296,7 +296,7 @@ struct sun_pci_dma_op {
 static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
 static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
 
-extern irqreturn_t floppy_interrupt(int irq, void *dev_id);
+irqreturn_t floppy_interrupt(int irq, void *dev_id);
 
 static unsigned char sun_pci_fd_inb(unsigned long port)
 {
index b0f18e9..9ec94ad 100644 (file)
@@ -6,7 +6,7 @@
 #define MCOUNT_INSN_SIZE       4 /* sizeof mcount call */
 
 #ifndef __ASSEMBLY__
-extern void _mcount(void);
+void _mcount(void);
 #endif
 
 #endif
@@ -22,4 +22,8 @@ struct dyn_arch_ftrace {
 };
 #endif /*  CONFIG_DYNAMIC_FTRACE */
 
+unsigned long prepare_ftrace_return(unsigned long parent,
+                                   unsigned long self_addr,
+                                   unsigned long frame_pointer);
+
 #endif /* _ASM_SPARC64_FTRACE */
index 4f9e15c..92ded29 100644 (file)
@@ -31,7 +31,7 @@ extern unsigned long highstart_pfn, highend_pfn;
 extern pgprot_t kmap_prot;
 extern pte_t *pkmap_page_table;
 
-extern void kmap_init(void) __init;
+void kmap_init(void) __init;
 
 /*
  * Right now we initialize only a single pte table. It can be extended
@@ -49,8 +49,8 @@ extern void kmap_init(void) __init;
 
 #define PKMAP_END (PKMAP_ADDR(LAST_PKMAP))
 
-extern void *kmap_high(struct page *page);
-extern void kunmap_high(struct page *page);
+void *kmap_high(struct page *page);
+void kunmap_high(struct page *page);
 
 static inline void *kmap(struct page *page)
 {
@@ -68,8 +68,8 @@ static inline void kunmap(struct page *page)
        kunmap_high(page);
 }
 
-extern void *kmap_atomic(struct page *page);
-extern void __kunmap_atomic(void *kvaddr);
+void *kmap_atomic(struct page *page);
+void __kunmap_atomic(void *kvaddr);
 
 #define flush_cache_kmaps()    flush_cache_all()
 
index b2b9b94..04b56f8 100644 (file)
@@ -19,7 +19,7 @@ struct hvtramp_descr {
        struct hvtramp_mapping  maps[1];
 };
 
-extern void hv_cpu_startup(unsigned long hvdescr_pa);
+void hv_cpu_startup(unsigned long hvdescr_pa);
 
 #endif
 
index ca121f0..94b39ca 100644 (file)
@@ -98,7 +98,7 @@
 #define HV_FAST_MACH_EXIT              0x00
 
 #ifndef __ASSEMBLY__
-extern void sun4v_mach_exit(unsigned long exit_code);
+void sun4v_mach_exit(unsigned long exit_code);
 #endif
 
 /* Domain services.  */
@@ -127,9 +127,9 @@ extern void sun4v_mach_exit(unsigned long exit_code);
 #define HV_FAST_MACH_DESC              0x01
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
-                                    unsigned long buf_len,
-                                    unsigned long *real_buf_len);
+unsigned long sun4v_mach_desc(unsigned long buffer_pa,
+                             unsigned long buf_len,
+                             unsigned long *real_buf_len);
 #endif
 
 /* mach_sir()
@@ -148,7 +148,7 @@ extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
 #define HV_FAST_MACH_SIR               0x02
 
 #ifndef __ASSEMBLY__
-extern void sun4v_mach_sir(void);
+void sun4v_mach_sir(void);
 #endif
 
 /* mach_set_watchdog()
@@ -204,8 +204,8 @@ extern void sun4v_mach_sir(void);
 #define HV_FAST_MACH_SET_WATCHDOG      0x05
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
-                                            unsigned long *orig_timeout);
+unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
+                                     unsigned long *orig_timeout);
 #endif
 
 /* CPU services.
@@ -250,10 +250,10 @@ extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
 #define HV_FAST_CPU_START              0x10
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_start(unsigned long cpuid,
-                                    unsigned long pc,
-                                    unsigned long rtba,
-                                    unsigned long arg0);
+unsigned long sun4v_cpu_start(unsigned long cpuid,
+                             unsigned long pc,
+                             unsigned long rtba,
+                             unsigned long arg0);
 #endif
 
 /* cpu_stop()
@@ -278,7 +278,7 @@ extern unsigned long sun4v_cpu_start(unsigned long cpuid,
 #define HV_FAST_CPU_STOP               0x11
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
+unsigned long sun4v_cpu_stop(unsigned long cpuid);
 #endif
 
 /* cpu_yield()
@@ -295,7 +295,7 @@ extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
 #define HV_FAST_CPU_YIELD              0x12
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_yield(void);
+unsigned long sun4v_cpu_yield(void);
 #endif
 
 /* cpu_qconf()
@@ -341,9 +341,9 @@ extern unsigned long sun4v_cpu_yield(void);
 #define  HV_CPU_QUEUE_NONRES_ERROR      0x3f
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_qconf(unsigned long type,
-                                    unsigned long queue_paddr,
-                                    unsigned long num_queue_entries);
+unsigned long sun4v_cpu_qconf(unsigned long type,
+                             unsigned long queue_paddr,
+                             unsigned long num_queue_entries);
 #endif
 
 /* cpu_qinfo()
@@ -394,7 +394,9 @@ extern unsigned long sun4v_cpu_qconf(unsigned long type,
 #define HV_FAST_CPU_MONDO_SEND         0x42
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count, unsigned long cpu_list_pa, unsigned long mondo_block_pa);
+unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count,
+                                  unsigned long cpu_list_pa,
+                                  unsigned long mondo_block_pa);
 #endif
 
 /* cpu_myid()
@@ -425,7 +427,7 @@ extern unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count, unsigned long
 #define  HV_CPU_STATE_ERROR             0x03
 
 #ifndef __ASSEMBLY__
-extern long sun4v_cpu_state(unsigned long cpuid);
+long sun4v_cpu_state(unsigned long cpuid);
 #endif
 
 /* cpu_set_rtba()
@@ -625,8 +627,8 @@ struct hv_fault_status {
 #define HV_FAST_MMU_TSB_CTX0           0x20
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
-                                       unsigned long tsb_desc_ra);
+unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
+                                unsigned long tsb_desc_ra);
 #endif
 
 /* mmu_tsb_ctxnon0()
@@ -710,7 +712,7 @@ extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
 #define HV_FAST_MMU_DEMAP_ALL          0x24
 
 #ifndef __ASSEMBLY__
-extern void sun4v_mmu_demap_all(void);
+void sun4v_mmu_demap_all(void);
 #endif
 
 /* mmu_map_perm_addr()
@@ -740,10 +742,10 @@ extern void sun4v_mmu_demap_all(void);
 #define HV_FAST_MMU_MAP_PERM_ADDR      0x25
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
-                                            unsigned long set_to_zero,
-                                            unsigned long tte,
-                                            unsigned long flags);
+unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
+                                     unsigned long set_to_zero,
+                                     unsigned long tte,
+                                     unsigned long flags);
 #endif
 
 /* mmu_fault_area_conf()
@@ -945,7 +947,7 @@ extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
 #define HV_FAST_TOD_GET                        0x50
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_tod_get(unsigned long *time);
+unsigned long sun4v_tod_get(unsigned long *time);
 #endif
 
 /* tod_set()
@@ -962,7 +964,7 @@ extern unsigned long sun4v_tod_get(unsigned long *time);
 #define HV_FAST_TOD_SET                        0x51
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_tod_set(unsigned long time);
+unsigned long sun4v_tod_set(unsigned long time);
 #endif
 
 /* Console services */
@@ -1038,14 +1040,14 @@ extern unsigned long sun4v_tod_set(unsigned long time);
 #define HV_FAST_CONS_WRITE             0x63
 
 #ifndef __ASSEMBLY__
-extern long sun4v_con_getchar(long *status);
-extern long sun4v_con_putchar(long c);
-extern long sun4v_con_read(unsigned long buffer,
-                          unsigned long size,
-                          unsigned long *bytes_read);
-extern unsigned long sun4v_con_write(unsigned long buffer,
-                                    unsigned long size,
-                                    unsigned long *bytes_written);
+long sun4v_con_getchar(long *status);
+long sun4v_con_putchar(long c);
+long sun4v_con_read(unsigned long buffer,
+                   unsigned long size,
+                   unsigned long *bytes_read);
+unsigned long sun4v_con_write(unsigned long buffer,
+                             unsigned long size,
+                             unsigned long *bytes_written);
 #endif
 
 /* mach_set_soft_state()
@@ -1080,8 +1082,8 @@ extern unsigned long sun4v_con_write(unsigned long buffer,
 #define  HV_SOFT_STATE_TRANSITION       0x02
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
-                                              unsigned long msg_string_ra);
+unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
+                                       unsigned long msg_string_ra);
 #endif
 
 /* mach_get_soft_state()
@@ -1159,20 +1161,20 @@ extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
 #define HV_FAST_SVC_CLRSTATUS          0x84
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_svc_send(unsigned long svc_id,
-                                   unsigned long buffer,
-                                   unsigned long buffer_size,
-                                   unsigned long *sent_bytes);
-extern unsigned long sun4v_svc_recv(unsigned long svc_id,
-                                   unsigned long buffer,
-                                   unsigned long buffer_size,
-                                   unsigned long *recv_bytes);
-extern unsigned long sun4v_svc_getstatus(unsigned long svc_id,
-                                        unsigned long *status_bits);
-extern unsigned long sun4v_svc_setstatus(unsigned long svc_id,
-                                        unsigned long status_bits);
-extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
-                                        unsigned long status_bits);
+unsigned long sun4v_svc_send(unsigned long svc_id,
+                            unsigned long buffer,
+                            unsigned long buffer_size,
+                            unsigned long *sent_bytes);
+unsigned long sun4v_svc_recv(unsigned long svc_id,
+                            unsigned long buffer,
+                            unsigned long buffer_size,
+                            unsigned long *recv_bytes);
+unsigned long sun4v_svc_getstatus(unsigned long svc_id,
+                                 unsigned long *status_bits);
+unsigned long sun4v_svc_setstatus(unsigned long svc_id,
+                                 unsigned long status_bits);
+unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
+                                 unsigned long status_bits);
 #endif
 
 /* Trap trace services.
@@ -1458,8 +1460,8 @@ struct hv_trap_trace_entry {
 #define HV_FAST_INTR_DEVINO2SYSINO     0xa0
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle,
-                                           unsigned long devino);
+unsigned long sun4v_devino_to_sysino(unsigned long devhandle,
+                                    unsigned long devino);
 #endif
 
 /* intr_getenabled()
@@ -1476,7 +1478,7 @@ extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle,
 #define HV_FAST_INTR_GETENABLED                0xa1
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_getenabled(unsigned long sysino);
+unsigned long sun4v_intr_getenabled(unsigned long sysino);
 #endif
 
 /* intr_setenabled()
@@ -1492,7 +1494,8 @@ extern unsigned long sun4v_intr_getenabled(unsigned long sysino);
 #define HV_FAST_INTR_SETENABLED                0xa2
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled);
+unsigned long sun4v_intr_setenabled(unsigned long sysino,
+                                   unsigned long intr_enabled);
 #endif
 
 /* intr_getstate()
@@ -1508,7 +1511,7 @@ extern unsigned long sun4v_intr_setenabled(unsigned long sysino, unsigned long i
 #define HV_FAST_INTR_GETSTATE          0xa3
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_getstate(unsigned long sysino);
+unsigned long sun4v_intr_getstate(unsigned long sysino);
 #endif
 
 /* intr_setstate()
@@ -1528,7 +1531,7 @@ extern unsigned long sun4v_intr_getstate(unsigned long sysino);
 #define HV_FAST_INTR_SETSTATE          0xa4
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state);
+unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state);
 #endif
 
 /* intr_gettarget()
@@ -1546,7 +1549,7 @@ extern unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long int
 #define HV_FAST_INTR_GETTARGET         0xa5
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_gettarget(unsigned long sysino);
+unsigned long sun4v_intr_gettarget(unsigned long sysino);
 #endif
 
 /* intr_settarget()
@@ -1563,7 +1566,7 @@ extern unsigned long sun4v_intr_gettarget(unsigned long sysino);
 #define HV_FAST_INTR_SETTARGET         0xa6
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
+unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
 #endif
 
 /* vintr_get_cookie()
@@ -1647,30 +1650,30 @@ extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cp
 #define HV_FAST_VINTR_SET_TARGET       0xae
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long *cookie);
-extern unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long cookie);
-extern unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long *valid);
-extern unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long valid);
-extern unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long *state);
-extern unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long state);
-extern unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long *cpuid);
-extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long cpuid);
+unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
+                                    unsigned long dev_ino,
+                                    unsigned long *cookie);
+unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
+                                    unsigned long dev_ino,
+                                    unsigned long cookie);
+unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
+                                   unsigned long dev_ino,
+                                   unsigned long *valid);
+unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
+                                   unsigned long dev_ino,
+                                   unsigned long valid);
+unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
+                                   unsigned long dev_ino,
+                                   unsigned long *state);
+unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
+                                   unsigned long dev_ino,
+                                   unsigned long state);
+unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
+                                    unsigned long dev_ino,
+                                    unsigned long *cpuid);
+unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
+                                    unsigned long dev_ino,
+                                    unsigned long cpuid);
 #endif
 
 /* PCI IO services.
@@ -2627,50 +2630,50 @@ struct ldc_mtable_entry {
 #define HV_FAST_LDC_REVOKE             0xef
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
-                                       unsigned long ra,
-                                       unsigned long num_entries);
-extern unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
-                                       unsigned long *ra,
-                                       unsigned long *num_entries);
-extern unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
-                                           unsigned long *head_off,
-                                           unsigned long *tail_off,
-                                           unsigned long *chan_state);
-extern unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
-                                           unsigned long tail_off);
-extern unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
-                                       unsigned long ra,
-                                       unsigned long num_entries);
-extern unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
-                                       unsigned long *ra,
-                                       unsigned long *num_entries);
-extern unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
-                                           unsigned long *head_off,
-                                           unsigned long *tail_off,
-                                           unsigned long *chan_state);
-extern unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
-                                           unsigned long head_off);
-extern unsigned long sun4v_ldc_set_map_table(unsigned long channel,
-                                            unsigned long ra,
-                                            unsigned long num_entries);
-extern unsigned long sun4v_ldc_get_map_table(unsigned long channel,
-                                            unsigned long *ra,
-                                            unsigned long *num_entries);
-extern unsigned long sun4v_ldc_copy(unsigned long channel,
-                                   unsigned long dir_code,
-                                   unsigned long tgt_raddr,
-                                   unsigned long lcl_raddr,
-                                   unsigned long len,
-                                   unsigned long *actual_len);
-extern unsigned long sun4v_ldc_mapin(unsigned long channel,
-                                    unsigned long cookie,
-                                    unsigned long *ra,
-                                    unsigned long *perm);
-extern unsigned long sun4v_ldc_unmap(unsigned long ra);
-extern unsigned long sun4v_ldc_revoke(unsigned long channel,
-                                     unsigned long cookie,
-                                     unsigned long mte_cookie);
+unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
+                                unsigned long ra,
+                                unsigned long num_entries);
+unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
+                                unsigned long *ra,
+                                unsigned long *num_entries);
+unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
+                                    unsigned long *head_off,
+                                    unsigned long *tail_off,
+                                    unsigned long *chan_state);
+unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
+                                    unsigned long tail_off);
+unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
+                                unsigned long ra,
+                                unsigned long num_entries);
+unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
+                                unsigned long *ra,
+                                unsigned long *num_entries);
+unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
+                                    unsigned long *head_off,
+                                    unsigned long *tail_off,
+                                    unsigned long *chan_state);
+unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
+                                    unsigned long head_off);
+unsigned long sun4v_ldc_set_map_table(unsigned long channel,
+                                     unsigned long ra,
+                                     unsigned long num_entries);
+unsigned long sun4v_ldc_get_map_table(unsigned long channel,
+                                     unsigned long *ra,
+                                     unsigned long *num_entries);
+unsigned long sun4v_ldc_copy(unsigned long channel,
+                            unsigned long dir_code,
+                            unsigned long tgt_raddr,
+                            unsigned long lcl_raddr,
+                            unsigned long len,
+                            unsigned long *actual_len);
+unsigned long sun4v_ldc_mapin(unsigned long channel,
+                             unsigned long cookie,
+                             unsigned long *ra,
+                             unsigned long *perm);
+unsigned long sun4v_ldc_unmap(unsigned long ra);
+unsigned long sun4v_ldc_revoke(unsigned long channel,
+                              unsigned long cookie,
+                              unsigned long mte_cookie);
 #endif
 
 /* Performance counter services.  */
@@ -2727,14 +2730,14 @@ extern unsigned long sun4v_ldc_revoke(unsigned long channel,
 #define HV_FAST_N2_SET_PERFREG         0x105
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_niagara_getperf(unsigned long reg,
-                                          unsigned long *val);
-extern unsigned long sun4v_niagara_setperf(unsigned long reg,
-                                          unsigned long val);
-extern unsigned long sun4v_niagara2_getperf(unsigned long reg,
-                                           unsigned long *val);
-extern unsigned long sun4v_niagara2_setperf(unsigned long reg,
-                                           unsigned long val);
+unsigned long sun4v_niagara_getperf(unsigned long reg,
+                                   unsigned long *val);
+unsigned long sun4v_niagara_setperf(unsigned long reg,
+                                   unsigned long val);
+unsigned long sun4v_niagara2_getperf(unsigned long reg,
+                                    unsigned long *val);
+unsigned long sun4v_niagara2_setperf(unsigned long reg,
+                                    unsigned long val);
 #endif
 
 /* MMU statistics services.
@@ -2829,8 +2832,8 @@ struct hv_mmu_statistics {
 #define HV_FAST_MMUSTAT_INFO           0x103
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
-extern unsigned long sun4v_mmustat_info(unsigned long *ra);
+unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
+unsigned long sun4v_mmustat_info(unsigned long *ra);
 #endif
 
 /* NCS crypto services  */
@@ -2919,9 +2922,9 @@ struct hv_ncs_qtail_update_arg {
 #define HV_FAST_NCS_REQUEST            0x110
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_ncs_request(unsigned long request,
-                                      unsigned long arg_ra,
-                                      unsigned long arg_size);
+unsigned long sun4v_ncs_request(unsigned long request,
+                               unsigned long arg_ra,
+                               unsigned long arg_size);
 #endif
 
 #define HV_FAST_FIRE_GET_PERFREG       0x120
@@ -2930,18 +2933,18 @@ extern unsigned long sun4v_ncs_request(unsigned long request,
 #define HV_FAST_REBOOT_DATA_SET                0x172
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_reboot_data_set(unsigned long ra,
-                                          unsigned long len);
+unsigned long sun4v_reboot_data_set(unsigned long ra,
+                                   unsigned long len);
 #endif
 
 #define HV_FAST_VT_GET_PERFREG         0x184
 #define HV_FAST_VT_SET_PERFREG         0x185
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_vt_get_perfreg(unsigned long reg_num,
-                                         unsigned long *reg_val);
-extern unsigned long sun4v_vt_set_perfreg(unsigned long reg_num,
-                                         unsigned long reg_val);
+unsigned long sun4v_vt_get_perfreg(unsigned long reg_num,
+                                  unsigned long *reg_val);
+unsigned long sun4v_vt_set_perfreg(unsigned long reg_num,
+                                  unsigned long reg_val);
 #endif
 
 /* Function numbers for HV_CORE_TRAP.  */
@@ -2978,21 +2981,21 @@ extern unsigned long sun4v_vt_set_perfreg(unsigned long reg_num,
 #define HV_GRP_DIAG                    0x0300
 
 #ifndef __ASSEMBLY__
-extern unsigned long sun4v_get_version(unsigned long group,
-                                      unsigned long *major,
-                                      unsigned long *minor);
-extern unsigned long sun4v_set_version(unsigned long group,
-                                      unsigned long major,
-                                      unsigned long minor,
-                                      unsigned long *actual_minor);
-
-extern int sun4v_hvapi_register(unsigned long group, unsigned long major,
-                               unsigned long *minor);
-extern void sun4v_hvapi_unregister(unsigned long group);
-extern int sun4v_hvapi_get(unsigned long group,
-                          unsigned long *major,
-                          unsigned long *minor);
-extern void sun4v_hvapi_init(void);
+unsigned long sun4v_get_version(unsigned long group,
+                               unsigned long *major,
+                               unsigned long *minor);
+unsigned long sun4v_set_version(unsigned long group,
+                               unsigned long major,
+                               unsigned long minor,
+                               unsigned long *actual_minor);
+
+int sun4v_hvapi_register(unsigned long group, unsigned long major,
+                        unsigned long *minor);
+void sun4v_hvapi_unregister(unsigned long group);
+int sun4v_hvapi_get(unsigned long group,
+                   unsigned long *major,
+                   unsigned long *minor);
+void sun4v_hvapi_init(void);
 #endif
 
 #endif /* !(_SPARC64_HYPERVISOR_H) */
index 6976aa2..3793f7f 100644 (file)
@@ -20,6 +20,6 @@ struct idprom {
 };
 
 extern struct idprom *idprom;
-extern void idprom_init(void);
+void idprom_init(void);
 
 #endif /* !(_SPARC_IDPROM_H) */
index 01ab2f6..04a9701 100644 (file)
@@ -43,7 +43,7 @@
 struct iounit_struct {
        unsigned long           bmap[(IOUNIT_DMA_SIZE >> (PAGE_SHIFT + 3)) / sizeof(unsigned long)];
        spinlock_t              lock;
-       iopte_t                 *page_table;
+       iopte_t __iomem         *page_table;
        unsigned long           rotor[3];
        unsigned long           limit[4];
 };
index c1acbd8..9f53290 100644 (file)
 #define __SPARC_IO_H
 
 #include <linux/kernel.h>
-#include <linux/types.h>
 #include <linux/ioport.h>  /* struct resource */
 
-#include <asm/page.h>      /* IO address mapping routines need this */
-#include <asm-generic/pci_iomap.h>
-
-#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
-
-static inline u32 flip_dword (u32 l)
-{
-       return ((l&0xff)<<24) | (((l>>8)&0xff)<<16) | (((l>>16)&0xff)<<8)| ((l>>24)&0xff);
-}
-
-static inline u16 flip_word (u16 w)
-{
-       return ((w&0xff) << 8) | ((w>>8)&0xff);
-}
-
-#define mmiowb()
-
-/*
- * Memory mapped I/O to PCI
- */
-
-static inline u8 __raw_readb(const volatile void __iomem *addr)
-{
-       return *(__force volatile u8 *)addr;
-}
-
-static inline u16 __raw_readw(const volatile void __iomem *addr)
-{
-       return *(__force volatile u16 *)addr;
-}
-
-static inline u32 __raw_readl(const volatile void __iomem *addr)
-{
-       return *(__force volatile u32 *)addr;
-}
+#define readb_relaxed(__addr)  readb(__addr)
+#define readw_relaxed(__addr)  readw(__addr)
+#define readl_relaxed(__addr)  readl(__addr)
 
-static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
-{
-       *(__force volatile u8 *)addr = b;
-}
+#define IO_SPACE_LIMIT 0xffffffff
 
-static inline void __raw_writew(u16 w, volatile void __iomem *addr)
-{
-       *(__force volatile u16 *)addr = w;
-}
+#define memset_io(d,c,sz)     _memset_io(d,c,sz)
+#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
+#define memcpy_toio(d,s,sz)   _memcpy_toio(d,s,sz)
 
-static inline void __raw_writel(u32 l, volatile void __iomem *addr)
-{
-       *(__force volatile u32 *)addr = l;
-}
+#include <asm-generic/io.h>
 
-static inline u8 __readb(const volatile void __iomem *addr)
+static inline void _memset_io(volatile void __iomem *dst,
+                              int c, __kernel_size_t n)
 {
-       return *(__force volatile u8 *)addr;
-}
+       volatile void __iomem *d = dst;
 
-static inline u16 __readw(const volatile void __iomem *addr)
-{
-       return flip_word(*(__force volatile u16 *)addr);
+       while (n--) {
+               writeb(c, d);
+               d++;
+       }
 }
 
-static inline u32 __readl(const volatile void __iomem *addr)
+static inline void _memcpy_fromio(void *dst, const volatile void __iomem *src,
+                                  __kernel_size_t n)
 {
-       return flip_dword(*(__force volatile u32 *)addr);
-}
+       char *d = dst;
 
-static inline void __writeb(u8 b, volatile void __iomem *addr)
-{
-       *(__force volatile u8 *)addr = b;
+       while (n--) {
+               char tmp = readb(src);
+               *d++ = tmp;
+               src++;
+       }
 }
 
-static inline void __writew(u16 w, volatile void __iomem *addr)
+static inline void _memcpy_toio(volatile void __iomem *dst, const void *src,
+                                __kernel_size_t n)
 {
-       *(__force volatile u16 *)addr = flip_word(w);
-}
+       const char *s = src;
+       volatile void __iomem *d = dst;
 
-static inline void __writel(u32 l, volatile void __iomem *addr)
-{
-       *(__force volatile u32 *)addr = flip_dword(l);
+       while (n--) {
+               char tmp = *s++;
+               writeb(tmp, d);
+               d++;
+       }
 }
 
-#define readb(__addr)          __readb(__addr)
-#define readw(__addr)          __readw(__addr)
-#define readl(__addr)          __readl(__addr)
-#define readb_relaxed(__addr)  readb(__addr)
-#define readw_relaxed(__addr)  readw(__addr)
-#define readl_relaxed(__addr)  readl(__addr)
-
-#define writeb(__b, __addr)    __writeb((__b),(__addr))
-#define writew(__w, __addr)    __writew((__w),(__addr))
-#define writel(__l, __addr)    __writel((__l),(__addr))
-
-/*
- * I/O space operations
- *
- * Arrangement on a Sun is somewhat complicated.
- *
- * First of all, we want to use standard Linux drivers
- * for keyboard, PC serial, etc. These drivers think
- * they access I/O space and use inb/outb.
- * On the other hand, EBus bridge accepts PCI *memory*
- * cycles and converts them into ISA *I/O* cycles.
- * Ergo, we want inb & outb to generate PCI memory cycles.
- *
- * If we want to issue PCI *I/O* cycles, we do this
- * with a low 64K fixed window in PCIC. This window gets
- * mapped somewhere into virtual kernel space and we
- * can use inb/outb again.
- */
-#define inb_local(__addr)      __readb((void __iomem *)(unsigned long)(__addr))
-#define inb(__addr)            __readb((void __iomem *)(unsigned long)(__addr))
-#define inw(__addr)            __readw((void __iomem *)(unsigned long)(__addr))
-#define inl(__addr)            __readl((void __iomem *)(unsigned long)(__addr))
-
-#define outb_local(__b, __addr)        __writeb(__b, (void __iomem *)(unsigned long)(__addr))
-#define outb(__b, __addr)      __writeb(__b, (void __iomem *)(unsigned long)(__addr))
-#define outw(__w, __addr)      __writew(__w, (void __iomem *)(unsigned long)(__addr))
-#define outl(__l, __addr)      __writel(__l, (void __iomem *)(unsigned long)(__addr))
-
-#define inb_p(__addr)          inb(__addr)
-#define outb_p(__b, __addr)    outb(__b, __addr)
-#define inw_p(__addr)          inw(__addr)
-#define outw_p(__w, __addr)    outw(__w, __addr)
-#define inl_p(__addr)          inl(__addr)
-#define outl_p(__l, __addr)    outl(__l, __addr)
-
-void outsb(unsigned long addr, const void *src, unsigned long cnt);
-void outsw(unsigned long addr, const void *src, unsigned long cnt);
-void outsl(unsigned long addr, const void *src, unsigned long cnt);
-void insb(unsigned long addr, void *dst, unsigned long count);
-void insw(unsigned long addr, void *dst, unsigned long count);
-void insl(unsigned long addr, void *dst, unsigned long count);
-
-#define IO_SPACE_LIMIT 0xffffffff
-
 /*
  * SBus accessors.
  *
  * SBus has only one, memory mapped, I/O space.
  * We do not need to flip bytes for SBus of course.
  */
-static inline u8 _sbus_readb(const volatile void __iomem *addr)
+static inline u8 sbus_readb(const volatile void __iomem *addr)
 {
        return *(__force volatile u8 *)addr;
 }
 
-static inline u16 _sbus_readw(const volatile void __iomem *addr)
+static inline u16 sbus_readw(const volatile void __iomem *addr)
 {
        return *(__force volatile u16 *)addr;
 }
 
-static inline u32 _sbus_readl(const volatile void __iomem *addr)
+static inline u32 sbus_readl(const volatile void __iomem *addr)
 {
        return *(__force volatile u32 *)addr;
 }
 
-static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
+static inline void sbus_writeb(u8 b, volatile void __iomem *addr)
 {
        *(__force volatile u8 *)addr = b;
 }
 
-static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
+static inline void sbus_writew(u16 w, volatile void __iomem *addr)
 {
        *(__force volatile u16 *)addr = w;
 }
 
-static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
+static inline void sbus_writel(u32 l, volatile void __iomem *addr)
 {
        *(__force volatile u32 *)addr = l;
 }
 
-/*
- * The only reason for #define's is to hide casts to unsigned long.
- */
-#define sbus_readb(__addr)             _sbus_readb(__addr)
-#define sbus_readw(__addr)             _sbus_readw(__addr)
-#define sbus_readl(__addr)             _sbus_readl(__addr)
-#define sbus_writeb(__b, __addr)       _sbus_writeb(__b, __addr)
-#define sbus_writew(__w, __addr)       _sbus_writew(__w, __addr)
-#define sbus_writel(__l, __addr)       _sbus_writel(__l, __addr)
-
-static inline void sbus_memset_io(volatile void __iomem *__dst, int c, __kernel_size_t n)
+static inline void sbus_memset_io(volatile void __iomem *__dst, int c,
+                                  __kernel_size_t n)
 {
        while(n--) {
                sbus_writeb(c, __dst);
@@ -194,22 +97,9 @@ static inline void sbus_memset_io(volatile void __iomem *__dst, int c, __kernel_
        }
 }
 
-static inline void
-_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
-{
-       volatile void __iomem *d = dst;
-
-       while (n--) {
-               writeb(c, d);
-               d++;
-       }
-}
-
-#define memset_io(d,c,sz)      _memset_io(d,c,sz)
-
-static inline void
-_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
-                   __kernel_size_t n)
+static inline void sbus_memcpy_fromio(void *dst,
+                                      const volatile void __iomem *src,
+                                      __kernel_size_t n)
 {
        char *d = dst;
 
@@ -220,25 +110,9 @@ _sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
        }
 }
 
-#define sbus_memcpy_fromio(d, s, sz)   _sbus_memcpy_fromio(d, s, sz)
-
-static inline void
-_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
-{
-       char *d = dst;
-
-       while (n--) {
-               char tmp = readb(src);
-               *d++ = tmp;
-               src++;
-       }
-}
-
-#define memcpy_fromio(d,s,sz)  _memcpy_fromio(d,s,sz)
-
-static inline void
-_sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
-                 __kernel_size_t n)
+static inline void sbus_memcpy_toio(volatile void __iomem *dst,
+                                    const void *src,
+                                    __kernel_size_t n)
 {
        const char *s = src;
        volatile void __iomem *d = dst;
@@ -250,81 +124,26 @@ _sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
        }
 }
 
-#define sbus_memcpy_toio(d, s, sz)     _sbus_memcpy_toio(d, s, sz)
-
-static inline void
-_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
-{
-       const char *s = src;
-       volatile void __iomem *d = dst;
-
-       while (n--) {
-               char tmp = *s++;
-               writeb(tmp, d);
-               d++;
-       }
-}
-
-#define memcpy_toio(d,s,sz)    _memcpy_toio(d,s,sz)
-
 #ifdef __KERNEL__
 
 /*
  * Bus number may be embedded in the higher bits of the physical address.
  * This is why we have no bus number argument to ioremap().
  */
-extern void __iomem *ioremap(unsigned long offset, unsigned long size);
+void __iomem *ioremap(unsigned long offset, unsigned long size);
 #define ioremap_nocache(X,Y)   ioremap((X),(Y))
 #define ioremap_wc(X,Y)                ioremap((X),(Y))
-extern void iounmap(volatile void __iomem *addr);
-
-#define ioread8(X)                     readb(X)
-#define ioread16(X)                    readw(X)
-#define ioread16be(X)                  __raw_readw(X)
-#define ioread32(X)                    readl(X)
-#define ioread32be(X)                  __raw_readl(X)
-#define iowrite8(val,X)                        writeb(val,X)
-#define iowrite16(val,X)               writew(val,X)
-#define iowrite16be(val,X)             __raw_writew(val,X)
-#define iowrite32(val,X)               writel(val,X)
-#define iowrite32be(val,X)             __raw_writel(val,X)
-
-static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insb((unsigned long __force)port, buf, count);
-}
-static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insw((unsigned long __force)port, buf, count);
-}
-
-static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insl((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsb((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsw((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsl((unsigned long __force)port, buf, count);
-}
+void iounmap(volatile void __iomem *addr);
 
 /* Create a virtual mapping cookie for an IO port range */
-extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
-extern void ioport_unmap(void __iomem *);
+void __iomem *ioport_map(unsigned long port, unsigned int nr);
+void ioport_unmap(void __iomem *);
 
 /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
-extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
+void pci_iounmap(struct pci_dev *dev, void __iomem *);
+
+
 
 /*
  * At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
@@ -343,21 +162,11 @@ static inline int sbus_can_burst64(void)
        return 0; /* actually, sparc_cpu_model==sun4d */
 }
 struct device;
-extern void sbus_set_sbus64(struct device *, int);
+void sbus_set_sbus64(struct device *, int);
 
 #endif
 
 #define __ARCH_HAS_NO_PAGE_ZERO_MAPPED         1
 
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p)   __va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)  p
 
 #endif /* !(__SPARC_IO_H) */
index 09b0b88..05381c3 100644 (file)
@@ -15,7 +15,6 @@
 
 /* BIO layer definitions. */
 extern unsigned long kern_base, kern_size;
-#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
 
 static inline u8 _inb(unsigned long addr)
 {
@@ -91,12 +90,12 @@ static inline void _outl(u32 l, unsigned long addr)
 #define inl_p(__addr)          inl(__addr)
 #define outl_p(__l, __addr)    outl(__l, __addr)
 
-extern void outsb(unsigned long, const void *, unsigned long);
-extern void outsw(unsigned long, const void *, unsigned long);
-extern void outsl(unsigned long, const void *, unsigned long);
-extern void insb(unsigned long, void *, unsigned long);
-extern void insw(unsigned long, void *, unsigned long);
-extern void insl(unsigned long, void *, unsigned long);
+void outsb(unsigned long, const void *, unsigned long);
+void outsw(unsigned long, const void *, unsigned long);
+void outsl(unsigned long, const void *, unsigned long);
+void insb(unsigned long, void *, unsigned long);
+void insw(unsigned long, void *, unsigned long);
+void insl(unsigned long, void *, unsigned long);
 
 static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
 {
@@ -509,12 +508,12 @@ static inline void iounmap(volatile void __iomem *addr)
 #define iowrite32be(val,X)             __raw_writel(val,X)
 
 /* Create a virtual mapping cookie for an IO port range */
-extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
-extern void ioport_unmap(void __iomem *);
+void __iomem *ioport_map(unsigned long port, unsigned int nr);
+void ioport_unmap(void __iomem *);
 
 /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
-extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
+void pci_iounmap(struct pci_dev *dev, void __iomem *);
 
 static inline int sbus_can_dma_64bit(void)
 {
@@ -525,7 +524,7 @@ static inline int sbus_can_burst64(void)
        return 1;
 }
 struct device;
-extern void sbus_set_sbus64(struct device *, int);
+void sbus_set_sbus64(struct device *, int);
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
index 70c589c..f6c066b 100644 (file)
@@ -99,7 +99,7 @@ struct iommu_regs {
 #define IOPTE_WAZ           0x00000001 /* Write as zeros */
 
 struct iommu_struct {
-       struct iommu_regs *regs;
+       struct iommu_regs __iomem *regs;
        iopte_t *page_table;
        /* For convenience */
        unsigned long start; /* First managed virtual address */
@@ -108,14 +108,14 @@ struct iommu_struct {
        struct bit_map usemap;
 };
 
-static inline void iommu_invalidate(struct iommu_regs *regs)
+static inline void iommu_invalidate(struct iommu_regs __iomem *regs)
 {
-       regs->tlbflush = 0;
+       sbus_writel(0, &regs->tlbflush);
 }
 
-static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
+static inline void iommu_invalidate_page(struct iommu_regs __iomem *regs, unsigned long ba)
 {
-       regs->pageflush = (ba & PAGE_MASK);
+       sbus_writel(ba & PAGE_MASK, &regs->pageflush);
 }
 
 #endif /* !(_SPARC_IOMMU_H) */
index caf798b..2b9321a 100644 (file)
@@ -58,8 +58,8 @@ struct strbuf {
        volatile unsigned long  __flushflag_buf[(64+(64-1)) / sizeof(long)];
 };
 
-extern int iommu_table_init(struct iommu *iommu, int tsbsize,
-                           u32 dma_offset, u32 dma_addr_mask,
-                           int numa_node);
+int iommu_table_init(struct iommu *iommu, int tsbsize,
+                    u32 dma_offset, u32 dma_addr_mask,
+                    int numa_node);
 
 #endif /* !(_SPARC64_IOMMU_H) */
index 2ae3aca..eecd3d8 100644 (file)
@@ -16,7 +16,8 @@
 
 #define irq_canonicalize(irq)  (irq)
 
-extern void __init init_IRQ(void);
+void __init init_IRQ(void);
+void __init sun4d_init_sbi_irq(void);
 
 #define NO_IRQ         0xffffffff
 
index abf6afe..91d2193 100644 (file)
  */
 #define NR_IRQS    255
 
-extern void irq_install_pre_handler(int irq,
-                                   void (*func)(unsigned int, void *, void *),
-                                   void *arg1, void *arg2);
+void irq_install_pre_handler(int irq,
+                            void (*func)(unsigned int, void *, void *),
+                            void *arg1, void *arg2);
 #define irq_canonicalize(irq)  (irq)
-extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap);
-extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino);
-extern unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino);
-extern unsigned int sun4v_build_msi(u32 devhandle, unsigned int *irq_p,
-                                   unsigned int msi_devino_start,
-                                   unsigned int msi_devino_end);
-extern void sun4v_destroy_msi(unsigned int irq);
-extern unsigned int sun4u_build_msi(u32 portid, unsigned int *irq_p,
-                                   unsigned int msi_devino_start,
-                                   unsigned int msi_devino_end,
-                                   unsigned long imap_base,
-                                   unsigned long iclr_base);
-extern void sun4u_destroy_msi(unsigned int irq);
-
-extern unsigned char irq_alloc(unsigned int dev_handle,
-                                   unsigned int dev_ino);
+unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap);
+unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino);
+unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino);
+unsigned int sun4v_build_msi(u32 devhandle, unsigned int *irq_p,
+                            unsigned int msi_devino_start,
+                            unsigned int msi_devino_end);
+void sun4v_destroy_msi(unsigned int irq);
+unsigned int sun4u_build_msi(u32 portid, unsigned int *irq_p,
+                            unsigned int msi_devino_start,
+                            unsigned int msi_devino_end,
+                            unsigned long imap_base,
+                            unsigned long iclr_base);
+void sun4u_destroy_msi(unsigned int irq);
+
+unsigned char irq_alloc(unsigned int dev_handle,
+                       unsigned int dev_ino);
 #ifdef CONFIG_PCI_MSI
-extern void irq_free(unsigned int irq);
+void irq_free(unsigned int irq);
 #endif
 
-extern void __init init_IRQ(void);
-extern void fixup_irqs(void);
+void __init init_IRQ(void);
+void fixup_irqs(void);
 
 static inline void set_softint(unsigned long bits)
 {
@@ -89,7 +89,7 @@ static inline unsigned long get_softint(void)
        return retval;
 }
 
-void arch_trigger_all_cpu_backtrace(void);
+void arch_trigger_all_cpu_backtrace(bool);
 #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
 
 extern void *hardirq_stack[NR_CPUS];
index e414c06..71cc284 100644 (file)
@@ -15,9 +15,9 @@
 #include <linux/types.h>
 #include <asm/psr.h>
 
-extern void arch_local_irq_restore(unsigned long);
-extern unsigned long arch_local_irq_save(void);
-extern void arch_local_irq_enable(void);
+void arch_local_irq_restore(unsigned long);
+unsigned long arch_local_irq_save(void);
+void arch_local_irq_enable(void);
 
 static inline notrace unsigned long arch_local_save_flags(void)
 {
index feb3578..04465de 100644 (file)
@@ -3,7 +3,7 @@
 
 struct pt_regs;
 
-extern void bad_trap(struct pt_regs *, long);
+void bad_trap(struct pt_regs *, long);
 
 /* Grossly misnamed. */
 enum die_val {
index b6ef301..47366af 100644 (file)
@@ -28,9 +28,12 @@ enum regnames {
 #define NUMREGBYTES            ((GDB_CSR + 1) * 4)
 #else
 #define NUMREGBYTES            ((GDB_Y + 1) * 8)
+
+struct pt_regs;
+asmlinkage void kgdb_trap(unsigned long trap_level, struct pt_regs *regs);
 #endif
 
-extern void arch_kgdb_breakpoint(void);
+void arch_kgdb_breakpoint(void);
 
 #define BREAK_INSTR_SIZE       4
 #define CACHE_FLUSH_IS_SAFE    1
index 5879d71..a145d79 100644 (file)
@@ -43,7 +43,9 @@ struct kprobe_ctlblk {
        struct prev_kprobe prev_kprobe;
 };
 
-extern int kprobe_exceptions_notify(struct notifier_block *self,
-                                   unsigned long val, void *data);
-extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
+int kprobe_exceptions_notify(struct notifier_block *self,
+                            unsigned long val, void *data);
+int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
+asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
+                                     struct pt_regs *regs);
 #endif /* _SPARC64_KPROBES_H */
index bdb524a..c8c67f6 100644 (file)
@@ -4,9 +4,9 @@
 #include <asm/hypervisor.h>
 
 extern int ldom_domaining_enabled;
-extern void ldom_set_var(const char *var, const char *value);
-extern void ldom_reboot(const char *boot_command);
-extern void ldom_power_off(void);
+void ldom_set_var(const char *var, const char *value);
+void ldom_reboot(const char *boot_command);
+void ldom_power_off(void);
 
 /* The event handler will be evoked when link state changes
  * or data becomes available on the receive side.
@@ -51,30 +51,30 @@ struct ldc_channel_config {
 struct ldc_channel;
 
 /* Allocate state for a channel.  */
-extern struct ldc_channel *ldc_alloc(unsigned long id,
-                                    const struct ldc_channel_config *cfgp,
-                                    void *event_arg);
+struct ldc_channel *ldc_alloc(unsigned long id,
+                             const struct ldc_channel_config *cfgp,
+                             void *event_arg);
 
 /* Shut down and free state for a channel.  */
-extern void ldc_free(struct ldc_channel *lp);
+void ldc_free(struct ldc_channel *lp);
 
 /* Register TX and RX queues of the link with the hypervisor.  */
-extern int ldc_bind(struct ldc_channel *lp, const char *name);
+int ldc_bind(struct ldc_channel *lp, const char *name);
 
 /* For non-RAW protocols we need to complete a handshake before
  * communication can proceed.  ldc_connect() does that, if the
  * handshake completes successfully, an LDC_EVENT_UP event will
  * be sent up to the driver.
  */
-extern int ldc_connect(struct ldc_channel *lp);
-extern int ldc_disconnect(struct ldc_channel *lp);
+int ldc_connect(struct ldc_channel *lp);
+int ldc_disconnect(struct ldc_channel *lp);
 
-extern int ldc_state(struct ldc_channel *lp);
+int ldc_state(struct ldc_channel *lp);
 
 /* Read and write operations.  Only valid when the link is up.  */
-extern int ldc_write(struct ldc_channel *lp, const void *buf,
-                    unsigned int size);
-extern int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
+int ldc_write(struct ldc_channel *lp, const void *buf,
+             unsigned int size);
+int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
 
 #define LDC_MAP_SHADOW 0x01
 #define LDC_MAP_DIRECT 0x02
@@ -92,22 +92,22 @@ struct ldc_trans_cookie {
 };
 
 struct scatterlist;
-extern int ldc_map_sg(struct ldc_channel *lp,
-                     struct scatterlist *sg, int num_sg,
-                     struct ldc_trans_cookie *cookies, int ncookies,
-                     unsigned int map_perm);
+int ldc_map_sg(struct ldc_channel *lp,
+              struct scatterlist *sg, int num_sg,
+              struct ldc_trans_cookie *cookies, int ncookies,
+              unsigned int map_perm);
 
-extern int ldc_map_single(struct ldc_channel *lp,
-                         void *buf, unsigned int len,
-                         struct ldc_trans_cookie *cookies, int ncookies,
-                         unsigned int map_perm);
+int ldc_map_single(struct ldc_channel *lp,
+                  void *buf, unsigned int len,
+                  struct ldc_trans_cookie *cookies, int ncookies,
+                  unsigned int map_perm);
 
-extern void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
-                     int ncookies);
+void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
+              int ncookies);
 
-extern int ldc_copy(struct ldc_channel *lp, int copy_dir,
-                   void *buf, unsigned int len, unsigned long offset,
-                   struct ldc_trans_cookie *cookies, int ncookies);
+int ldc_copy(struct ldc_channel *lp, int copy_dir,
+            void *buf, unsigned int len, unsigned long offset,
+            struct ldc_trans_cookie *cookies, int ncookies);
 
 static inline int ldc_get_dring_entry(struct ldc_channel *lp,
                                      void *buf, unsigned int len,
@@ -127,12 +127,12 @@ static inline int ldc_put_dring_entry(struct ldc_channel *lp,
        return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies);
 }
 
-extern void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
-                                struct ldc_trans_cookie *cookies,
-                                int *ncookies, unsigned int map_perm);
+void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
+                         struct ldc_trans_cookie *cookies,
+                         int *ncookies, unsigned int map_perm);
 
-extern void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
-                              unsigned int len,
-                              struct ldc_trans_cookie *cookies, int ncookies);
+void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
+                       unsigned int len,
+                       struct ldc_trans_cookie *cookies, int ncookies);
 
 #endif /* _SPARC64_LDC_H */
index c2f6ff6..204771c 100644 (file)
@@ -82,8 +82,8 @@ static inline unsigned long leon_load_reg(unsigned long paddr)
 #define LEON_BYPASS_LOAD_PA(x)      leon_load_reg((unsigned long)(x))
 #define LEON_BYPASS_STORE_PA(x, v)  leon_store_reg((unsigned long)(x), (unsigned long)(v))
 
-extern void leon_switch_mm(void);
-extern void leon_init_IRQ(void);
+void leon_switch_mm(void);
+void leon_init_IRQ(void);
 
 static inline unsigned long sparc_leon3_get_dcachecfg(void)
 {
@@ -196,14 +196,14 @@ static inline int sparc_leon3_cpuid(void)
 #ifndef __ASSEMBLY__
 struct vm_area_struct;
 
-extern unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr);
-extern void leon_flush_icache_all(void);
-extern void leon_flush_dcache_all(void);
-extern void leon_flush_cache_all(void);
-extern void leon_flush_tlb_all(void);
+unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr);
+void leon_flush_icache_all(void);
+void leon_flush_dcache_all(void);
+void leon_flush_cache_all(void);
+void leon_flush_tlb_all(void);
 extern int leon_flush_during_switch;
-extern int leon_flush_needed(void);
-extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
+int leon_flush_needed(void);
+void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
 
 /* struct that hold LEON3 cache configuration registers */
 struct leon3_cacheregs {
@@ -217,29 +217,29 @@ struct leon3_cacheregs {
 
 struct device_node;
 struct task_struct;
-extern unsigned int leon_build_device_irq(unsigned int real_irq,
-                                          irq_flow_handler_t flow_handler,
-                                          const char *name, int do_ack);
-extern void leon_update_virq_handling(unsigned int virq,
-                             irq_flow_handler_t flow_handler,
-                             const char *name, int do_ack);
-extern void leon_init_timers(void);
-extern void leon_trans_init(struct device_node *dp);
-extern void leon_node_init(struct device_node *dp, struct device_node ***nextp);
-extern void init_leon(void);
-extern void poke_leonsparc(void);
-extern void leon3_getCacheRegs(struct leon3_cacheregs *regs);
+unsigned int leon_build_device_irq(unsigned int real_irq,
+                                  irq_flow_handler_t flow_handler,
+                                  const char *name, int do_ack);
+void leon_update_virq_handling(unsigned int virq,
+                              irq_flow_handler_t flow_handler,
+                              const char *name, int do_ack);
+void leon_init_timers(void);
+void leon_trans_init(struct device_node *dp);
+void leon_node_init(struct device_node *dp, struct device_node ***nextp);
+void init_leon(void);
+void poke_leonsparc(void);
+void leon3_getCacheRegs(struct leon3_cacheregs *regs);
 extern int leon3_ticker_irq;
 
 #ifdef CONFIG_SMP
-extern int leon_smp_nrcpus(void);
-extern void leon_clear_profile_irq(int cpu);
-extern void leon_smp_done(void);
-extern void leon_boot_cpus(void);
-extern int leon_boot_one_cpu(int i, struct task_struct *);
+int leon_smp_nrcpus(void);
+void leon_clear_profile_irq(int cpu);
+void leon_smp_done(void);
+void leon_boot_cpus(void);
+int leon_boot_one_cpu(int i, struct task_struct *);
 void leon_init_smp(void);
 void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
-extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
+irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
 
 extern unsigned int smpleon_ipi[];
 extern unsigned int linux_trap_ipi15_leon[];
index bfd3ab3..049d067 100644 (file)
@@ -16,7 +16,7 @@ struct leon_pci_info {
        int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
 };
 
-extern void leon_pci_init(struct platform_device *ofdev,
-                               struct leon_pci_info *info);
+void leon_pci_init(struct platform_device *ofdev,
+                  struct leon_pci_info *info);
 
 #endif /* _ASM_LEON_PCI_H_ */
index 67ed9e3..d8e72f3 100644 (file)
@@ -1,5 +1,10 @@
 #ifndef ___ASM_SPARC_MC146818RTC_H
 #define ___ASM_SPARC_MC146818RTC_H
+
+#include <linux/spinlock.h>
+
+extern spinlock_t rtc_lock;
+
 #if defined(__sparc__) && defined(__arch64__)
 #include <asm/mc146818rtc_64.h>
 #else
index 139097f..aebeb88 100644 (file)
@@ -12,13 +12,13 @@ struct mdesc_handle;
  * the first argument to all of the operational calls that work
  * on mdescs.
  */
-extern struct mdesc_handle *mdesc_grab(void);
-extern void mdesc_release(struct mdesc_handle *);
+struct mdesc_handle *mdesc_grab(void);
+void mdesc_release(struct mdesc_handle *);
 
 #define MDESC_NODE_NULL                (~(u64)0)
 
-extern u64 mdesc_node_by_name(struct mdesc_handle *handle,
-                             u64 from_node, const char *name);
+u64 mdesc_node_by_name(struct mdesc_handle *handle,
+                      u64 from_node, const char *name);
 #define mdesc_for_each_node_by_name(__hdl, __node, __name) \
        for (__node = mdesc_node_by_name(__hdl, MDESC_NODE_NULL, __name); \
             (__node) != MDESC_NODE_NULL; \
@@ -34,9 +34,9 @@ extern u64 mdesc_node_by_name(struct mdesc_handle *handle,
  *
  * These same rules apply to mdesc_node_name().
  */
-extern const void *mdesc_get_property(struct mdesc_handle *handle,
-                                     u64 node, const char *name, int *lenp);
-extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node);
+const void *mdesc_get_property(struct mdesc_handle *handle,
+                              u64 node, const char *name, int *lenp);
+const char *mdesc_node_name(struct mdesc_handle *hp, u64 node);
 
 /* MD arc iteration, the standard sequence is:
  *
@@ -50,16 +50,16 @@ extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node);
 #define MDESC_ARC_TYPE_FWD     "fwd"
 #define MDESC_ARC_TYPE_BACK    "back"
 
-extern u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from,
-                         const char *arc_type);
+u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from,
+                  const char *arc_type);
 #define mdesc_for_each_arc(__arc, __hdl, __node, __type) \
        for (__arc = mdesc_next_arc(__hdl, __node, __type); \
             (__arc) != MDESC_NODE_NULL; \
             __arc = mdesc_next_arc(__hdl, __arc, __type))
 
-extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
+u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
 
-extern void mdesc_update(void);
+void mdesc_update(void);
 
 struct mdesc_notifier_client {
        void (*add)(struct mdesc_handle *handle, u64 node);
@@ -69,12 +69,12 @@ struct mdesc_notifier_client {
        struct mdesc_notifier_client    *next;
 };
 
-extern void mdesc_register_notifier(struct mdesc_notifier_client *client);
+void mdesc_register_notifier(struct mdesc_notifier_client *client);
 
-extern void mdesc_fill_in_cpu_data(cpumask_t *mask);
-extern void mdesc_populate_present_mask(cpumask_t *mask);
-extern void mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask);
+void mdesc_fill_in_cpu_data(cpumask_t *mask);
+void mdesc_populate_present_mask(cpumask_t *mask);
+void mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask);
 
-extern void sun4v_mdesc_init(void);
+void sun4v_mdesc_init(void);
 
 #endif
index f668797..70067ce 100644 (file)
@@ -67,9 +67,9 @@ struct tsb {
        unsigned long pte;
 } __attribute__((aligned(TSB_ENTRY_ALIGNMENT)));
 
-extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte);
-extern void tsb_flush(unsigned long ent, unsigned long tag);
-extern void tsb_init(struct tsb *tsb, unsigned long size);
+void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte);
+void tsb_flush(unsigned long ent, unsigned long tag);
+void tsb_init(struct tsb *tsb, unsigned long size);
 
 struct tsb_config {
        struct tsb              *tsb;
index 3d528f0..b84be67 100644 (file)
@@ -17,20 +17,20 @@ extern spinlock_t ctx_alloc_lock;
 extern unsigned long tlb_context_cache;
 extern unsigned long mmu_context_bmap[];
 
-extern void get_new_mmu_context(struct mm_struct *mm);
+void get_new_mmu_context(struct mm_struct *mm);
 #ifdef CONFIG_SMP
-extern void smp_new_mmu_context_version(void);
+void smp_new_mmu_context_version(void);
 #else
 #define smp_new_mmu_context_version() do { } while (0)
 #endif
 
-extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
-extern void destroy_context(struct mm_struct *mm);
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+void destroy_context(struct mm_struct *mm);
 
-extern void __tsb_context_switch(unsigned long pgd_pa,
-                                struct tsb_config *tsb_base,
-                                struct tsb_config *tsb_huge,
-                                unsigned long tsb_descr_pa);
+void __tsb_context_switch(unsigned long pgd_pa,
+                         struct tsb_config *tsb_base,
+                         struct tsb_config *tsb_huge,
+                         unsigned long tsb_descr_pa);
 
 static inline void tsb_context_switch(struct mm_struct *mm)
 {
@@ -46,9 +46,11 @@ static inline void tsb_context_switch(struct mm_struct *mm)
                             , __pa(&mm->context.tsb_descr[0]));
 }
 
-extern void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long mm_rss);
+void tsb_grow(struct mm_struct *mm,
+             unsigned long tsb_index,
+             unsigned long mm_rss);
 #ifdef CONFIG_SMP
-extern void smp_tsb_sync(struct mm_struct *mm);
+void smp_tsb_sync(struct mm_struct *mm);
 #else
 #define smp_tsb_sync(__mm) do { } while (0)
 #endif
@@ -66,7 +68,7 @@ extern void smp_tsb_sync(struct mm_struct *mm);
        : "r" (CTX_HWBITS((__mm)->context)), \
          "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU), "i" (ASI_MMU))
 
-extern void __flush_tlb_mm(unsigned long, unsigned long);
+void __flush_tlb_mm(unsigned long, unsigned long);
 
 /* Switch the current MM context. */
 static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk)
index 72e6500..26ad2b2 100644 (file)
@@ -1,13 +1,13 @@
 #ifndef __NMI_H
 #define __NMI_H
 
-extern int __init nmi_init(void);
-extern void perfctr_irq(int irq, struct pt_regs *regs);
-extern void nmi_adjust_hz(unsigned int new_hz);
+int __init nmi_init(void);
+void perfctr_irq(int irq, struct pt_regs *regs);
+void nmi_adjust_hz(unsigned int new_hz);
 
 extern atomic_t nmi_active;
 
-extern void start_nmi_watchdog(void *unused);
-extern void stop_nmi_watchdog(void *unused);
+void start_nmi_watchdog(void *unused);
+void stop_nmi_watchdog(void *unused);
 
 #endif /* __NMI_H */
index c72f304..56a09b9 100644 (file)
@@ -43,28 +43,28 @@ extern struct linux_nodeops *prom_nodeops;
 /* You must call prom_init() before using any of the library services,
  * preferably as early as possible.  Pass it the romvec pointer.
  */
-extern void prom_init(struct linux_romvec *rom_ptr);
+void prom_init(struct linux_romvec *rom_ptr);
 
 /* Boot argument acquisition, returns the boot command line string. */
-extern char *prom_getbootargs(void);
+char *prom_getbootargs(void);
 
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
-extern void prom_reboot(char *boot_command);
+void prom_reboot(char *boot_command);
 
 /* Evaluate the forth string passed. */
-extern void prom_feval(char *forth_string);
+void prom_feval(char *forth_string);
 
 /* Enter the prom, with possibility of continuation with the 'go'
  * command in newer proms.
  */
-extern void prom_cmdline(void);
+void prom_cmdline(void);
 
 /* Enter the prom, with no chance of continuation for the stand-alone
  * which calls this.
  */
-extern void __noreturn prom_halt(void);
+void __noreturn prom_halt(void);
 
 /* Set the PROM 'sync' callback function to the passed function pointer.
  * When the user gives the 'sync' command at the prom prompt while the
@@ -73,37 +73,37 @@ extern void __noreturn prom_halt(void);
  * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX
  */
 typedef void (*sync_func_t)(void);
-extern void prom_setsync(sync_func_t func_ptr);
+void prom_setsync(sync_func_t func_ptr);
 
 /* Acquire the IDPROM of the root node in the prom device tree.  This
  * gets passed a buffer where you would like it stuffed.  The return value
  * is the format type of this idprom or 0xff on error.
  */
-extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
 
 /* Get the prom major version. */
-extern int prom_version(void);
+int prom_version(void);
 
 /* Get the prom plugin revision. */
-extern int prom_getrev(void);
+int prom_getrev(void);
 
 /* Get the prom firmware revision. */
-extern int prom_getprev(void);
+int prom_getprev(void);
 
 /* Write a buffer of characters to the console. */
-extern void prom_console_write_buf(const char *buf, int len);
+void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
-extern __printf(1, 2) void prom_printf(const char *fmt, ...);
-extern void prom_write(const char *buf, unsigned int len);
+__printf(1, 2) void prom_printf(const char *fmt, ...);
+void prom_write(const char *buf, unsigned int len);
 
 /* Multiprocessor operations... */
 
 /* Start the CPU with the given device tree node, context table, and context
  * at the passed program counter.
  */
-extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
-                        int context, char *program_counter);
+int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
+                 int context, char *program_counter);
 
 /* Initialize the memory lists based upon the prom version. */
 void prom_meminit(void);
@@ -111,65 +111,65 @@ void prom_meminit(void);
 /* PROM device tree traversal functions... */
 
 /* Get the child node of the given node, or zero if no child exists. */
-extern phandle prom_getchild(phandle parent_node);
+phandle prom_getchild(phandle parent_node);
 
 /* Get the next sibling node of the given node, or zero if no further
  * siblings exist.
  */
-extern phandle prom_getsibling(phandle node);
+phandle prom_getsibling(phandle node);
 
 /* Get the length, at the passed node, of the given property type.
  * Returns -1 on error (ie. no such property at this node).
  */
-extern int prom_getproplen(phandle thisnode, const char *property);
+int prom_getproplen(phandle thisnode, const char *property);
 
 /* Fetch the requested property using the given buffer.  Returns
  * the number of bytes the prom put into your buffer or -1 on error.
  */
-extern int __must_check prom_getproperty(phandle thisnode, const char *property,
-                                        char *prop_buffer, int propbuf_size);
+int __must_check prom_getproperty(phandle thisnode, const char *property,
+                                 char *prop_buffer, int propbuf_size);
 
 /* Acquire an integer property. */
-extern int prom_getint(phandle node, char *property);
+int prom_getint(phandle node, char *property);
 
 /* Acquire an integer property, with a default value. */
-extern int prom_getintdefault(phandle node, char *property, int defval);
+int prom_getintdefault(phandle node, char *property, int defval);
 
 /* Acquire a boolean property, 0=FALSE 1=TRUE. */
-extern int prom_getbool(phandle node, char *prop);
+int prom_getbool(phandle node, char *prop);
 
 /* Acquire a string property, null string on error. */
-extern void prom_getstring(phandle node, char *prop, char *buf, int bufsize);
+void prom_getstring(phandle node, char *prop, char *buf, int bufsize);
 
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */
-extern phandle prom_searchsiblings(phandle node_start, char *name);
+phandle prom_searchsiblings(phandle node_start, char *name);
 
 /* Returns the next property after the passed property for the given
  * node.  Returns null string on failure.
  */
-extern char *prom_nextprop(phandle node, char *prev_property, char *buffer);
+char *prom_nextprop(phandle node, char *prev_property, char *buffer);
 
 /* Returns phandle of the path specified */
-extern phandle prom_finddevice(char *name);
+phandle prom_finddevice(char *name);
 
 /* Set the indicated property at the given node with the passed value.
  * Returns the number of bytes of your value that the prom took.
  */
-extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
-                       int value_size);
+int prom_setprop(phandle node, const char *prop_name, char *prop_value,
+                int value_size);
 
-extern phandle prom_inst2pkg(int);
+phandle prom_inst2pkg(int);
 
 /* Dorking with Bus ranges... */
 
 /* Apply promlib probes OBIO ranges to registers. */
-extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
+void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
 
 /* Apply ranges of any prom node (and optionally parent node as well) to registers. */
-extern void prom_apply_generic_ranges(phandle node, phandle parent,
-                                     struct linux_prom_registers *sbusregs, int nregs);
+void prom_apply_generic_ranges(phandle node, phandle parent,
+                              struct linux_prom_registers *sbusregs, int nregs);
 
 void prom_ranges_init(void);
 
index a12dbe3..f346824 100644 (file)
@@ -62,100 +62,100 @@ struct linux_mem_p1275 {
 /* You must call prom_init() before using any of the library services,
  * preferably as early as possible.  Pass it the romvec pointer.
  */
-extern void prom_init(void *cif_handler, void *cif_stack);
+void prom_init(void *cif_handler, void *cif_stack);
 
 /* Boot argument acquisition, returns the boot command line string. */
-extern char *prom_getbootargs(void);
+char *prom_getbootargs(void);
 
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
-extern void prom_reboot(const char *boot_command);
+void prom_reboot(const char *boot_command);
 
 /* Evaluate the forth string passed. */
-extern void prom_feval(const char *forth_string);
+void prom_feval(const char *forth_string);
 
 /* Enter the prom, with possibility of continuation with the 'go'
  * command in newer proms.
  */
-extern void prom_cmdline(void);
+void prom_cmdline(void);
 
 /* Enter the prom, with no chance of continuation for the stand-alone
  * which calls this.
  */
-extern void prom_halt(void) __attribute__ ((noreturn));
+void prom_halt(void) __attribute__ ((noreturn));
 
 /* Halt and power-off the machine. */
-extern void prom_halt_power_off(void) __attribute__ ((noreturn));
+void prom_halt_power_off(void) __attribute__ ((noreturn));
 
 /* Acquire the IDPROM of the root node in the prom device tree.  This
  * gets passed a buffer where you would like it stuffed.  The return value
  * is the format type of this idprom or 0xff on error.
  */
-extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
 
 /* Write a buffer of characters to the console. */
-extern void prom_console_write_buf(const char *buf, int len);
+void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
-extern __printf(1, 2) void prom_printf(const char *fmt, ...);
-extern void prom_write(const char *buf, unsigned int len);
+__printf(1, 2) void prom_printf(const char *fmt, ...);
+void prom_write(const char *buf, unsigned int len);
 
 /* Multiprocessor operations... */
 #ifdef CONFIG_SMP
 /* Start the CPU with the given device tree node at the passed program
  * counter with the given arg passed in via register %o0.
  */
-extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg);
+void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg);
 
 /* Start the CPU with the given cpu ID at the passed program
  * counter with the given arg passed in via register %o0.
  */
-extern void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg);
+void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg);
 
 /* Stop the CPU with the given cpu ID.  */
-extern void prom_stopcpu_cpuid(int cpuid);
+void prom_stopcpu_cpuid(int cpuid);
 
 /* Stop the current CPU. */
-extern void prom_stopself(void);
+void prom_stopself(void);
 
 /* Idle the current CPU. */
-extern void prom_idleself(void);
+void prom_idleself(void);
 
 /* Resume the CPU with the passed device tree node. */
-extern void prom_resumecpu(int cpunode);
+void prom_resumecpu(int cpunode);
 #endif
 
 /* Power management interfaces. */
 
 /* Put the current CPU to sleep. */
-extern void prom_sleepself(void);
+void prom_sleepself(void);
 
 /* Put the entire system to sleep. */
-extern int prom_sleepsystem(void);
+int prom_sleepsystem(void);
 
 /* Initiate a wakeup event. */
-extern int prom_wakeupsystem(void);
+int prom_wakeupsystem(void);
 
 /* MMU and memory related OBP interfaces. */
 
 /* Get unique string identifying SIMM at given physical address. */
-extern int prom_getunumber(int syndrome_code,
-                          unsigned long phys_addr,
-                          char *buf, int buflen);
+int prom_getunumber(int syndrome_code,
+                   unsigned long phys_addr,
+                   char *buf, int buflen);
 
 /* Retain physical memory to the caller across soft resets. */
-extern int prom_retain(const char *name, unsigned long size,
-                      unsigned long align, unsigned long *paddr);
+int prom_retain(const char *name, unsigned long size,
+               unsigned long align, unsigned long *paddr);
 
 /* Load explicit I/D TLB entries into the calling processor. */
-extern long prom_itlb_load(unsigned long index,
-                          unsigned long tte_data,
-                          unsigned long vaddr);
+long prom_itlb_load(unsigned long index,
+                   unsigned long tte_data,
+                   unsigned long vaddr);
 
-extern long prom_dtlb_load(unsigned long index,
-                          unsigned long tte_data,
-                          unsigned long vaddr);
+long prom_dtlb_load(unsigned long index,
+                   unsigned long tte_data,
+                   unsigned long vaddr);
 
 /* Map/Unmap client program address ranges.  First the format of
  * the mapping mode argument.
@@ -170,81 +170,81 @@ extern long prom_dtlb_load(unsigned long index,
 #define PROM_MAP_IE    0x0100 /* Invert-Endianness */
 #define PROM_MAP_DEFAULT (PROM_MAP_WRITE | PROM_MAP_READ | PROM_MAP_EXEC | PROM_MAP_CACHED)
 
-extern int prom_map(int mode, unsigned long size,
-                   unsigned long vaddr, unsigned long paddr);
-extern void prom_unmap(unsigned long size, unsigned long vaddr);
+int prom_map(int mode, unsigned long size,
+            unsigned long vaddr, unsigned long paddr);
+void prom_unmap(unsigned long size, unsigned long vaddr);
 
 
 /* PROM device tree traversal functions... */
 
 /* Get the child node of the given node, or zero if no child exists. */
-extern phandle prom_getchild(phandle parent_node);
+phandle prom_getchild(phandle parent_node);
 
 /* Get the next sibling node of the given node, or zero if no further
  * siblings exist.
  */
-extern phandle prom_getsibling(phandle node);
+phandle prom_getsibling(phandle node);
 
 /* Get the length, at the passed node, of the given property type.
  * Returns -1 on error (ie. no such property at this node).
  */
-extern int prom_getproplen(phandle thisnode, const char *property);
+int prom_getproplen(phandle thisnode, const char *property);
 
 /* Fetch the requested property using the given buffer.  Returns
  * the number of bytes the prom put into your buffer or -1 on error.
  */
-extern int prom_getproperty(phandle thisnode, const char *property,
-                           char *prop_buffer, int propbuf_size);
+int prom_getproperty(phandle thisnode, const char *property,
+                    char *prop_buffer, int propbuf_size);
 
 /* Acquire an integer property. */
-extern int prom_getint(phandle node, const char *property);
+int prom_getint(phandle node, const char *property);
 
 /* Acquire an integer property, with a default value. */
-extern int prom_getintdefault(phandle node, const char *property, int defval);
+int prom_getintdefault(phandle node, const char *property, int defval);
 
 /* Acquire a boolean property, 0=FALSE 1=TRUE. */
-extern int prom_getbool(phandle node, const char *prop);
+int prom_getbool(phandle node, const char *prop);
 
 /* Acquire a string property, null string on error. */
-extern void prom_getstring(phandle node, const char *prop, char *buf,
-                          int bufsize);
+void prom_getstring(phandle node, const char *prop, char *buf,
+                   int bufsize);
 
 /* Does the passed node have the given "name"? YES=1 NO=0 */
-extern int prom_nodematch(phandle thisnode, const char *name);
+int prom_nodematch(phandle thisnode, const char *name);
 
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */
-extern phandle prom_searchsiblings(phandle node_start, const char *name);
+phandle prom_searchsiblings(phandle node_start, const char *name);
 
 /* Return the first property type, as a string, for the given node.
  * Returns a null string on error. Buffer should be at least 32B long.
  */
-extern char *prom_firstprop(phandle node, char *buffer);
+char *prom_firstprop(phandle node, char *buffer);
 
 /* Returns the next property after the passed property for the given
  * node.  Returns null string on failure. Buffer should be at least 32B long.
  */
-extern char *prom_nextprop(phandle node, const char *prev_property, char *buf);
+char *prom_nextprop(phandle node, const char *prev_property, char *buf);
 
 /* Returns 1 if the specified node has given property. */
-extern int prom_node_has_property(phandle node, const char *property);
+int prom_node_has_property(phandle node, const char *property);
 
 /* Returns phandle of the path specified */
-extern phandle prom_finddevice(const char *name);
+phandle prom_finddevice(const char *name);
 
 /* Set the indicated property at the given node with the passed value.
  * Returns the number of bytes of your value that the prom took.
  */
-extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
-                       int value_size);
+int prom_setprop(phandle node, const char *prop_name, char *prop_value,
+                int value_size);
 
-extern phandle prom_inst2pkg(int);
-extern void prom_sun4v_guest_soft_state(void);
+phandle prom_inst2pkg(int);
+void prom_sun4v_guest_soft_state(void);
 
-extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
+int prom_ihandle2path(int handle, char *buffer, int bufsize);
 
 /* Client interface level routines. */
-extern void p1275_cmd_direct(unsigned long *);
+void p1275_cmd_direct(unsigned long *);
 
 #endif /* !(__SPARC64_OPLIB_H) */
index f21de03..1be2fde 100644 (file)
@@ -1,5 +1,8 @@
 #ifndef ___ASM_SPARC_PAGE_H
 #define ___ASM_SPARC_PAGE_H
+
+#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+
 #if defined(__sparc__) && defined(__arch64__)
 #include <asm/page_64.h>
 #else
index aac53fc..bf10998 100644 (file)
 
 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 struct pt_regs;
-extern void hugetlb_setup(struct pt_regs *regs);
+void hugetlb_setup(struct pt_regs *regs);
 #endif
 
 #define WANT_PAGE_VIRTUAL
 
-extern void _clear_page(void *page);
+void _clear_page(void *page);
 #define clear_page(X)  _clear_page((void *)(X))
 struct page;
-extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page);
+void clear_user_page(void *addr, unsigned long vaddr, struct page *page);
 #define copy_page(X,Y) memcpy((void *)(X), (void *)(Y), PAGE_SIZE)
-extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topage);
+void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topage);
 
 /* Unlike sparc32, sparc64's parameter passing API is more
  * sane in that structures which as small enough are passed
index c6c7396..bd00a62 100644 (file)
@@ -52,7 +52,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 
 /* Return the index of the PCI controller for device PDEV. */
 
-extern int pci_domain_nr(struct pci_bus *bus);
+int pci_domain_nr(struct pci_bus *bus);
 static inline int pci_proc_domain(struct pci_bus *bus)
 {
        return 1;
@@ -64,9 +64,9 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 #define HAVE_ARCH_PCI_GET_UNMAPPED_AREA
 #define get_pci_unmapped_area get_fb_unmapped_area
 
-extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-                              enum pci_mmap_state mmap_state,
-                              int write_combine);
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+                       enum pci_mmap_state mmap_state,
+                       int write_combine);
 
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
@@ -74,9 +74,9 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 }
 
 #define HAVE_ARCH_PCI_RESOURCE_TO_USER
-extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
-                                const struct resource *rsrc,
-                                resource_size_t *start, resource_size_t *end);
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                         const struct resource *rsrc,
+                         resource_size_t *start, resource_size_t *end);
 #endif /* __KERNEL__ */
 
 #endif /* __SPARC64_PCI_H */
index 6676cbc..f417067 100644 (file)
@@ -30,10 +30,10 @@ struct linux_pcic {
 };
 
 #ifdef CONFIG_PCIC_PCI
-extern int pcic_present(void);
-extern int pcic_probe(void);
-extern void pci_time_init(void);
-extern void sun4m_pci_init_IRQ(void);
+int pcic_present(void);
+int pcic_probe(void);
+void pci_time_init(void);
+void sun4m_pci_init_IRQ(void);
 #else
 static inline int pcic_present(void) { return 0; }
 static inline int pcic_probe(void) { return 0; }
index 942bb17..cdf800c 100644 (file)
@@ -12,8 +12,8 @@ struct pcr_ops {
 };
 extern const struct pcr_ops *pcr_ops;
 
-extern void deferred_pcr_work_irq(int irq, struct pt_regs *regs);
-extern void schedule_deferred_pcr_work(void);
+void deferred_pcr_work_irq(int irq, struct pt_regs *regs);
+void schedule_deferred_pcr_work(void);
 
 #define PCR_PIC_PRIV           0x00000001 /* PIC access is privileged */
 #define PCR_STRACE             0x00000002 /* Trace supervisor events  */
@@ -45,6 +45,6 @@ extern void schedule_deferred_pcr_work(void);
 #define PCR_N4_PICNHT          0x00020000 /* PIC non-hypervisor trap  */
 #define PCR_N4_NTC             0x00040000 /* Next-To-Commit wrap      */
 
-extern int pcr_arch_init(void);
+int pcr_arch_init(void);
 
 #endif /* __PCR_H */
index 9b1c36d..a3890da 100644 (file)
@@ -14,6 +14,8 @@ struct page;
 void *srmmu_get_nocache(int size, int align);
 void srmmu_free_nocache(void *addr, int size);
 
+extern struct resource sparc_iomap;
+
 #define check_pgt_cache()      do { } while (0)
 
 pgd_t *get_pgd_fast(void);
index bcfe063..39a7ac4 100644 (file)
@@ -38,12 +38,12 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
        kmem_cache_free(pgtable_cache, pmd);
 }
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                  unsigned long address);
-extern pgtable_t pte_alloc_one(struct mm_struct *mm,
-                              unsigned long address);
-extern void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
-extern void pte_free(struct mm_struct *mm, pgtable_t ptepage);
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+                           unsigned long address);
+pgtable_t pte_alloc_one(struct mm_struct *mm,
+                       unsigned long address);
+void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
+void pte_free(struct mm_struct *mm, pgtable_t ptepage);
 
 #define pmd_populate_kernel(MM, PMD, PTE)      pmd_set(MM, PMD, PTE)
 #define pmd_populate(MM, PMD, PTE)             pmd_set(MM, PMD, PTE)
@@ -51,12 +51,12 @@ extern void pte_free(struct mm_struct *mm, pgtable_t ptepage);
 
 #define check_pgt_cache()      do { } while (0)
 
-extern void pgtable_free(void *table, bool is_page);
+void pgtable_free(void *table, bool is_page);
 
 #ifdef CONFIG_SMP
 
 struct mmu_gather;
-extern void tlb_remove_table(struct mmu_gather *, void *);
+void tlb_remove_table(struct mmu_gather *, void *);
 
 static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is_page)
 {
index 502f632..b9b91ae 100644 (file)
@@ -25,8 +25,9 @@
 struct vm_area_struct;
 struct page;
 
-extern void load_mmu(void);
-extern unsigned long calc_highpages(void);
+void load_mmu(void);
+unsigned long calc_highpages(void);
+unsigned long __init bootmem_init(unsigned long *pages_avail);
 
 #define pte_ERROR(e)   __builtin_trap()
 #define pmd_ERROR(e)   __builtin_trap()
@@ -56,7 +57,7 @@ extern unsigned long calc_highpages(void);
  * srmmu.c will assign the real one (which is dynamically sized) */
 #define swapper_pg_dir NULL
 
-extern void paging_init(void);
+void paging_init(void);
 
 extern unsigned long ptr_in_current_pgd;
 
@@ -428,8 +429,8 @@ extern unsigned long *sparc_valid_addr_bitmap;
 #define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)                   (pfn & 0x0fffffffUL)
 
-extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
-                          unsigned long, pgprot_t);
+int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+                   unsigned long, pgprot_t);
 
 static inline int io_remap_pfn_range(struct vm_area_struct *vma,
                                     unsigned long from, unsigned long pfn,
index 1a49ffd..3770bf5 100644 (file)
@@ -210,9 +210,9 @@ static inline bool kern_addr_valid(unsigned long addr)
 
 #ifndef __ASSEMBLY__
 
-extern pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long);
+pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long);
 
-extern unsigned long pte_sz_bits(unsigned long size);
+unsigned long pte_sz_bits(unsigned long size);
 
 extern pgprot_t PAGE_KERNEL;
 extern pgprot_t PAGE_KERNEL_LOCKED;
@@ -780,8 +780,8 @@ static inline int pmd_present(pmd_t pmd)
                                         !__kern_addr_valid(pud_val(pud)))
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
-                      pmd_t *pmdp, pmd_t pmd);
+void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+               pmd_t *pmdp, pmd_t pmd);
 #else
 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
                              pmd_t *pmdp, pmd_t pmd)
@@ -840,8 +840,8 @@ static inline unsigned long __pmd_page(pmd_t pmd)
 #define pte_unmap(pte)                 do { } while (0)
 
 /* Actual page table PTE updates.  */
-extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
-                         pte_t *ptep, pte_t orig, int fullmm);
+void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+                  pte_t *ptep, pte_t orig, int fullmm);
 
 #define __HAVE_ARCH_PMDP_GET_AND_CLEAR
 static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
@@ -900,28 +900,28 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern pmd_t swapper_low_pmd_dir[PTRS_PER_PMD];
 
-extern void paging_init(void);
-extern unsigned long find_ecache_flush_span(unsigned long size);
+void paging_init(void);
+unsigned long find_ecache_flush_span(unsigned long size);
 
 struct seq_file;
-extern void mmu_info(struct seq_file *);
+void mmu_info(struct seq_file *);
 
 struct vm_area_struct;
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
+void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
-                                pmd_t *pmd);
+void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+                         pmd_t *pmd);
 
 #define __HAVE_ARCH_PMDP_INVALIDATE
 extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
                            pmd_t *pmdp);
 
 #define __HAVE_ARCH_PGTABLE_DEPOSIT
-extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
-                                      pgtable_t pgtable);
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+                               pgtable_t pgtable);
 
 #define __HAVE_ARCH_PGTABLE_WITHDRAW
-extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
 #endif
 
 /* Encode and de-code a swap entry */
@@ -937,12 +937,12 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
 #define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
 
 /* File offset in PTE support. */
-extern unsigned long pte_file(pte_t);
+unsigned long pte_file(pte_t);
 #define pte_to_pgoff(pte)      (pte_val(pte) >> PAGE_SHIFT)
-extern pte_t pgoff_to_pte(unsigned long);
+pte_t pgoff_to_pte(unsigned long);
 #define PTE_FILE_MAX_BITS      (64UL - PAGE_SHIFT - 1UL)
 
-extern int page_in_phys_avail(unsigned long paddr);
+int page_in_phys_avail(unsigned long paddr);
 
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
@@ -952,8 +952,8 @@ extern int page_in_phys_avail(unsigned long paddr);
 #define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)                   (pfn & 0x0fffffffffffffffUL)
 
-extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
-                          unsigned long, pgprot_t);
+int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+                   unsigned long, pgprot_t);
 
 static inline int io_remap_pfn_range(struct vm_area_struct *vma,
                                     unsigned long from, unsigned long pfn,
@@ -981,20 +981,20 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
 /* We provide a special get_unmapped_area for framebuffer mmaps to try and use
  * the largest alignment possible such that larget PTEs can be used.
  */
-extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
-                                         unsigned long, unsigned long,
-                                         unsigned long);
+unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
+                                  unsigned long, unsigned long,
+                                  unsigned long);
 #define HAVE_ARCH_FB_UNMAPPED_AREA
 
-extern void pgtable_cache_init(void);
-extern void sun4v_register_fault_status(void);
-extern void sun4v_ktsb_register(void);
-extern void __init cheetah_ecache_flush_init(void);
-extern void sun4v_patch_tlb_handlers(void);
+void pgtable_cache_init(void);
+void sun4v_register_fault_status(void);
+void sun4v_ktsb_register(void);
+void __init cheetah_ecache_flush_init(void);
+void sun4v_patch_tlb_handlers(void);
 
 extern unsigned long cmdline_memory_size;
 
-extern asmlinkage void do_sparc64_fault(struct pt_regs *regs);
+asmlinkage void do_sparc64_fault(struct pt_regs *regs);
 
 #endif /* !(__ASSEMBLY__) */
 
index 2c7baa4..a564817 100644 (file)
@@ -74,7 +74,7 @@ struct thread_struct {
 }
 
 /* Return saved PC of a blocked thread. */
-extern unsigned long thread_saved_pc(struct task_struct *t);
+unsigned long thread_saved_pc(struct task_struct *t);
 
 /* Do necessary setup to start up a newly executed thread. */
 static inline void start_thread(struct pt_regs * regs, unsigned long pc,
@@ -107,7 +107,7 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,
 /* Free all resources held by a thread. */
 #define release_thread(tsk)            do { } while(0)
 
-extern unsigned long get_wchan(struct task_struct *);
+unsigned long get_wchan(struct task_struct *);
 
 #define task_pt_regs(tsk) ((tsk)->thread.kregs)
 #define KSTK_EIP(tsk)  ((tsk)->thread.kregs->pc)
@@ -116,6 +116,7 @@ extern unsigned long get_wchan(struct task_struct *);
 #ifdef __KERNEL__
 
 extern struct task_struct *last_task_used_math;
+int do_mathemu(struct pt_regs *regs, struct task_struct *fpt);
 
 #define cpu_relax()    barrier()
 extern void (*sparc_idle)(void);
index 4c3f7f0..7028fe1 100644 (file)
@@ -95,7 +95,7 @@ struct thread_struct {
 
 /* Return saved PC of a blocked thread. */
 struct task_struct;
-extern unsigned long thread_saved_pc(struct task_struct *);
+unsigned long thread_saved_pc(struct task_struct *);
 
 /* On Uniprocessor, even in RMO processes see TSO semantics */
 #ifdef CONFIG_SMP
@@ -194,7 +194,7 @@ do { \
 /* Free all resources held by a thread. */
 #define release_thread(tsk)            do { } while (0)
 
-extern unsigned long get_wchan(struct task_struct *task);
+unsigned long get_wchan(struct task_struct *task);
 
 #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->tpc)
@@ -253,6 +253,8 @@ static inline void prefetchw(const void *x)
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
+int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap);
+
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(__ASM_SPARC64_PROCESSOR_H) */
index 11ebd65..d955c8d 100644 (file)
@@ -36,28 +36,28 @@ struct of_irq_controller {
        void            *data;
 };
 
-extern struct device_node *of_find_node_by_cpuid(int cpuid);
-extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
+struct device_node *of_find_node_by_cpuid(int cpuid);
+int of_set_property(struct device_node *node, const char *name, void *val, int len);
 extern struct mutex of_set_property_mutex;
-extern int of_getintprop_default(struct device_node *np,
-                                const char *name,
+int of_getintprop_default(struct device_node *np,
+                         const char *name,
                                 int def);
-extern int of_find_in_proplist(const char *list, const char *match, int len);
+int of_find_in_proplist(const char *list, const char *match, int len);
 
-extern void prom_build_devicetree(void);
-extern void of_populate_present_mask(void);
-extern void of_fill_in_cpu_data(void);
+void prom_build_devicetree(void);
+void of_populate_present_mask(void);
+void of_fill_in_cpu_data(void);
 
 struct resource;
-extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
-extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
+void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
+void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
 
 extern struct device_node *of_console_device;
 extern char *of_console_path;
 extern char *of_console_options;
 
-extern void irq_trans_init(struct device_node *dp);
-extern char *build_path_component(struct device_node *dp);
+void irq_trans_init(struct device_node *dp);
+char *build_path_component(struct device_node *dp);
 
 #endif /* __KERNEL__ */
 #endif /* _SPARC_PROM_H */
index bdfafd7..bac6a94 100644 (file)
@@ -73,7 +73,7 @@ static inline long regs_return_value(struct pt_regs *regs)
        return regs->u_regs[UREG_I0];
 }
 #ifdef CONFIG_SMP
-extern unsigned long profile_pc(struct pt_regs *);
+unsigned long profile_pc(struct pt_regs *);
 #else
 #define profile_pc(regs) instruction_pointer(regs)
 #endif
index 5e35e05..f5fffd8 100644 (file)
@@ -4,8 +4,9 @@
 #ifndef _SPARC_SETUP_H
 #define _SPARC_SETUP_H
 
-#include <uapi/asm/setup.h>
+#include <linux/interrupt.h>
 
+#include <uapi/asm/setup.h>
 
 extern char reboot_command[];
 
@@ -22,9 +23,43 @@ static inline int con_is_present(void)
 {
        return serial_console ? 0 : 1;
 }
+
+/* from irq_32.c */
+extern volatile unsigned char *fdc_status;
+extern char *pdma_vaddr;
+extern unsigned long pdma_size;
+extern volatile int doing_pdma;
+
+/* This is software state */
+extern char *pdma_base;
+extern unsigned long pdma_areasize;
+
+int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler);
+
+/* setup_32.c */
+extern unsigned long cmdline_memory_size;
+
+/* devices.c */
+void __init device_scan(void);
+
+/* unaligned_32.c */
+unsigned long safe_compute_effective_address(struct pt_regs *, unsigned int);
+
+#endif
+
+#ifdef CONFIG_SPARC64
+/* unaligned_64.c */
+int handle_ldf_stq(u32 insn, struct pt_regs *regs);
+void handle_ld_nf(u32 insn, struct pt_regs *regs);
+
+/* init_64.c */
+extern atomic_t dcpage_flushes;
+extern atomic_t dcpage_flushes_xcall;
+
+extern int sysctl_tsb_ratio;
 #endif
 
-extern void sun_do_break(void);
+void sun_do_break(void);
 extern int stop_a_enabled;
 extern int scons_pwroff;
 
index 01d9c3b..838c9d5 100644 (file)
@@ -79,9 +79,9 @@
   __asm__ ("addcc %r7,%8,%2\n\t"                                       \
           "addxcc %r5,%6,%1\n\t"                                       \
           "addx %r3,%4,%0\n"                                           \
-          : "=r" ((USItype)(r2)),                                      \
-            "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
+          : "=r" (r2),                                                 \
+            "=&r" (r1),                                                \
+            "=&r" (r0)                                                 \
           : "%rJ" ((USItype)(x2)),                                     \
             "rI" ((USItype)(y2)),                                      \
             "%rJ" ((USItype)(x1)),                                     \
@@ -94,9 +94,9 @@
   __asm__ ("subcc %r7,%8,%2\n\t"                                       \
            "subxcc %r5,%6,%1\n\t"                                      \
            "subx %r3,%4,%0\n"                                          \
-          : "=r" ((USItype)(r2)),                                      \
-            "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
+          : "=r" (r2),                                                 \
+            "=&r" (r1),                                                \
+            "=&r" (r0)                                                 \
           : "%rJ" ((USItype)(x2)),                                     \
             "rI" ((USItype)(y2)),                                      \
             "%rJ" ((USItype)(x1)),                                     \
            "addxcc %r6,%7,%0\n\t"                                      \
            "addxcc %r4,%5,%%g2\n\t"                                    \
            "addx %r2,%3,%%g1\n\t"                                      \
-          : "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
+          : "=&r" (r1),                                                \
+            "=&r" (r0)                                                 \
           : "%rJ" ((USItype)(x3)),                                     \
             "rI" ((USItype)(y3)),                                      \
             "%rJ" ((USItype)(x2)),                                     \
            "subxcc %r6,%7,%0\n\t"                                      \
            "subxcc %r4,%5,%%g2\n\t"                                    \
            "subx %r2,%3,%%g1\n\t"                                      \
-          : "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
+          : "=&r" (r1),                                                \
+            "=&r" (r0)                                                 \
           : "%rJ" ((USItype)(x3)),                                     \
             "rI" ((USItype)(y3)),                                      \
             "%rJ" ((USItype)(x2)),                                     \
           "addxcc %2,%%g0,%2\n\t"                                      \
           "addxcc %1,%%g0,%1\n\t"                                      \
           "addx %0,%%g0,%0\n\t"                                        \
-          : "=&r" ((USItype)(x3)),                                     \
-            "=&r" ((USItype)(x2)),                                     \
-            "=&r" ((USItype)(x1)),                                     \
-            "=&r" ((USItype)(x0))                                      \
+          : "=&r" (x3),                                                \
+            "=&r" (x2),                                                \
+            "=&r" (x1),                                                \
+            "=&r" (x0)                                                 \
           : "rI" ((USItype)(i)),                                       \
             "0" ((USItype)(x3)),                                       \
             "1" ((USItype)(x2)),                                       \
index 3c8917f..7c24e08 100644 (file)
@@ -93,15 +93,15 @@ static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
                                    arg1, arg2, arg3, arg4);
 }
 
-extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+void arch_send_call_function_single_ipi(int cpu);
+void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
 static inline int cpu_logical_map(int cpu)
 {
        return cpu;
 }
 
-extern int hard_smp_processor_id(void);
+int hard_smp_processor_id(void);
 
 #define raw_smp_processor_id()         (current_thread_info()->cpu)
 
index 0571039..26d9e77 100644 (file)
 DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
 extern cpumask_t cpu_core_map[NR_CPUS];
 
-extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+void arch_send_call_function_single_ipi(int cpu);
+void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
 /*
  *     General functions that each host system must provide.
  */
 
-extern int hard_smp_processor_id(void);
+int hard_smp_processor_id(void);
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
-extern void smp_fill_in_sib_core_maps(void);
-extern void cpu_play_dead(void);
+void smp_fill_in_sib_core_maps(void);
+void cpu_play_dead(void);
 
-extern void smp_fetch_global_regs(void);
-extern void smp_fetch_global_pmu(void);
+void smp_fetch_global_regs(void);
+void smp_fetch_global_pmu(void);
 
 struct seq_file;
 void smp_bogo(struct seq_file *);
 void smp_info(struct seq_file *);
 
+void smp_callin(void);
+void cpu_panic(void);
+void smp_synchronize_tick_client(void);
+void smp_capture(void);
+void smp_release(void);
+
 #ifdef CONFIG_HOTPLUG_CPU
-extern int __cpu_disable(void);
-extern void __cpu_die(unsigned int cpu);
+int __cpu_disable(void);
+void __cpu_die(unsigned int cpu);
 #endif
 
 #endif /* !(__ASSEMBLY__) */
index 6b67e50..3fc5869 100644 (file)
@@ -62,7 +62,7 @@ extern enum ultra_tlb_layout tlb_type;
 extern int sun4v_chip_type;
 
 extern int cheetah_pcache_forced_on;
-extern void cheetah_enable_pcache(void);
+void cheetah_enable_pcache(void);
 
 #define sparc64_highest_locked_tlbent()        \
        (tlb_type == spitfire ? \
index 6cee39a..c30d066 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _SPARC64_STACKTRACE_H
 #define _SPARC64_STACKTRACE_H
 
-extern void stack_trace_flush(void);
+void stack_trace_flush(void);
 
 #endif /* _SPARC64_STACKTRACE_H */
index d56ce60..c100dc2 100644 (file)
 
 extern int this_is_starfire;
 
-extern void check_if_starfire(void);
-extern int starfire_hard_smp_processor_id(void);
-extern void starfire_hookup(int);
-extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
+void check_if_starfire(void);
+int starfire_hard_smp_processor_id(void);
+void starfire_hookup(int);
+unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
 
 #endif
 #endif
index 12f6785..69974e9 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifdef __KERNEL__
 
-extern void __memmove(void *,const void *,__kernel_size_t);
+void __memmove(void *,const void *,__kernel_size_t);
 
 #ifndef EXPORT_SYMTAB_STROPS
 
@@ -40,8 +40,8 @@ extern void __memmove(void *,const void *,__kernel_size_t);
 #undef memscan
 #define memscan(__arg0, __char, __arg2)                                                \
 ({                                                                             \
-       extern void *__memscan_zero(void *, size_t);                            \
-       extern void *__memscan_generic(void *, int, size_t);                    \
+       void *__memscan_zero(void *, size_t);                                   \
+       void *__memscan_generic(void *, int, size_t);                           \
        void *__retval, *__addr = (__arg0);                                     \
        size_t __size = (__arg2);                                               \
                                                                                \
@@ -54,14 +54,14 @@ extern void __memmove(void *,const void *,__kernel_size_t);
 })
 
 #define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *,const void *,__kernel_size_t);
+int memcmp(const void *,const void *,__kernel_size_t);
 
 /* Now the str*() stuff... */
 #define __HAVE_ARCH_STRLEN
-extern __kernel_size_t strlen(const char *);
+__kernel_size_t strlen(const char *);
 
 #define __HAVE_ARCH_STRNCMP
-extern int strncmp(const char *, const char *, __kernel_size_t);
+int strncmp(const char *, const char *, __kernel_size_t);
 
 #endif /* !EXPORT_SYMTAB_STROPS */
 
index 9623bc2..5936b8f 100644 (file)
@@ -19,7 +19,7 @@
 
 /* First the mem*() things. */
 #define __HAVE_ARCH_MEMMOVE
-extern void *memmove(void *, const void *, __kernel_size_t);
+void *memmove(void *, const void *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCPY
 #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
@@ -32,8 +32,8 @@ extern void *memmove(void *, const void *, __kernel_size_t);
 #undef memscan
 #define memscan(__arg0, __char, __arg2)                                        \
 ({                                                                     \
-       extern void *__memscan_zero(void *, size_t);                    \
-       extern void *__memscan_generic(void *, int, size_t);            \
+       void *__memscan_zero(void *, size_t);                           \
+       void *__memscan_generic(void *, int, size_t);                   \
        void *__retval, *__addr = (__arg0);                             \
        size_t __size = (__arg2);                                       \
                                                                        \
@@ -46,14 +46,14 @@ extern void *memmove(void *, const void *, __kernel_size_t);
 })
 
 #define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *,const void *,__kernel_size_t);
+int memcmp(const void *,const void *,__kernel_size_t);
 
 /* Now the str*() stuff... */
 #define __HAVE_ARCH_STRLEN
-extern __kernel_size_t strlen(const char *);
+__kernel_size_t strlen(const char *);
 
 #define __HAVE_ARCH_STRNCMP
-extern int strncmp(const char *, const char *, __kernel_size_t);
+int strncmp(const char *, const char *, __kernel_size_t);
 
 #endif /* !EXPORT_SYMTAB_STROPS */
 
index e32e82b..16f1037 100644 (file)
@@ -99,8 +99,8 @@ extern struct thread_info *current_set[NR_CPUS];
          "o0", "o1", "o2", "o3",                   "o7");      \
        } while(0)
 
-extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
-                  void *fpqueue, unsigned long *fpqdepth);
-extern void synchronize_user_stack(void);
+void fpsave(unsigned long *fpregs, unsigned long *fsr,
+           void *fpqueue, unsigned long *fpqdepth);
+void synchronize_user_stack(void);
 
 #endif /* __SPARC_SWITCH_TO_H */
index 8d28480..10e7633 100644 (file)
@@ -65,7 +65,7 @@ do {  save_and_clear_fpu();                                           \
          "o0", "o1", "o2", "o3", "o4", "o5",       "o7");              \
 } while(0)
 
-extern void synchronize_user_stack(void);
-extern void fault_in_user_windows(void);
+void synchronize_user_stack(void);
+void fault_in_user_windows(void);
 
 #endif /* __SPARC64_SWITCH_TO_64_H */
index bf8972a..b0a0db8 100644 (file)
@@ -3,9 +3,9 @@
 
 struct pt_regs;
 
-extern asmlinkage long sparc_do_fork(unsigned long clone_flags,
-                                    unsigned long stack_start,
-                                    struct pt_regs *regs,
-                                    unsigned long stack_size);
+asmlinkage long sparc_do_fork(unsigned long clone_flags,
+                             unsigned long stack_start,
+                             struct pt_regs *regs,
+                             unsigned long stack_size);
 
 #endif /* _SPARC64_SYSCALLS_H */
index 72f40a5..f8e708a 100644 (file)
@@ -32,13 +32,13 @@ static inline unsigned int timer_value(unsigned int value)
        return (value + 1) << TIMER_VALUE_SHIFT;
 }
 
-extern __volatile__ unsigned int *master_l10_counter;
+extern volatile u32 __iomem *master_l10_counter;
 
-extern irqreturn_t notrace timer_interrupt(int dummy, void *dev_id);
+irqreturn_t notrace timer_interrupt(int dummy, void *dev_id);
 
 #ifdef CONFIG_SMP
 DECLARE_PER_CPU(struct clock_event_device, sparc32_clockevent);
-extern void register_percpu_ce(int cpu);
+void register_percpu_ce(int cpu);
 #endif
 
 #endif /* !(_SPARC_TIMER_H) */
index 01197d8..fce4150 100644 (file)
@@ -23,8 +23,8 @@ struct sparc64_tick_ops {
 
 extern struct sparc64_tick_ops *tick_ops;
 
-extern unsigned long sparc64_get_clock_tick(unsigned int cpu);
-extern void setup_sparc64_timer(void);
-extern void __init time_init(void);
+unsigned long sparc64_get_clock_tick(unsigned int cpu);
+void setup_sparc64_timer(void);
+void __init time_init(void);
 
 #endif /* _SPARC64_TIMER_H */
index 190e189..4cb392f 100644 (file)
@@ -8,19 +8,19 @@
 #include <asm/mmu_context.h>
 
 #ifdef CONFIG_SMP
-extern void smp_flush_tlb_pending(struct mm_struct *,
+void smp_flush_tlb_pending(struct mm_struct *,
                                  unsigned long, unsigned long *);
 #endif
 
 #ifdef CONFIG_SMP
-extern void smp_flush_tlb_mm(struct mm_struct *mm);
+void smp_flush_tlb_mm(struct mm_struct *mm);
 #define do_flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
 #else
 #define do_flush_tlb_mm(mm) __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT)
 #endif
 
-extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *);
-extern void flush_tlb_pending(void);
+void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *);
+void flush_tlb_pending(void);
 
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma)  do { } while (0)
index 3c3c89f..816d820 100644 (file)
@@ -14,9 +14,9 @@ struct tlb_batch {
        unsigned long vaddrs[TLB_BATCH_NR];
 };
 
-extern void flush_tsb_kernel_range(unsigned long start, unsigned long end);
-extern void flush_tsb_user(struct tlb_batch *tb);
-extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
+void flush_tsb_kernel_range(unsigned long start, unsigned long end);
+void flush_tsb_user(struct tlb_batch *tb);
+void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
 
 /* TLB flush operations. */
 
@@ -36,15 +36,15 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
 
 #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
 
-extern void flush_tlb_pending(void);
-extern void arch_enter_lazy_mmu_mode(void);
-extern void arch_leave_lazy_mmu_mode(void);
+void flush_tlb_pending(void);
+void arch_enter_lazy_mmu_mode(void);
+void arch_leave_lazy_mmu_mode(void);
 #define arch_flush_lazy_mmu_mode()      do {} while (0)
 
 /* Local cpu only.  */
-extern void __flush_tlb_all(void);
-extern void __flush_tlb_page(unsigned long context, unsigned long vaddr);
-extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
+void __flush_tlb_all(void);
+void __flush_tlb_page(unsigned long context, unsigned long vaddr);
+void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
 #ifndef CONFIG_SMP
 
@@ -60,8 +60,8 @@ static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vad
 
 #else /* CONFIG_SMP */
 
-extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
-extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
+void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
+void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
 
 #define flush_tlb_kernel_range(start, end) \
 do {   flush_tsb_kernel_range(start,end); \
index a2d10fc..ed8f071 100644 (file)
@@ -18,7 +18,7 @@ static inline int cpu_to_node(int cpu)
 
 struct pci_bus;
 #ifdef CONFIG_PCI
-extern int pcibus_to_node(struct pci_bus *pbus);
+int pcibus_to_node(struct pci_bus *pbus);
 #else
 static inline int pcibus_to_node(struct pci_bus *pbus)
 {
index 7e26b2d..6fd4436 100644 (file)
@@ -51,11 +51,11 @@ struct trap_per_cpu {
        unsigned long           __per_cpu_base;
 } __attribute__((aligned(64)));
 extern struct trap_per_cpu trap_block[NR_CPUS];
-extern void init_cur_cpu_trap(struct thread_info *);
-extern void setup_tba(void);
+void init_cur_cpu_trap(struct thread_info *);
+void setup_tba(void);
 extern int ncpus_probed;
 
-extern unsigned long real_hard_smp_processor_id(void);
+unsigned long real_hard_smp_processor_id(void);
 
 struct cpuid_patch_entry {
        unsigned int    addr;
index 0167d26..bd56c28 100644 (file)
@@ -9,6 +9,6 @@
 #define user_addr_max() \
        (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
 
-extern long strncpy_from_user(char *dest, const char __user *src, long count);
+long strncpy_from_user(char *dest, const char __user *src, long count);
 
 #endif
index 53a28dd..9634d08 100644 (file)
@@ -78,9 +78,9 @@ struct exception_table_entry
 };
 
 /* Returns 0 if exception not found and fixup otherwise.  */
-extern unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
+unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
 
-extern void __ret_efault(void);
+void __ret_efault(void);
 
 /* Uh, these should become the main single-value transfer routines..
  * They automatically use the right size if we just have the right
@@ -152,7 +152,7 @@ __asm__ __volatile__(                                                       \
        : "=&r" (ret) : "r" (x), "m" (*__m(addr)),                      \
         "i" (-EFAULT))
 
-extern int __put_user_bad(void);
+int __put_user_bad(void);
 
 #define __get_user_check(x,addr,size,type) ({ \
 register int __gu_ret; \
@@ -244,9 +244,9 @@ __asm__ __volatile__(                                                       \
        ".previous\n\t"                                                 \
        : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
 
-extern int __get_user_bad(void);
+int __get_user_bad(void);
 
-extern unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size);
+unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size);
 
 static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
 {
@@ -306,8 +306,8 @@ static inline unsigned long clear_user(void __user *addr, unsigned long n)
                return n;
 }
 
-extern __must_check long strlen_user(const char __user *str);
-extern __must_check long strnlen_user(const char __user *str, long n);
+__must_check long strlen_user(const char __user *str);
+__must_check long strnlen_user(const char __user *str, long n);
 
 #endif  /* __ASSEMBLY__ */
 
index ad7e178..c990a5e 100644 (file)
@@ -76,8 +76,8 @@ struct exception_table_entry {
         unsigned int insn, fixup;
 };
 
-extern void __ret_efault(void);
-extern void __retl_efault(void);
+void __ret_efault(void);
+void __retl_efault(void);
 
 /* Uh, these should become the main single-value transfer routines..
  * They automatically use the right size if we just have the right
@@ -134,7 +134,7 @@ __asm__ __volatile__(                                                       \
        : "=r" (ret) : "r" (x), "r" (__m(addr)),                                \
         "i" (-EFAULT))
 
-extern int __put_user_bad(void);
+int __put_user_bad(void);
 
 #define __get_user_nocheck(data,addr,size,type) ({ \
 register int __gu_ret; \
@@ -204,13 +204,13 @@ __asm__ __volatile__(                                                     \
        ".previous\n\t"                                                 \
        : "=r" (x) : "r" (__m(addr)), "i" (retval))
 
-extern int __get_user_bad(void);
+int __get_user_bad(void);
 
-extern unsigned long __must_check ___copy_from_user(void *to,
-                                                   const void __user *from,
-                                                   unsigned long size);
-extern unsigned long copy_from_user_fixup(void *to, const void __user *from,
-                                         unsigned long size);
+unsigned long __must_check ___copy_from_user(void *to,
+                                            const void __user *from,
+                                            unsigned long size);
+unsigned long copy_from_user_fixup(void *to, const void __user *from,
+                                  unsigned long size);
 static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long size)
 {
@@ -223,11 +223,11 @@ copy_from_user(void *to, const void __user *from, unsigned long size)
 }
 #define __copy_from_user copy_from_user
 
-extern unsigned long __must_check ___copy_to_user(void __user *to,
-                                                 const void *from,
-                                                 unsigned long size);
-extern unsigned long copy_to_user_fixup(void __user *to, const void *from,
-                                       unsigned long size);
+unsigned long __must_check ___copy_to_user(void __user *to,
+                                          const void *from,
+                                          unsigned long size);
+unsigned long copy_to_user_fixup(void __user *to, const void *from,
+                                unsigned long size);
 static inline unsigned long __must_check
 copy_to_user(void __user *to, const void *from, unsigned long size)
 {
@@ -239,11 +239,11 @@ copy_to_user(void __user *to, const void *from, unsigned long size)
 }
 #define __copy_to_user copy_to_user
 
-extern unsigned long __must_check ___copy_in_user(void __user *to,
-                                                 const void __user *from,
-                                                 unsigned long size);
-extern unsigned long copy_in_user_fixup(void __user *to, void __user *from,
-                                       unsigned long size);
+unsigned long __must_check ___copy_in_user(void __user *to,
+                                          const void __user *from,
+                                          unsigned long size);
+unsigned long copy_in_user_fixup(void __user *to, void __user *from,
+                                unsigned long size);
 static inline unsigned long __must_check
 copy_in_user(void __user *to, void __user *from, unsigned long size)
 {
@@ -255,20 +255,20 @@ copy_in_user(void __user *to, void __user *from, unsigned long size)
 }
 #define __copy_in_user copy_in_user
 
-extern unsigned long __must_check __clear_user(void __user *, unsigned long);
+unsigned long __must_check __clear_user(void __user *, unsigned long);
 
 #define clear_user __clear_user
 
-extern __must_check long strlen_user(const char __user *str);
-extern __must_check long strnlen_user(const char __user *str, long n);
+__must_check long strlen_user(const char __user *str);
+__must_check long strnlen_user(const char __user *str, long n);
 
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
 struct pt_regs;
-extern unsigned long compute_effective_address(struct pt_regs *,
-                                              unsigned int insn,
-                                              unsigned int rd);
+unsigned long compute_effective_address(struct pt_regs *,
+                                       unsigned int insn,
+                                       unsigned int rd);
 
 #endif  /* __ASSEMBLY__ */
 
index 432afa8..e0f6c39 100644 (file)
@@ -372,14 +372,14 @@ do {      if (vio->debug & VIO_DEBUG_##TYPE) \
                       vio->vdev->channel_id, ## a); \
 } while (0)
 
-extern int __vio_register_driver(struct vio_driver *drv, struct module *owner,
+int __vio_register_driver(struct vio_driver *drv, struct module *owner,
                                 const char *mod_name);
 /*
  * vio_register_driver must be a macro so that KBUILD_MODNAME can be expanded
  */
 #define vio_register_driver(driver)            \
        __vio_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
-extern void vio_unregister_driver(struct vio_driver *drv);
+void vio_unregister_driver(struct vio_driver *drv);
 
 static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
 {
@@ -391,21 +391,21 @@ static inline struct vio_dev *to_vio_dev(struct device *dev)
        return container_of(dev, struct vio_dev, dev);
 }
 
-extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
-extern void vio_link_state_change(struct vio_driver_state *vio, int event);
-extern void vio_conn_reset(struct vio_driver_state *vio);
-extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt);
-extern int vio_validate_sid(struct vio_driver_state *vio,
-                           struct vio_msg_tag *tp);
-extern u32 vio_send_sid(struct vio_driver_state *vio);
-extern int vio_ldc_alloc(struct vio_driver_state *vio,
-                        struct ldc_channel_config *base_cfg, void *event_arg);
-extern void vio_ldc_free(struct vio_driver_state *vio);
-extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
-                          u8 dev_class, struct vio_version *ver_table,
-                          int ver_table_size, struct vio_driver_ops *ops,
-                          char *name);
-
-extern void vio_port_up(struct vio_driver_state *vio);
+int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
+void vio_link_state_change(struct vio_driver_state *vio, int event);
+void vio_conn_reset(struct vio_driver_state *vio);
+int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt);
+int vio_validate_sid(struct vio_driver_state *vio,
+                    struct vio_msg_tag *tp);
+u32 vio_send_sid(struct vio_driver_state *vio);
+int vio_ldc_alloc(struct vio_driver_state *vio,
+                 struct ldc_channel_config *base_cfg, void *event_arg);
+void vio_ldc_free(struct vio_driver_state *vio);
+int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
+                   u8 dev_class, struct vio_version *ver_table,
+                   int ver_table_size, struct vio_driver_ops *ops,
+                   char *name);
+
+void vio_port_up(struct vio_driver_state *vio);
 
 #endif /* _SPARC64_VIO_H */
index 39ca301..b266737 100644 (file)
@@ -57,7 +57,8 @@ static inline void save_and_clear_fpu(void) {
 "              " : : "i" (FPRS_FEF|FPRS_DU) :
                "o5", "g1", "g2", "g3", "g7", "cc");
 }
-extern int vis_emul(struct pt_regs *, unsigned int);
+
+int vis_emul(struct pt_regs *, unsigned int);
 #endif
 
 #endif /* _SPARC64_ASI_H */
index ee8edc6..50c8828 100644 (file)
 
 #include <asm/spitfire.h>
 
-extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
-                     unsigned long *);
-extern void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
-                     unsigned long *, unsigned long *);
-extern void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
-                     unsigned long *, unsigned long *, unsigned long *);
+void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
+void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
+              unsigned long *);
+void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
+              unsigned long *, unsigned long *);
+void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
+              unsigned long *, unsigned long *, unsigned long *);
 
 /* XXX Ugh, write cheetah versions... -DaveM */
 
@@ -38,13 +38,13 @@ static struct xor_block_template xor_block_VIS = {
         .do_5  = xor_vis_5,
 };
 
-extern void xor_niagara_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_niagara_3(unsigned long, unsigned long *, unsigned long *,
-                         unsigned long *);
-extern void xor_niagara_4(unsigned long, unsigned long *, unsigned long *,
-                         unsigned long *, unsigned long *);
-extern void xor_niagara_5(unsigned long, unsigned long *, unsigned long *,
-                         unsigned long *, unsigned long *, unsigned long *);
+void xor_niagara_2(unsigned long, unsigned long *, unsigned long *);
+void xor_niagara_3(unsigned long, unsigned long *, unsigned long *,
+                  unsigned long *);
+void xor_niagara_4(unsigned long, unsigned long *, unsigned long *,
+                  unsigned long *, unsigned long *);
+void xor_niagara_5(unsigned long, unsigned long *, unsigned long *,
+                  unsigned long *, unsigned long *, unsigned long *);
 
 static struct xor_block_template xor_block_niagara = {
         .name  = "Niagara",
index d15cc17..7cf9c6e 100644 (file)
@@ -42,7 +42,6 @@ obj-y                   += time_$(BITS).o
 obj-$(CONFIG_SPARC32)   += windows.o
 obj-y                   += cpu.o
 obj-$(CONFIG_SPARC32)   += devices.o
-obj-$(CONFIG_SPARC32)   += tadpole.o
 obj-y                   += ptrace_$(BITS).o
 obj-y                   += unaligned_$(BITS).o
 obj-y                   += una_asm_$(BITS).o
index 8fff0ac..24361b4 100644 (file)
@@ -3,6 +3,8 @@
 #include <linux/audit.h>
 #include <asm/unistd.h>
 
+#include "kernel.h"
+
 static unsigned dir_class[] = {
 #include <asm-generic/audit_dir_write.h>
 ~0U
@@ -40,7 +42,6 @@ int audit_classify_arch(int arch)
 int audit_classify_syscall(int abi, unsigned syscall)
 {
 #ifdef CONFIG_COMPAT
-       extern int sparc32_classify_syscall(unsigned);
        if (abi == AUDIT_ARCH_SPARC)
                return sparc32_classify_syscall(syscall);
 #endif
@@ -61,11 +62,6 @@ int audit_classify_syscall(int abi, unsigned syscall)
 static int __init audit_classes_init(void)
 {
 #ifdef CONFIG_COMPAT
-       extern __u32 sparc32_dir_class[];
-       extern __u32 sparc32_write_class[];
-       extern __u32 sparc32_read_class[];
-       extern __u32 sparc32_chattr_class[];
-       extern __u32 sparc32_signal_class[];
        audit_register_class(AUDIT_CLASS_WRITE_32, sparc32_write_class);
        audit_register_class(AUDIT_CLASS_READ_32, sparc32_read_class);
        audit_register_class(AUDIT_CLASS_DIR_WRITE_32, sparc32_dir_class);
index e20cc55..ae88c22 100644 (file)
@@ -9,12 +9,15 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/export.h>
+
 #include <asm/oplib.h>
 #include <asm/io.h>
 #include <asm/auxio.h>
 #include <asm/string.h>                /* memset(), Linux has no bzero() */
 #include <asm/cpu_type.h>
 
+#include "kernel.h"
+
 /* Probe and map in the Auxiliary I/O register */
 
 /* auxio_register is not static because it is referenced 
@@ -103,7 +106,7 @@ EXPORT_SYMBOL(set_auxio);
 
 /* sun4m power control register (AUXIO2) */
 
-volatile unsigned char * auxio_power_register = NULL;
+volatile u8 __iomem *auxio_power_register = NULL;
 
 void __init auxio_power_probe(void)
 {
@@ -127,8 +130,8 @@ void __init auxio_power_probe(void)
        r.flags = regs.which_io & 0xF;
        r.start = regs.phys_addr;
        r.end = regs.phys_addr + regs.reg_size - 1;
-       auxio_power_register = (unsigned char *) of_ioremap(&r, 0,
-           regs.reg_size, "auxpower");
+       auxio_power_register =
+               (u8 __iomem *)of_ioremap(&r, 0, regs.reg_size, "auxpower");
 
        /* Display a quick message on the console. */
        if (auxio_power_register)
index 57073e5..987f7ec 100644 (file)
@@ -137,7 +137,7 @@ static void scrollscreen(void)
 }
 #endif /* ndef NO_SCROLL */
 
-void btext_drawchar(char c)
+static void btext_drawchar(char c)
 {
        int cline = 0;
 #ifdef NO_SCROLL
index d865575..7062263 100644 (file)
@@ -1,5 +1,6 @@
 #define __32bit_syscall_numbers__
 #include <asm/unistd.h>
+#include "kernel.h"
 
 unsigned sparc32_dir_class[] = {
 #include <asm-generic/audit_dir_write.h>
index 5c51258..82a3a71 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/cpudata.h>
 
 #include "kernel.h"
+#include "entry.h"
 
 DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
 EXPORT_PER_CPU_SYMBOL(__cpu_data);
index e639880..9dac398 100644 (file)
@@ -2,8 +2,8 @@
 #define _CPUMAP_H
 
 #ifdef CONFIG_SMP
-extern void cpu_map_rebuild(void);
-extern int  map_to_cpu(unsigned int index);
+void cpu_map_rebuild(void);
+int map_to_cpu(unsigned int index);
 #define cpu_map_init() cpu_map_rebuild()
 #else
 #define cpu_map_init() do {} while (0)
index 3d465e8..8d5d09f 100644 (file)
@@ -19,8 +19,9 @@
 #include <asm/smp.h>
 #include <asm/cpudata.h>
 #include <asm/cpu_type.h>
+#include <asm/setup.h>
 
-extern void clock_stop_probe(void); /* tadpole.c */
+#include "kernel.h"
 
 static char *cpu_mid_prop(void)
 {
@@ -131,11 +132,6 @@ void __init device_scan(void)
        }
 #endif /* !CONFIG_SMP */
 
-       {
-               extern void auxio_probe(void);
-               extern void auxio_power_probe(void);
-               auxio_probe();
-               auxio_power_probe();
-       }
-       clock_stop_probe();
+       auxio_probe();
+       auxio_power_probe();
 }
index 140966f..ebaba61 100644 (file)
@@ -6,40 +6,39 @@
 #include <linux/init.h>
 
 /* irq */
-extern void handler_irq(int irq, struct pt_regs *regs);
+void handler_irq(int irq, struct pt_regs *regs);
 
 #ifdef CONFIG_SPARC32
 /* traps */
-extern void do_hw_interrupt(struct pt_regs *regs, unsigned long type);
-extern void do_illegal_instruction(struct pt_regs *regs, unsigned long pc,
-                                   unsigned long npc, unsigned long psr);
-
-extern void do_priv_instruction(struct pt_regs *regs, unsigned long pc,
-                                unsigned long npc, unsigned long psr);
-extern void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc,
-                                   unsigned long npc,
-                                   unsigned long psr);
-extern void do_fpd_trap(struct pt_regs *regs, unsigned long pc,
+void do_hw_interrupt(struct pt_regs *regs, unsigned long type);
+void do_illegal_instruction(struct pt_regs *regs, unsigned long pc,
+                            unsigned long npc, unsigned long psr);
+
+void do_priv_instruction(struct pt_regs *regs, unsigned long pc,
+                         unsigned long npc, unsigned long psr);
+void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc,
+                            unsigned long npc, unsigned long psr);
+void do_fpd_trap(struct pt_regs *regs, unsigned long pc,
+                 unsigned long npc, unsigned long psr);
+void do_fpe_trap(struct pt_regs *regs, unsigned long pc,
+                 unsigned long npc, unsigned long psr);
+void handle_tag_overflow(struct pt_regs *regs, unsigned long pc,
+                         unsigned long npc, unsigned long psr);
+void handle_watchpoint(struct pt_regs *regs, unsigned long pc,
+                       unsigned long npc, unsigned long psr);
+void handle_reg_access(struct pt_regs *regs, unsigned long pc,
+                       unsigned long npc, unsigned long psr);
+void handle_cp_disabled(struct pt_regs *regs, unsigned long pc,
                         unsigned long npc, unsigned long psr);
-extern void do_fpe_trap(struct pt_regs *regs, unsigned long pc,
-                        unsigned long npc, unsigned long psr);
-extern void handle_tag_overflow(struct pt_regs *regs, unsigned long pc,
-                                unsigned long npc, unsigned long psr);
-extern void handle_watchpoint(struct pt_regs *regs, unsigned long pc,
-                              unsigned long npc, unsigned long psr);
-extern void handle_reg_access(struct pt_regs *regs, unsigned long pc,
-                              unsigned long npc, unsigned long psr);
-extern void handle_cp_disabled(struct pt_regs *regs, unsigned long pc,
-                               unsigned long npc, unsigned long psr);
-extern void handle_cp_exception(struct pt_regs *regs, unsigned long pc,
-                                unsigned long npc, unsigned long psr);
+void handle_cp_exception(struct pt_regs *regs, unsigned long pc,
+                         unsigned long npc, unsigned long psr);
 
 
 
 /* entry.S */
-extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
-                   void *fpqueue, unsigned long *fpqdepth);
-extern void fpload(unsigned long *fpregs, unsigned long *fsr);
+void fpsave(unsigned long *fpregs, unsigned long *fsr,
+            void *fpqueue, unsigned long *fpqdepth);
+void fpload(unsigned long *fpregs, unsigned long *fsr);
 
 #else /* CONFIG_SPARC32 */
 
@@ -66,123 +65,123 @@ struct pause_patch_entry {
 extern struct pause_patch_entry __pause_3insn_patch,
        __pause_3insn_patch_end;
 
-extern void __init per_cpu_patch(void);
-extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
-                                   struct sun4v_1insn_patch_entry *);
-extern void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
-                                   struct sun4v_2insn_patch_entry *);
-extern void __init sun4v_patch(void);
-extern void __init boot_cpu_id_too_large(int cpu);
+void __init per_cpu_patch(void);
+void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
+                            struct sun4v_1insn_patch_entry *);
+void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
+                            struct sun4v_2insn_patch_entry *);
+void __init sun4v_patch(void);
+void __init boot_cpu_id_too_large(int cpu);
 extern unsigned int dcache_parity_tl1_occurred;
 extern unsigned int icache_parity_tl1_occurred;
 
-extern asmlinkage void sparc_breakpoint(struct pt_regs *regs);
-extern void timer_interrupt(int irq, struct pt_regs *regs);
-
-extern void do_notify_resume(struct pt_regs *regs,
-                            unsigned long orig_i0,
-                            unsigned long thread_info_flags);
-
-extern asmlinkage int syscall_trace_enter(struct pt_regs *regs);
-extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
-
-extern void bad_trap_tl1(struct pt_regs *regs, long lvl);
-
-extern void do_fpieee(struct pt_regs *regs);
-extern void do_fpother(struct pt_regs *regs);
-extern void do_tof(struct pt_regs *regs);
-extern void do_div0(struct pt_regs *regs);
-extern void do_illegal_instruction(struct pt_regs *regs);
-extern void mem_address_unaligned(struct pt_regs *regs,
-                                 unsigned long sfar,
-                                 unsigned long sfsr);
-extern void sun4v_do_mna(struct pt_regs *regs,
-                        unsigned long addr,
-                        unsigned long type_ctx);
-extern void do_privop(struct pt_regs *regs);
-extern void do_privact(struct pt_regs *regs);
-extern void do_cee(struct pt_regs *regs);
-extern void do_cee_tl1(struct pt_regs *regs);
-extern void do_dae_tl1(struct pt_regs *regs);
-extern void do_iae_tl1(struct pt_regs *regs);
-extern void do_div0_tl1(struct pt_regs *regs);
-extern void do_fpdis_tl1(struct pt_regs *regs);
-extern void do_fpieee_tl1(struct pt_regs *regs);
-extern void do_fpother_tl1(struct pt_regs *regs);
-extern void do_ill_tl1(struct pt_regs *regs);
-extern void do_irq_tl1(struct pt_regs *regs);
-extern void do_lddfmna_tl1(struct pt_regs *regs);
-extern void do_stdfmna_tl1(struct pt_regs *regs);
-extern void do_paw(struct pt_regs *regs);
-extern void do_paw_tl1(struct pt_regs *regs);
-extern void do_vaw(struct pt_regs *regs);
-extern void do_vaw_tl1(struct pt_regs *regs);
-extern void do_tof_tl1(struct pt_regs *regs);
-extern void do_getpsr(struct pt_regs *regs);
-
-extern void spitfire_insn_access_exception(struct pt_regs *regs,
-                                          unsigned long sfsr,
-                                          unsigned long sfar);
-extern void spitfire_insn_access_exception_tl1(struct pt_regs *regs,
-                                              unsigned long sfsr,
-                                              unsigned long sfar);
-extern void spitfire_data_access_exception(struct pt_regs *regs,
-                                          unsigned long sfsr,
-                                          unsigned long sfar);
-extern void spitfire_data_access_exception_tl1(struct pt_regs *regs,
-                                              unsigned long sfsr,
-                                              unsigned long sfar);
-extern void spitfire_access_error(struct pt_regs *regs,
-                                 unsigned long status_encoded,
-                                 unsigned long afar);
-
-extern void cheetah_fecc_handler(struct pt_regs *regs,
-                                unsigned long afsr,
-                                unsigned long afar);
-extern void cheetah_cee_handler(struct pt_regs *regs,
-                               unsigned long afsr,
-                               unsigned long afar);
-extern void cheetah_deferred_handler(struct pt_regs *regs,
-                                    unsigned long afsr,
-                                    unsigned long afar);
-extern void cheetah_plus_parity_error(int type, struct pt_regs *regs);
-
-extern void sun4v_insn_access_exception(struct pt_regs *regs,
-                                       unsigned long addr,
-                                       unsigned long type_ctx);
-extern void sun4v_insn_access_exception_tl1(struct pt_regs *regs,
-                                           unsigned long addr,
-                                           unsigned long type_ctx);
-extern void sun4v_data_access_exception(struct pt_regs *regs,
-                                       unsigned long addr,
-                                       unsigned long type_ctx);
-extern void sun4v_data_access_exception_tl1(struct pt_regs *regs,
-                                           unsigned long addr,
-                                           unsigned long type_ctx);
-extern void sun4v_resum_error(struct pt_regs *regs,
-                             unsigned long offset);
-extern void sun4v_resum_overflow(struct pt_regs *regs);
-extern void sun4v_nonresum_error(struct pt_regs *regs,
-                                unsigned long offset);
-extern void sun4v_nonresum_overflow(struct pt_regs *regs);
+asmlinkage void sparc_breakpoint(struct pt_regs *regs);
+void timer_interrupt(int irq, struct pt_regs *regs);
+
+void do_notify_resume(struct pt_regs *regs,
+                     unsigned long orig_i0,
+                     unsigned long thread_info_flags);
+
+asmlinkage int syscall_trace_enter(struct pt_regs *regs);
+asmlinkage void syscall_trace_leave(struct pt_regs *regs);
+
+void bad_trap_tl1(struct pt_regs *regs, long lvl);
+
+void do_fpieee(struct pt_regs *regs);
+void do_fpother(struct pt_regs *regs);
+void do_tof(struct pt_regs *regs);
+void do_div0(struct pt_regs *regs);
+void do_illegal_instruction(struct pt_regs *regs);
+void mem_address_unaligned(struct pt_regs *regs,
+                          unsigned long sfar,
+                          unsigned long sfsr);
+void sun4v_do_mna(struct pt_regs *regs,
+                 unsigned long addr,
+                 unsigned long type_ctx);
+void do_privop(struct pt_regs *regs);
+void do_privact(struct pt_regs *regs);
+void do_cee(struct pt_regs *regs);
+void do_cee_tl1(struct pt_regs *regs);
+void do_dae_tl1(struct pt_regs *regs);
+void do_iae_tl1(struct pt_regs *regs);
+void do_div0_tl1(struct pt_regs *regs);
+void do_fpdis_tl1(struct pt_regs *regs);
+void do_fpieee_tl1(struct pt_regs *regs);
+void do_fpother_tl1(struct pt_regs *regs);
+void do_ill_tl1(struct pt_regs *regs);
+void do_irq_tl1(struct pt_regs *regs);
+void do_lddfmna_tl1(struct pt_regs *regs);
+void do_stdfmna_tl1(struct pt_regs *regs);
+void do_paw(struct pt_regs *regs);
+void do_paw_tl1(struct pt_regs *regs);
+void do_vaw(struct pt_regs *regs);
+void do_vaw_tl1(struct pt_regs *regs);
+void do_tof_tl1(struct pt_regs *regs);
+void do_getpsr(struct pt_regs *regs);
+
+void spitfire_insn_access_exception(struct pt_regs *regs,
+                                   unsigned long sfsr,
+                                   unsigned long sfar);
+void spitfire_insn_access_exception_tl1(struct pt_regs *regs,
+                                       unsigned long sfsr,
+                                       unsigned long sfar);
+void spitfire_data_access_exception(struct pt_regs *regs,
+                                   unsigned long sfsr,
+                                   unsigned long sfar);
+void spitfire_data_access_exception_tl1(struct pt_regs *regs,
+                                       unsigned long sfsr,
+                                       unsigned long sfar);
+void spitfire_access_error(struct pt_regs *regs,
+                          unsigned long status_encoded,
+                          unsigned long afar);
+
+void cheetah_fecc_handler(struct pt_regs *regs,
+                         unsigned long afsr,
+                         unsigned long afar);
+void cheetah_cee_handler(struct pt_regs *regs,
+                        unsigned long afsr,
+                        unsigned long afar);
+void cheetah_deferred_handler(struct pt_regs *regs,
+                             unsigned long afsr,
+                             unsigned long afar);
+void cheetah_plus_parity_error(int type, struct pt_regs *regs);
+
+void sun4v_insn_access_exception(struct pt_regs *regs,
+                                unsigned long addr,
+                                unsigned long type_ctx);
+void sun4v_insn_access_exception_tl1(struct pt_regs *regs,
+                                    unsigned long addr,
+                                    unsigned long type_ctx);
+void sun4v_data_access_exception(struct pt_regs *regs,
+                                unsigned long addr,
+                                unsigned long type_ctx);
+void sun4v_data_access_exception_tl1(struct pt_regs *regs,
+                                    unsigned long addr,
+                                    unsigned long type_ctx);
+void sun4v_resum_error(struct pt_regs *regs,
+                      unsigned long offset);
+void sun4v_resum_overflow(struct pt_regs *regs);
+void sun4v_nonresum_error(struct pt_regs *regs,
+                         unsigned long offset);
+void sun4v_nonresum_overflow(struct pt_regs *regs);
 
 extern unsigned long sun4v_err_itlb_vaddr;
 extern unsigned long sun4v_err_itlb_ctx;
 extern unsigned long sun4v_err_itlb_pte;
 extern unsigned long sun4v_err_itlb_error;
 
-extern void sun4v_itlb_error_report(struct pt_regs *regs, int tl);
+void sun4v_itlb_error_report(struct pt_regs *regs, int tl);
 
 extern unsigned long sun4v_err_dtlb_vaddr;
 extern unsigned long sun4v_err_dtlb_ctx;
 extern unsigned long sun4v_err_dtlb_pte;
 extern unsigned long sun4v_err_dtlb_error;
 
-extern void sun4v_dtlb_error_report(struct pt_regs *regs, int tl);
-extern void hypervisor_tlbop_error(unsigned long err,
-                                  unsigned long op);
-extern void hypervisor_tlbop_error_xcall(unsigned long err,
-                                        unsigned long op);
+void sun4v_dtlb_error_report(struct pt_regs *regs, int tl);
+void hypervisor_tlbop_error(unsigned long err,
+                           unsigned long op);
+void hypervisor_tlbop_error_xcall(unsigned long err,
+                                 unsigned long op);
 
 /* WARNING: The error trap handlers in assembly know the precise
  *         layout of the following structure.
@@ -248,8 +247,8 @@ struct ino_bucket {
 extern struct ino_bucket *ivector_table;
 extern unsigned long ivector_table_pa;
 
-extern void init_irqwork_curcpu(void);
-extern void sun4v_register_mondo_queues(int this_cpu);
+void init_irqwork_curcpu(void);
+void sun4v_register_mondo_queues(int this_cpu);
 
 #endif /* CONFIG_SPARC32 */
 #endif /* _ENTRY_H */
index 76663b0..bfa4d0c 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/iommu.h>
 
 #include "iommu_common.h"
+#include "kernel.h"
 
 #define STC_CTXMATCH_ADDR(STC, CTX)    \
        ((STC)->strbuf_ctxmatch_base + ((CTX) << 3))
@@ -840,8 +841,6 @@ static struct dma_map_ops sun4u_dma_ops = {
 struct dma_map_ops *dma_ops = &sun4u_dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
-extern int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask);
-
 int dma_supported(struct device *dev, u64 device_mask)
 {
        struct iommu *iommu = dev->archdata.iommu;
index 591f587..1ec0de4 100644 (file)
@@ -48,12 +48,12 @@ static inline int is_span_boundary(unsigned long entry,
        return iommu_is_span_boundary(entry, nr, shift, boundary_size);
 }
 
-extern unsigned long iommu_range_alloc(struct device *dev,
-                                      struct iommu *iommu,
-                                      unsigned long npages,
-                                      unsigned long *handle);
-extern void iommu_range_free(struct iommu *iommu,
-                            dma_addr_t dma_addr,
-                            unsigned long npages);
+unsigned long iommu_range_alloc(struct device *dev,
+                               struct iommu *iommu,
+                               unsigned long npages,
+                               unsigned long *handle);
+void iommu_range_free(struct iommu *iommu,
+                     dma_addr_t dma_addr,
+                     unsigned long npages);
 
 #endif /* _IOMMU_COMMON_H */
index e7e215d..7f08ec8 100644 (file)
@@ -186,7 +186,7 @@ static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys,
 
        if (name == NULL) name = "???";
 
-       if ((xres = xres_alloc()) != 0) {
+       if ((xres = xres_alloc()) != NULL) {
                tack = xres->xname;
                res = &xres->xres;
        } else {
@@ -400,7 +400,7 @@ static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
        BUG();
 }
 
-struct dma_map_ops sbus_dma_ops = {
+static struct dma_map_ops sbus_dma_ops = {
        .alloc                  = sbus_alloc_coherent,
        .free                   = sbus_free_coherent,
        .map_page               = sbus_map_page,
@@ -681,7 +681,7 @@ static int sparc_io_proc_show(struct seq_file *m, void *v)
        const char *nm;
 
        for (r = root->child; r != NULL; r = r->sibling) {
-               if ((nm = r->name) == 0) nm = "???";
+               if ((nm = r->name) == NULL) nm = "???";
                seq_printf(m, "%016llx-%016llx: %s\n",
                                (unsigned long long)r->start,
                                (unsigned long long)r->end, nm);
index b66b6aa..70a0b8d 100644 (file)
@@ -82,11 +82,20 @@ void handler_irq(unsigned int pil, struct pt_regs *regs);
 
 unsigned long leon_get_irqmask(unsigned int irq);
 
+/* irq_32.c */
+void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs);
+
+/* sun4m_irq.c */
+void sun4m_nmi(struct pt_regs *regs);
+
+/* sun4d_irq.c */
+void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs);
+
 #ifdef CONFIG_SMP
 
 /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
 #define SUN4D_IPI_IRQ 13
 
-extern void sun4d_ipi_interrupt(void);
+void sun4d_ipi_interrupt(void);
 
 #endif
index c145f6f..a979e99 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpudata.h>
+#include <asm/setup.h>
 #include <asm/pcic.h>
 #include <asm/leon.h>
 
index a702d9a..e7f652b 100644 (file)
@@ -2,6 +2,7 @@
 #define __SPARC_KERNEL_H
 
 #include <linux/interrupt.h>
+#include <linux/ftrace.h>
 
 #include <asm/traps.h>
 #include <asm/head.h>
@@ -15,62 +16,111 @@ extern int ncpus_probed;
 #ifdef CONFIG_SPARC64
 /* setup_64.c */
 struct seq_file;
-extern void cpucap_info(struct seq_file *);
+void cpucap_info(struct seq_file *);
 
-static inline unsigned long kimage_addr_to_ra(const char *p)
+static inline unsigned long kimage_addr_to_ra(const void *p)
 {
        unsigned long val = (unsigned long) p;
 
        return kern_base + (val - KERNBASE);
 }
+
+/* sys_sparc_64.c */
+asmlinkage long sys_kern_features(void);
+
+/* unaligned_64.c */
+asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn);
+int handle_popc(u32 insn, struct pt_regs *regs);
+void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr);
+void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr);
+
+/* smp_64.c */
+void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs);
+void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs);
+void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs);
+void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs);
+void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs);
+
+/* kgdb_64.c */
+void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs);
+
+/* pci.c */
+int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask);
+
+/* signal32.c */
+void do_sigreturn32(struct pt_regs *regs);
+asmlinkage void do_rt_sigreturn32(struct pt_regs *regs);
+void do_signal32(struct pt_regs * regs);
+asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp);
+
+/* compat_audit.c */
+extern unsigned sparc32_dir_class[];
+extern unsigned sparc32_chattr_class[];
+extern unsigned sparc32_write_class[];
+extern unsigned sparc32_read_class[];
+extern unsigned sparc32_signal_class[];
+int sparc32_classify_syscall(unsigned syscall);
 #endif
 
 #ifdef CONFIG_SPARC32
 /* setup_32.c */
+struct linux_romvec;
 void sparc32_start_kernel(struct linux_romvec *rp);
 
 /* cpu.c */
-extern void cpu_probe(void);
+void cpu_probe(void);
 
 /* traps_32.c */
-extern void handle_hw_divzero(struct pt_regs *regs, unsigned long pc,
-                              unsigned long npc, unsigned long psr);
+void handle_hw_divzero(struct pt_regs *regs, unsigned long pc,
+                       unsigned long npc, unsigned long psr);
 /* irq_32.c */
 extern struct irqaction static_irqaction[];
 extern int static_irq_count;
 extern spinlock_t irq_action_lock;
 
-extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs);
-extern void init_IRQ(void);
+void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs);
+void init_IRQ(void);
 
 /* sun4m_irq.c */
-extern void sun4m_init_IRQ(void);
-extern void sun4m_unmask_profile_irq(void);
-extern void sun4m_clear_profile_irq(int cpu);
+void sun4m_init_IRQ(void);
+void sun4m_unmask_profile_irq(void);
+void sun4m_clear_profile_irq(int cpu);
 
 /* sun4m_smp.c */
 void sun4m_cpu_pre_starting(void *arg);
 void sun4m_cpu_pre_online(void *arg);
+void __init smp4m_boot_cpus(void);
+int smp4m_boot_one_cpu(int i, struct task_struct *idle);
+void __init smp4m_smp_done(void);
+void smp4m_cross_call_irq(void);
+void smp4m_percpu_timer_interrupt(struct pt_regs *regs);
 
 /* sun4d_irq.c */
 extern spinlock_t sun4d_imsk_lock;
 
-extern void sun4d_init_IRQ(void);
-extern int sun4d_request_irq(unsigned int irq,
-                             irq_handler_t handler,
-                             unsigned long irqflags,
-                             const char *devname, void *dev_id);
-extern int show_sun4d_interrupts(struct seq_file *, void *);
-extern void sun4d_distribute_irqs(void);
-extern void sun4d_free_irq(unsigned int irq, void *dev_id);
+void sun4d_init_IRQ(void);
+int sun4d_request_irq(unsigned int irq,
+                      irq_handler_t handler,
+                      unsigned long irqflags,
+                      const char *devname, void *dev_id);
+int show_sun4d_interrupts(struct seq_file *, void *);
+void sun4d_distribute_irqs(void);
+void sun4d_free_irq(unsigned int irq, void *dev_id);
 
 /* sun4d_smp.c */
 void sun4d_cpu_pre_starting(void *arg);
 void sun4d_cpu_pre_online(void *arg);
+void __init smp4d_boot_cpus(void);
+int smp4d_boot_one_cpu(int i, struct task_struct *idle);
+void __init smp4d_smp_done(void);
+void smp4d_cross_call_irq(void);
+void smp4d_percpu_timer_interrupt(struct pt_regs *regs);
 
 /* leon_smp.c */
 void leon_cpu_pre_starting(void *arg);
 void leon_cpu_pre_online(void *arg);
+void leonsmp_ipi_interrupt(void);
+void leon_cross_call_irq(void);
 
 /* head_32.S */
 extern unsigned int t_nmi[];
@@ -89,12 +139,48 @@ extern unsigned int real_irq_entry[];
 extern unsigned int smp4d_ticker[];
 extern unsigned int patchme_maybe_smp_msg[];
 
-extern void floppy_hardint(void);
+void floppy_hardint(void);
 
 /* trampoline_32.S */
 extern unsigned long sun4m_cpu_startup;
 extern unsigned long sun4d_cpu_startup;
 
+/* process_32.c */
+asmlinkage int sparc_do_fork(unsigned long clone_flags,
+                             unsigned long stack_start,
+                             struct pt_regs *regs,
+                             unsigned long stack_size);
+
+/* signal_32.c */
+asmlinkage void do_sigreturn(struct pt_regs *regs);
+asmlinkage void do_rt_sigreturn(struct pt_regs *regs);
+void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
+                      unsigned long thread_info_flags);
+asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr,
+                               struct sigstack __user *ossptr,
+                               unsigned long sp);
+
+/* ptrace_32.c */
+asmlinkage int syscall_trace(struct pt_regs *regs, int syscall_exit_p);
+
+/* unaligned_32.c */
+asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn);
+asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn);
+
+/* windows.c */
+void try_to_clear_window_buffer(struct pt_regs *regs, int who);
+
+/* auxio_32.c */
+void __init auxio_probe(void);
+void __init auxio_power_probe(void);
+
+/* pcic.c */
+extern void __iomem *pcic_regs;
+void pcic_nmi(unsigned int pend, struct pt_regs *regs);
+
+/* time_32.c */
+void __init time_init(void);
+
 #else /* CONFIG_SPARC32 */
 #endif /* CONFIG_SPARC32 */
 #endif /* !(__SPARC_KERNEL_H) */
index b45fe3f..cbf21d0 100644 (file)
@@ -13,6 +13,8 @@
 #include <asm/ptrace.h>
 #include <asm/irq.h>
 
+#include "kernel.h"
+
 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
        struct reg_window *win;
index 1b09735..98d7128 100644 (file)
@@ -512,7 +512,8 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
 /*
  * Called when the probe at kretprobe trampoline is hit
  */
-int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes trampoline_probe_handler(struct kprobe *p,
+                                             struct pt_regs *regs)
 {
        struct kretprobe_instance *ri = NULL;
        struct hlist_head *head, empty_rp;
@@ -576,7 +577,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        return 1;
 }
 
-void kretprobe_trampoline_holder(void)
+static void __used kretprobe_trampoline_holder(void)
 {
        asm volatile(".global kretprobe_trampoline\n"
                     "kretprobe_trampoline:\n"
index b7c6897..683c4af 100644 (file)
@@ -32,12 +32,12 @@ struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base addr
 
 int leondebug_irq_disable;
 int leon_debug_irqout;
-static int dummy_master_l10_counter;
+static volatile u32 dummy_master_l10_counter;
 unsigned long amba_system_id;
 static DEFINE_SPINLOCK(leon_irq_lock);
 
+static unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */
 unsigned long leon3_gptimer_irq; /* interrupt controller irq number */
-unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */
 unsigned int sparc_leon_eirq;
 #define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu])
 #define LEON_IACK (&leon3_irqctrl_regs->iclear)
@@ -65,7 +65,7 @@ static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
 }
 
 /* The extended IRQ controller has been found, this function registers it */
-void leon_eirq_setup(unsigned int eirq)
+static void leon_eirq_setup(unsigned int eirq)
 {
        unsigned long mask, oldmask;
        unsigned int veirq;
@@ -270,7 +270,7 @@ static u32 leon_cycles_offset(void)
 #ifdef CONFIG_SMP
 
 /* smp clockevent irq */
-irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused)
+static irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused)
 {
        struct clock_event_device *ce;
        int cpu = smp_processor_id();
@@ -313,7 +313,7 @@ void __init leon_init_timers(void)
 
        leondebug_irq_disable = 0;
        leon_debug_irqout = 0;
-       master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
+       master_l10_counter = (u32 __iomem *)&dummy_master_l10_counter;
        dummy_master_l10_counter = 0;
 
        rootnp = of_find_node_by_path("/ambapp0");
index e16c415..899b720 100644 (file)
@@ -98,82 +98,3 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 {
        return res->start;
 }
-
-/* in/out routines taken from pcic.c
- *
- * This probably belongs here rather than ioport.c because
- * we do not want this crud linked into SBus kernels.
- * Also, think for a moment about likes of floppy.c that
- * include architecture specific parts. They may want to redefine ins/outs.
- *
- * We do not use horrible macros here because we want to
- * advance pointer by sizeof(size).
- */
-void outsb(unsigned long addr, const void *src, unsigned long count)
-{
-       while (count) {
-               count -= 1;
-               outb(*(const char *)src, addr);
-               src += 1;
-               /* addr += 1; */
-       }
-}
-EXPORT_SYMBOL(outsb);
-
-void outsw(unsigned long addr, const void *src, unsigned long count)
-{
-       while (count) {
-               count -= 2;
-               outw(*(const short *)src, addr);
-               src += 2;
-               /* addr += 2; */
-       }
-}
-EXPORT_SYMBOL(outsw);
-
-void outsl(unsigned long addr, const void *src, unsigned long count)
-{
-       while (count) {
-               count -= 4;
-               outl(*(const long *)src, addr);
-               src += 4;
-               /* addr += 4; */
-       }
-}
-EXPORT_SYMBOL(outsl);
-
-void insb(unsigned long addr, void *dst, unsigned long count)
-{
-       while (count) {
-               count -= 1;
-               *(unsigned char *)dst = inb(addr);
-               dst += 1;
-               /* addr += 1; */
-       }
-}
-EXPORT_SYMBOL(insb);
-
-void insw(unsigned long addr, void *dst, unsigned long count)
-{
-       while (count) {
-               count -= 2;
-               *(unsigned short *)dst = inw(addr);
-               dst += 2;
-               /* addr += 2; */
-       }
-}
-EXPORT_SYMBOL(insw);
-
-void insl(unsigned long addr, void *dst, unsigned long count)
-{
-       while (count) {
-               count -= 4;
-               /*
-                * XXX I am sure we are in for an unaligned trap here.
-                */
-               *(unsigned long *)dst = inl(addr);
-               dst += 4;
-               /* addr += 4; */
-       }
-}
-EXPORT_SYMBOL(insl);
index 6df26e3..c8bf26e 100644 (file)
@@ -80,7 +80,7 @@ struct grpci1_regs {
 
 struct grpci1_priv {
        struct leon_pci_info    info; /* must be on top of this structure */
-       struct grpci1_regs      *regs;          /* GRPCI register map */
+       struct grpci1_regs __iomem *regs;               /* GRPCI register map */
        struct device           *dev;
        int                     pci_err_mask;   /* STATUS register error mask */
        int                     irq;            /* LEON irqctrl GRPCI IRQ */
@@ -101,7 +101,7 @@ static struct grpci1_priv *grpci1priv;
 static int grpci1_cfg_w32(struct grpci1_priv *priv, unsigned int bus,
                                unsigned int devfn, int where, u32 val);
 
-int grpci1_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int grpci1_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct grpci1_priv *priv = dev->bus->sysdata;
        int irq_group;
@@ -144,7 +144,7 @@ static int grpci1_cfg_r32(struct grpci1_priv *priv, unsigned int bus,
                grpci1_cfg_w32(priv, TGT, 0, PCI_COMMAND, tmp);
        } else {
                /* Bus always little endian (unaffected by byte-swapping) */
-               *val = flip_dword(tmp);
+               *val = swab32(tmp);
        }
 
        return 0;
@@ -197,7 +197,7 @@ static int grpci1_cfg_w32(struct grpci1_priv *priv, unsigned int bus,
 
        pci_conf = (unsigned int *) (priv->pci_conf |
                                                (devfn << 8) | (where & 0xfc));
-       LEON3_BYPASS_STORE_PA(pci_conf, flip_dword(val));
+       LEON3_BYPASS_STORE_PA(pci_conf, swab32(val));
 
        return 0;
 }
@@ -417,10 +417,10 @@ out:
  *  BAR1: peripheral DMA to host's memory (size at least 256MByte)
  *  BAR2..BAR5: not implemented in hardware
  */
-void grpci1_hw_init(struct grpci1_priv *priv)
+static void grpci1_hw_init(struct grpci1_priv *priv)
 {
        u32 ahbadr, bar_sz, data, pciadr;
-       struct grpci1_regs *regs = priv->regs;
+       struct grpci1_regs __iomem *regs = priv->regs;
 
        /* set 1:1 mapping between AHB -> PCI memory space */
        REGSTORE(regs->cfg_stat, priv->pci_area & 0xf0000000);
@@ -509,7 +509,7 @@ static irqreturn_t grpci1_err_interrupt(int irq, void *arg)
 
 static int grpci1_of_probe(struct platform_device *ofdev)
 {
-       struct grpci1_regs *regs;
+       struct grpci1_regs __iomem *regs;
        struct grpci1_priv *priv;
        int err, len;
        const int *tmp;
@@ -690,7 +690,7 @@ err3:
 err2:
        release_resource(&priv->info.mem_space);
 err1:
-       iounmap((void *)priv->pci_io_va);
+       iounmap((void __iomem *)priv->pci_io_va);
        grpci1priv = NULL;
        return err;
 }
index 24d6a44..e433a4d 100644 (file)
@@ -191,7 +191,7 @@ struct grpci2_cap_first {
 
 struct grpci2_priv {
        struct leon_pci_info    info; /* must be on top of this structure */
-       struct grpci2_regs      *regs;
+       struct grpci2_regs __iomem *regs;
        char                    irq;
        char                    irq_mode; /* IRQ Mode from CAPSTS REG */
        char                    bt_enabled;
@@ -215,10 +215,10 @@ struct grpci2_priv {
        struct grpci2_barcfg    tgtbars[6];
 };
 
-DEFINE_SPINLOCK(grpci2_dev_lock);
-struct grpci2_priv *grpci2priv;
+static DEFINE_SPINLOCK(grpci2_dev_lock);
+static struct grpci2_priv *grpci2priv;
 
-int grpci2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int grpci2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct grpci2_priv *priv = dev->bus->sysdata;
        int irq_group;
@@ -270,7 +270,7 @@ static int grpci2_cfg_r32(struct grpci2_priv *priv, unsigned int bus,
                *val = 0xffffffff;
        } else {
                /* Bus always little endian (unaffected by byte-swapping) */
-               *val = flip_dword(tmp);
+               *val = swab32(tmp);
        }
 
        return 0;
@@ -328,7 +328,7 @@ static int grpci2_cfg_w32(struct grpci2_priv *priv, unsigned int bus,
 
        pci_conf = (unsigned int *) (priv->pci_conf |
                                                (devfn << 8) | (where & 0xfc));
-       LEON3_BYPASS_STORE_PA(pci_conf, flip_dword(val));
+       LEON3_BYPASS_STORE_PA(pci_conf, swab32(val));
 
        /* Wait until GRPCI2 signals that CFG access is done, it should be
         * done instantaneously unless a DMA operation is ongoing...
@@ -561,10 +561,10 @@ out:
        return virq;
 }
 
-void grpci2_hw_init(struct grpci2_priv *priv)
+static void grpci2_hw_init(struct grpci2_priv *priv)
 {
        u32 ahbadr, pciadr, bar_sz, capptr, io_map, data;
-       struct grpci2_regs *regs = priv->regs;
+       struct grpci2_regs __iomem *regs = priv->regs;
        int i;
        struct grpci2_barcfg *barcfg = priv->tgtbars;
 
@@ -655,7 +655,7 @@ static irqreturn_t grpci2_jump_interrupt(int irq, void *arg)
 static irqreturn_t grpci2_err_interrupt(int irq, void *arg)
 {
        struct grpci2_priv *priv = arg;
-       struct grpci2_regs *regs = priv->regs;
+       struct grpci2_regs __iomem *regs = priv->regs;
        unsigned int status;
 
        status = REGLOAD(regs->sts_cap);
@@ -682,7 +682,7 @@ static irqreturn_t grpci2_err_interrupt(int irq, void *arg)
 
 static int grpci2_of_probe(struct platform_device *ofdev)
 {
-       struct grpci2_regs *regs;
+       struct grpci2_regs __iomem *regs;
        struct grpci2_priv *priv;
        int err, i, len;
        const int *tmp;
@@ -878,7 +878,7 @@ err4:
        release_resource(&priv->info.mem_space);
 err3:
        err = -ENOMEM;
-       iounmap((void *)priv->pci_io_va);
+       iounmap((void __iomem *)priv->pci_io_va);
 err2:
        kfree(priv);
 err1:
index b0b3967..ddcf950 100644 (file)
 #include <asm/processor.h>
 
 /* List of Systems that need fixup instructions around power-down instruction */
-unsigned int pmc_leon_fixup_ids[] = {
+static unsigned int pmc_leon_fixup_ids[] = {
        AEROFLEX_UT699,
        GAISLER_GR712RC,
        LEON4_NEXTREME1,
        0
 };
 
-int pmc_leon_need_fixup(void)
+static int pmc_leon_need_fixup(void)
 {
        unsigned int systemid = amba_system_id >> 16;
        unsigned int *id;
@@ -38,7 +38,7 @@ int pmc_leon_need_fixup(void)
  * CPU idle callback function for systems that need some extra handling
  * See .../arch/sparc/kernel/process.c
  */
-void pmc_leon_idle_fixup(void)
+static void pmc_leon_idle_fixup(void)
 {
        /* Prepare an address to a non-cachable region. APB is always
         * none-cachable. One instruction is executed after the Sleep
@@ -62,7 +62,7 @@ void pmc_leon_idle_fixup(void)
  * CPU idle callback function
  * See .../arch/sparc/kernel/process.c
  */
-void pmc_leon_idle(void)
+static void pmc_leon_idle(void)
 {
        /* Interrupts need to be enabled to not hang the CPU */
        local_irq_enable();
index 6edf955..018ef11 100644 (file)
@@ -130,7 +130,7 @@ void leon_configure_cache_smp(void)
        local_ops->tlb_all();
 }
 
-void leon_smp_setbroadcast(unsigned int mask)
+static void leon_smp_setbroadcast(unsigned int mask)
 {
        int broadcast =
            ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >>
@@ -148,13 +148,6 @@ void leon_smp_setbroadcast(unsigned int mask)
        LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpbroadcast), mask);
 }
 
-unsigned int leon_smp_getbroadcast(void)
-{
-       unsigned int mask;
-       mask = LEON_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpbroadcast));
-       return mask;
-}
-
 int leon_smp_nrcpus(void)
 {
        int nrcpu =
@@ -266,10 +259,6 @@ void __init leon_smp_done(void)
 
 }
 
-void leon_irq_rotate(int cpu)
-{
-}
-
 struct leon_ipi_work {
        int single;
        int msk;
index 3241f56..de0ee39 100644 (file)
@@ -5,8 +5,10 @@
 #include <linux/mod_devicetable.h>
 #include <linux/errno.h>
 #include <linux/irq.h>
-#include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 #include "of_device_common.h"
 
index 857ad77..539babf 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/apb.h>
 
 #include "pci_impl.h"
+#include "kernel.h"
 
 /* List of all PCI controllers found in the system. */
 struct pci_pbm_info *pci_pbm_root = NULL;
index 5f68853..75803c7 100644 (file)
@@ -48,8 +48,8 @@ struct sparc64_msiq_ops {
                              unsigned long devino);
 };
 
-extern void sparc64_pbm_msi_init(struct pci_pbm_info *pbm,
-                                const struct sparc64_msiq_ops *ops);
+void sparc64_pbm_msi_init(struct pci_pbm_info *pbm,
+                         const struct sparc64_msiq_ops *ops);
 
 struct sparc64_msiq_cookie {
        struct pci_pbm_info *pbm;
@@ -158,23 +158,23 @@ extern struct pci_pbm_info *pci_pbm_root;
 extern int pci_num_pbms;
 
 /* PCI bus scanning and fixup support. */
-extern void pci_get_pbm_props(struct pci_pbm_info *pbm);
-extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
-                                       struct device *parent);
-extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
+void pci_get_pbm_props(struct pci_pbm_info *pbm);
+struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
+                                struct device *parent);
+void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
 
 /* Error reporting support. */
-extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
-extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *);
-extern void pci_scan_for_parity_error(struct pci_pbm_info *, struct pci_bus *);
+void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
+void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *);
+void pci_scan_for_parity_error(struct pci_pbm_info *, struct pci_bus *);
 
 /* Configuration space access. */
-extern void pci_config_read8(u8 *addr, u8 *ret);
-extern void pci_config_read16(u16 *addr, u16 *ret);
-extern void pci_config_read32(u32 *addr, u32 *ret);
-extern void pci_config_write8(u8 *addr, u8 val);
-extern void pci_config_write16(u16 *addr, u16 val);
-extern void pci_config_write32(u32 *addr, u32 val);
+void pci_config_read8(u8 *addr, u8 *ret);
+void pci_config_read16(u16 *addr, u16 *ret);
+void pci_config_read32(u32 *addr, u32 *ret);
+void pci_config_write8(u8 *addr, u8 val);
+void pci_config_write16(u16 *addr, u16 val);
+void pci_config_write32(u32 *addr, u32 val);
 
 extern struct pci_ops sun4u_pci_ops;
 extern struct pci_ops sun4v_pci_ops;
index 8e9fc3a..5642212 100644 (file)
@@ -6,87 +6,87 @@
 #ifndef _PCI_SUN4V_H
 #define _PCI_SUN4V_H
 
-extern long pci_sun4v_iommu_map(unsigned long devhandle,
-                               unsigned long tsbid,
-                               unsigned long num_ttes,
-                               unsigned long io_attributes,
-                               unsigned long io_page_list_pa);
-extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle,
-                                          unsigned long tsbid,
-                                          unsigned long num_ttes);
-extern unsigned long pci_sun4v_iommu_getmap(unsigned long devhandle,
-                                           unsigned long tsbid,
-                                           unsigned long *io_attributes,
-                                           unsigned long *real_address);
-extern unsigned long pci_sun4v_config_get(unsigned long devhandle,
-                                         unsigned long pci_device,
-                                         unsigned long config_offset,
-                                         unsigned long size);
-extern int pci_sun4v_config_put(unsigned long devhandle,
-                               unsigned long pci_device,
-                               unsigned long config_offset,
-                               unsigned long size,
-                               unsigned long data);
+long pci_sun4v_iommu_map(unsigned long devhandle,
+                        unsigned long tsbid,
+                        unsigned long num_ttes,
+                        unsigned long io_attributes,
+                        unsigned long io_page_list_pa);
+unsigned long pci_sun4v_iommu_demap(unsigned long devhandle,
+                                   unsigned long tsbid,
+                                   unsigned long num_ttes);
+unsigned long pci_sun4v_iommu_getmap(unsigned long devhandle,
+                                    unsigned long tsbid,
+                                    unsigned long *io_attributes,
+                                    unsigned long *real_address);
+unsigned long pci_sun4v_config_get(unsigned long devhandle,
+                                  unsigned long pci_device,
+                                  unsigned long config_offset,
+                                  unsigned long size);
+int pci_sun4v_config_put(unsigned long devhandle,
+                        unsigned long pci_device,
+                        unsigned long config_offset,
+                        unsigned long size,
+                        unsigned long data);
 
-extern unsigned long pci_sun4v_msiq_conf(unsigned long devhandle,
+unsigned long pci_sun4v_msiq_conf(unsigned long devhandle,
                                         unsigned long msiqid,
                                         unsigned long msiq_paddr,
                                         unsigned long num_entries);
-extern unsigned long pci_sun4v_msiq_info(unsigned long devhandle,
-                                        unsigned long msiqid,
-                                        unsigned long *msiq_paddr,
-                                        unsigned long *num_entries);
-extern unsigned long pci_sun4v_msiq_getvalid(unsigned long devhandle,
-                                            unsigned long msiqid,
-                                            unsigned long *valid);
-extern unsigned long pci_sun4v_msiq_setvalid(unsigned long devhandle,
-                                            unsigned long msiqid,
-                                            unsigned long valid);
-extern unsigned long pci_sun4v_msiq_getstate(unsigned long devhandle,
-                                            unsigned long msiqid,
-                                            unsigned long *state);
-extern unsigned long pci_sun4v_msiq_setstate(unsigned long devhandle,
-                                            unsigned long msiqid,
-                                            unsigned long state);
-extern unsigned long pci_sun4v_msiq_gethead(unsigned long devhandle,
-                                            unsigned long msiqid,
-                                            unsigned long *head);
-extern unsigned long pci_sun4v_msiq_sethead(unsigned long devhandle,
-                                            unsigned long msiqid,
-                                            unsigned long head);
-extern unsigned long pci_sun4v_msiq_gettail(unsigned long devhandle,
-                                            unsigned long msiqid,
-                                            unsigned long *head);
-extern unsigned long pci_sun4v_msi_getvalid(unsigned long devhandle,
-                                           unsigned long msinum,
-                                           unsigned long *valid);
-extern unsigned long pci_sun4v_msi_setvalid(unsigned long devhandle,
-                                           unsigned long msinum,
-                                           unsigned long valid);
-extern unsigned long pci_sun4v_msi_getmsiq(unsigned long devhandle,
-                                          unsigned long msinum,
-                                          unsigned long *msiq);
-extern unsigned long pci_sun4v_msi_setmsiq(unsigned long devhandle,
-                                          unsigned long msinum,
-                                          unsigned long msiq,
-                                          unsigned long msitype);
-extern unsigned long pci_sun4v_msi_getstate(unsigned long devhandle,
-                                           unsigned long msinum,
-                                           unsigned long *state);
-extern unsigned long pci_sun4v_msi_setstate(unsigned long devhandle,
-                                           unsigned long msinum,
-                                           unsigned long state);
-extern unsigned long pci_sun4v_msg_getmsiq(unsigned long devhandle,
-                                          unsigned long msinum,
-                                          unsigned long *msiq);
-extern unsigned long pci_sun4v_msg_setmsiq(unsigned long devhandle,
-                                          unsigned long msinum,
-                                          unsigned long msiq);
-extern unsigned long pci_sun4v_msg_getvalid(unsigned long devhandle,
-                                           unsigned long msinum,
-                                           unsigned long *valid);
-extern unsigned long pci_sun4v_msg_setvalid(unsigned long devhandle,
-                                           unsigned long msinum,
-                                           unsigned long valid);
+unsigned long pci_sun4v_msiq_info(unsigned long devhandle,
+                                 unsigned long msiqid,
+                                 unsigned long *msiq_paddr,
+                                 unsigned long *num_entries);
+unsigned long pci_sun4v_msiq_getvalid(unsigned long devhandle,
+                                     unsigned long msiqid,
+                                     unsigned long *valid);
+unsigned long pci_sun4v_msiq_setvalid(unsigned long devhandle,
+                                     unsigned long msiqid,
+                                     unsigned long valid);
+unsigned long pci_sun4v_msiq_getstate(unsigned long devhandle,
+                                     unsigned long msiqid,
+                                     unsigned long *state);
+unsigned long pci_sun4v_msiq_setstate(unsigned long devhandle,
+                                     unsigned long msiqid,
+                                     unsigned long state);
+unsigned long pci_sun4v_msiq_gethead(unsigned long devhandle,
+                                    unsigned long msiqid,
+                                    unsigned long *head);
+unsigned long pci_sun4v_msiq_sethead(unsigned long devhandle,
+                                    unsigned long msiqid,
+                                    unsigned long head);
+unsigned long pci_sun4v_msiq_gettail(unsigned long devhandle,
+                                     unsigned long msiqid,
+                                     unsigned long *head);
+unsigned long pci_sun4v_msi_getvalid(unsigned long devhandle,
+                                    unsigned long msinum,
+                                    unsigned long *valid);
+unsigned long pci_sun4v_msi_setvalid(unsigned long devhandle,
+                                    unsigned long msinum,
+                                    unsigned long valid);
+unsigned long pci_sun4v_msi_getmsiq(unsigned long devhandle,
+                                   unsigned long msinum,
+                                   unsigned long *msiq);
+unsigned long pci_sun4v_msi_setmsiq(unsigned long devhandle,
+                                   unsigned long msinum,
+                                   unsigned long msiq,
+                                   unsigned long msitype);
+unsigned long pci_sun4v_msi_getstate(unsigned long devhandle,
+                                    unsigned long msinum,
+                                    unsigned long *state);
+unsigned long pci_sun4v_msi_setstate(unsigned long devhandle,
+                                    unsigned long msinum,
+                                    unsigned long state);
+unsigned long pci_sun4v_msg_getmsiq(unsigned long devhandle,
+                                   unsigned long msinum,
+                                   unsigned long *msiq);
+unsigned long pci_sun4v_msg_setmsiq(unsigned long devhandle,
+                                   unsigned long msinum,
+                                   unsigned long msiq);
+unsigned long pci_sun4v_msg_getvalid(unsigned long devhandle,
+                                    unsigned long msinum,
+                                    unsigned long *valid);
+unsigned long pci_sun4v_msg_setvalid(unsigned long devhandle,
+                                    unsigned long msinum,
+                                    unsigned long valid);
 
 #endif /* !(_PCI_SUN4V_H) */
index 09f4fdd..6cc78c2 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/uaccess.h>
 #include <asm/irq_regs.h>
 
+#include "kernel.h"
 #include "irq.h"
 
 /*
@@ -162,8 +163,8 @@ static int pcic0_up;
 static struct linux_pcic pcic0;
 
 void __iomem *pcic_regs;
-volatile int pcic_speculative;
-volatile int pcic_trapped;
+static volatile int pcic_speculative;
+static volatile int pcic_trapped;
 
 /* forward */
 unsigned int pcic_build_device_irq(struct platform_device *op,
@@ -329,7 +330,7 @@ int __init pcic_probe(void)
 
        pcic->pcic_res_cfg_addr.name = "pcic_cfg_addr";
        if ((pcic->pcic_config_space_addr =
-           ioremap(regs[2].phys_addr, regs[2].reg_size * 2)) == 0) {
+           ioremap(regs[2].phys_addr, regs[2].reg_size * 2)) == NULL) {
                prom_printf("PCIC: Error, cannot map "
                            "PCI Configuration Space Address.\n");
                prom_halt();
@@ -341,7 +342,7 @@ int __init pcic_probe(void)
         */
        pcic->pcic_res_cfg_data.name = "pcic_cfg_data";
        if ((pcic->pcic_config_space_data =
-           ioremap(regs[3].phys_addr, regs[3].reg_size * 2)) == 0) {
+           ioremap(regs[3].phys_addr, regs[3].reg_size * 2)) == NULL) {
                prom_printf("PCIC: Error, cannot map "
                            "PCI Configuration Space Data.\n");
                prom_halt();
@@ -353,7 +354,6 @@ int __init pcic_probe(void)
        strcpy(pbm->prom_name, namebuf);
 
        {
-               extern volatile int t_nmi[4];
                extern int pcic_nmi_trap_patch[4];
 
                t_nmi[0] = pcic_nmi_trap_patch[0];
@@ -536,7 +536,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
                prom_getstring(node, "name", namebuf, sizeof(namebuf));
        }
 
-       if ((p = pcic->pcic_imap) == 0) {
+       if ((p = pcic->pcic_imap) == NULL) {
                dev->irq = 0;
                return;
        }
@@ -670,30 +670,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
        }
 }
 
-/*
- * pcic_pin_to_irq() is exported to bus probing code
- */
-unsigned int
-pcic_pin_to_irq(unsigned int pin, const char *name)
-{
-       struct linux_pcic *pcic = &pcic0;
-       unsigned int irq;
-       unsigned int ivec;
-
-       if (pin < 4) {
-               ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
-               irq = ivec >> (pin << 2) & 0xF;
-       } else if (pin < 8) {
-               ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
-               irq = ivec >> ((pin-4) << 2) & 0xF;
-       } else {                                        /* Corrupted map */
-               printk("PCIC: BAD PIN %d FOR %s\n", pin, name);
-               for (;;) {}     /* XXX Cannot panic properly in case of PROLL */
-       }
-/* P3 */ /* printk("PCIC: dev %s pin %d ivec 0x%x irq %x\n", name, pin, ivec, irq); */
-       return irq;
-}
-
 /* Makes compiler happy */
 static volatile int pcic_timer_dummy;
 
@@ -783,7 +759,7 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask)
 void pcic_nmi(unsigned int pend, struct pt_regs *regs)
 {
 
-       pend = flip_dword(pend);
+       pend = swab32(pend);
 
        if (!pcic_speculative || (pend & PCI_SYS_INT_PENDING_PIO) == 0) {
                /*
@@ -875,82 +851,4 @@ void __init sun4m_pci_init_IRQ(void)
        sparc_config.load_profile_irq = pcic_load_profile_irq;
 }
 
-/*
- * This probably belongs here rather than ioport.c because
- * we do not want this crud linked into SBus kernels.
- * Also, think for a moment about likes of floppy.c that
- * include architecture specific parts. They may want to redefine ins/outs.
- *
- * We do not use horrible macros here because we want to
- * advance pointer by sizeof(size).
- */
-void outsb(unsigned long addr, const void *src, unsigned long count)
-{
-       while (count) {
-               count -= 1;
-               outb(*(const char *)src, addr);
-               src += 1;
-               /* addr += 1; */
-       }
-}
-EXPORT_SYMBOL(outsb);
-
-void outsw(unsigned long addr, const void *src, unsigned long count)
-{
-       while (count) {
-               count -= 2;
-               outw(*(const short *)src, addr);
-               src += 2;
-               /* addr += 2; */
-       }
-}
-EXPORT_SYMBOL(outsw);
-
-void outsl(unsigned long addr, const void *src, unsigned long count)
-{
-       while (count) {
-               count -= 4;
-               outl(*(const long *)src, addr);
-               src += 4;
-               /* addr += 4; */
-       }
-}
-EXPORT_SYMBOL(outsl);
-
-void insb(unsigned long addr, void *dst, unsigned long count)
-{
-       while (count) {
-               count -= 1;
-               *(unsigned char *)dst = inb(addr);
-               dst += 1;
-               /* addr += 1; */
-       }
-}
-EXPORT_SYMBOL(insb);
-
-void insw(unsigned long addr, void *dst, unsigned long count)
-{
-       while (count) {
-               count -= 2;
-               *(unsigned short *)dst = inw(addr);
-               dst += 2;
-               /* addr += 2; */
-       }
-}
-EXPORT_SYMBOL(insw);
-
-void insl(unsigned long addr, void *dst, unsigned long count)
-{
-       while (count) {
-               count -= 4;
-               /*
-                * XXX I am sure we are in for an unaligned trap here.
-                */
-               *(unsigned long *)dst = inl(addr);
-               dst += 4;
-               /* addr += 4; */
-       }
-}
-EXPORT_SYMBOL(insl);
-
 subsys_initcall(pcic_init);
index b5c38fa..8efd337 100644 (file)
@@ -110,7 +110,7 @@ struct cpu_hw_events {
 
        unsigned int            group_flag;
 };
-DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
 
 /* An event map describes the characteristics of a performance
  * counter event.  In particular it gives the encoding as well as
@@ -1153,7 +1153,7 @@ static void perf_stop_nmi_watchdog(void *unused)
                cpuc->pcr[i] = pcr_ops->read_pcr(i);
 }
 
-void perf_event_grab_pmc(void)
+static void perf_event_grab_pmc(void)
 {
        if (atomic_inc_not_zero(&active_events))
                return;
@@ -1169,7 +1169,7 @@ void perf_event_grab_pmc(void)
        mutex_unlock(&pmc_grab_mutex);
 }
 
-void perf_event_release_pmc(void)
+static void perf_event_release_pmc(void)
 {
        if (atomic_dec_and_mutex_lock(&active_events, &pmc_grab_mutex)) {
                if (atomic_read(&nmi_active) == 0)
@@ -1669,7 +1669,7 @@ static bool __init supported_pmu(void)
        return false;
 }
 
-int __init init_hw_perf_events(void)
+static int __init init_hw_perf_events(void)
 {
        pr_info("Performance events: ");
 
@@ -1742,10 +1742,11 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry,
 
        ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
        do {
-               struct sparc_stackf *usf, sf;
+               struct sparc_stackf __user *usf;
+               struct sparc_stackf sf;
                unsigned long pc;
 
-               usf = (struct sparc_stackf *) ufp;
+               usf = (struct sparc_stackf __user *)ufp;
                if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
                        break;
 
@@ -1765,17 +1766,19 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
                unsigned long pc;
 
                if (thread32_stack_is_64bit(ufp)) {
-                       struct sparc_stackf *usf, sf;
+                       struct sparc_stackf __user *usf;
+                       struct sparc_stackf sf;
 
                        ufp += STACK_BIAS;
-                       usf = (struct sparc_stackf *) ufp;
+                       usf = (struct sparc_stackf __user *)ufp;
                        if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
                                break;
                        pc = sf.callers_pc & 0xffffffff;
                        ufp = ((unsigned long) sf.fp) & 0xffffffff;
                } else {
-                       struct sparc_stackf32 *usf, sf;
-                       usf = (struct sparc_stackf32 *) ufp;
+                       struct sparc_stackf32 __user *usf;
+                       struct sparc_stackf32 sf;
+                       usf = (struct sparc_stackf32 __user *)ufp;
                        if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
                                break;
                        pc = sf.callers_pc;
index 510baec..50e7b62 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <stdarg.h>
 
+#include <linux/elfcore.h>
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -23,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
+#include <linux/cpu.h>
 
 #include <asm/auxio.h>
 #include <asm/oplib.h>
@@ -38,6 +40,8 @@
 #include <asm/unistd.h>
 #include <asm/setup.h>
 
+#include "kernel.h"
+
 /* 
  * Power management idle function 
  * Set in pm platform drivers (apc.c and pmc.c)
@@ -102,8 +106,12 @@ void machine_restart(char * cmd)
 void machine_power_off(void)
 {
        if (auxio_power_register &&
-           (strcmp(of_console_device->type, "serial") || scons_pwroff))
-               *auxio_power_register |= AUXIO_POWER_OFF;
+           (strcmp(of_console_device->type, "serial") || scons_pwroff)) {
+               u8 power_register = sbus_readb(auxio_power_register);
+               power_register |= AUXIO_POWER_OFF;
+               sbus_writeb(power_register, auxio_power_register);
+       }
+
        machine_halt();
 }
 
index d7b4967..027e099 100644 (file)
@@ -88,7 +88,7 @@ void arch_cpu_idle(void)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-void arch_cpu_idle_dead()
+void arch_cpu_idle_dead(void)
 {
        sched_preempt_enable_no_resched();
        cpu_play_dead();
@@ -239,7 +239,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp)
        }
 }
 
-void arch_trigger_all_cpu_backtrace(void)
+void arch_trigger_all_cpu_backtrace(bool include_self)
 {
        struct thread_info *tp = current_thread_info();
        struct pt_regs *regs = get_irq_regs();
@@ -251,16 +251,22 @@ void arch_trigger_all_cpu_backtrace(void)
 
        spin_lock_irqsave(&global_cpu_snapshot_lock, flags);
 
-       memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
-
        this_cpu = raw_smp_processor_id();
 
-       __global_reg_self(tp, regs, this_cpu);
+       memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
+
+       if (include_self)
+               __global_reg_self(tp, regs, this_cpu);
 
        smp_fetch_global_regs();
 
        for_each_online_cpu(cpu) {
-               struct global_reg_snapshot *gp = &global_cpu_snapshot[cpu].reg;
+               struct global_reg_snapshot *gp;
+
+               if (!include_self && cpu == this_cpu)
+                       continue;
+
+               gp = &global_cpu_snapshot[cpu].reg;
 
                __global_reg_poll(gp);
 
@@ -292,7 +298,7 @@ void arch_trigger_all_cpu_backtrace(void)
 
 static void sysrq_handle_globreg(int key)
 {
-       arch_trigger_all_cpu_backtrace();
+       arch_trigger_all_cpu_backtrace(true);
 }
 
 static struct sysrq_key_op sparc_globalreg_op = {
index cf5fe1c..890281b 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/spinlock.h>
 #include <asm/prom.h>
 
-extern void of_console_init(void);
+void of_console_init(void);
 
 extern unsigned int prom_early_allocated;
 
index 9a690d3..20cc5d8 100644 (file)
  *      2 of the License, or (at your option) any later version.
  */
 
+#include <linux/memblock.h>
 #include <linux/kernel.h>
-#include <linux/types.h>
 #include <linux/string.h>
+#include <linux/types.h>
+#include <linux/cpu.h>
 #include <linux/mm.h>
-#include <linux/memblock.h>
 #include <linux/of.h>
 
 #include <asm/prom.h>
index 590b4ed..05a6e30 100644 (file)
@@ -30,19 +30,19 @@ enum psycho_error_type {
        UE_ERR, CE_ERR, PCI_ERR
 };
 
-extern void psycho_check_iommu_error(struct pci_pbm_info *pbm,
-                                    unsigned long afsr,
-                                    unsigned long afar,
-                                    enum psycho_error_type type);
+void psycho_check_iommu_error(struct pci_pbm_info *pbm,
+                             unsigned long afsr,
+                             unsigned long afar,
+                             enum psycho_error_type type);
 
-extern irqreturn_t psycho_pcierr_intr(int irq, void *dev_id);
+irqreturn_t psycho_pcierr_intr(int irq, void *dev_id);
 
-extern int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
-                            u32 dvma_offset, u32 dma_mask,
-                            unsigned long write_complete_offset);
+int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
+                     u32 dvma_offset, u32 dma_mask,
+                     unsigned long write_complete_offset);
 
-extern void psycho_pbm_init_common(struct pci_pbm_info *pbm,
-                                  struct platform_device *op,
-                                  const char *chip_name, int chip_type);
+void psycho_pbm_init_common(struct pci_pbm_info *pbm,
+                           struct platform_device *op,
+                           const char *chip_name, int chip_type);
 
 #endif /* _PSYCHO_COMMON_H */
index 896ba7c..a331fdc 100644 (file)
@@ -26,6 +26,8 @@
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
 
+#include "kernel.h"
+
 /* #define ALLOW_INIT_TRACING */
 
 /*
index 1434526..baef495 100644 (file)
@@ -267,7 +267,7 @@ static __init void leon_patch(void)
 }
 
 struct tt_entry *sparc_ttable;
-struct pt_regs fake_swapper_regs;
+static struct pt_regs fake_swapper_regs;
 
 /* Called from head_32.S - before we have setup anything
  * in the kernel. Be very careful with what you do here.
@@ -365,7 +365,7 @@ void __init setup_arch(char **cmdline_p)
 
        prom_setsync(prom_sync_me);
 
-       if((boot_flags&BOOTME_DEBUG) && (linux_dbvec!=0) && 
+       if((boot_flags & BOOTME_DEBUG) && (linux_dbvec != NULL) &&
           ((*(short *)linux_dbvec) != -1)) {
                printk("Booted under KADB. Syncing trap table.\n");
                (*(linux_dbvec->teach_debugger))();
index ee789d2..62deba7 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/switch_to.h>
 
 #include "sigutil.h"
+#include "kernel.h"
 
 /* This magic should be in g_upper[0] for all upper parts
  * to be valid.
@@ -145,7 +146,7 @@ void do_sigreturn32(struct pt_regs *regs)
        unsigned int psr;
        unsigned pc, npc;
        sigset_t set;
-       unsigned seta[_COMPAT_NSIG_WORDS];
+       compat_sigset_t seta;
        int err, i;
        
        /* Always make any pending restarted system calls return -EINTR */
@@ -209,17 +210,13 @@ void do_sigreturn32(struct pt_regs *regs)
                if (restore_rwin_state(compat_ptr(rwin_save)))
                        goto segv;
        }
-       err |= __get_user(seta[0], &sf->info.si_mask);
-       err |= copy_from_user(seta+1, &sf->extramask,
+       err |= __get_user(seta.sig[0], &sf->info.si_mask);
+       err |= copy_from_user(&seta.sig[1], &sf->extramask,
                              (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
        if (err)
                goto segv;
-       switch (_NSIG_WORDS) {
-               case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
-               case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
-               case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
-               case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
-       }
+
+       set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
        set_current_blocked(&set);
        return;
 
@@ -303,12 +300,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
                        goto segv;
        }
 
-       switch (_NSIG_WORDS) {
-               case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
-               case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
-               case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
-               case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
-       }
+       set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
        set_current_blocked(&set);
        return;
 segv:
@@ -417,7 +409,7 @@ static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
        void __user *tail;
        int sigframe_size;
        u32 psr;
-       unsigned int seta[_COMPAT_NSIG_WORDS];
+       compat_sigset_t seta;
 
        /* 1. Make sure everything is clean */
        synchronize_user_stack();
@@ -481,18 +473,14 @@ static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
                err |= __put_user(0, &sf->rwin_save);
        }
 
-       switch (_NSIG_WORDS) {
-       case 4: seta[7] = (oldset->sig[3] >> 32);
-               seta[6] = oldset->sig[3];
-       case 3: seta[5] = (oldset->sig[2] >> 32);
-               seta[4] = oldset->sig[2];
-       case 2: seta[3] = (oldset->sig[1] >> 32);
-               seta[2] = oldset->sig[1];
-       case 1: seta[1] = (oldset->sig[0] >> 32);
-               seta[0] = oldset->sig[0];
-       }
-       err |= __put_user(seta[0], &sf->info.si_mask);
-       err |= __copy_to_user(sf->extramask, seta + 1,
+       /* If these change we need to know - assignments to seta relies on these sizes */
+       BUILD_BUG_ON(_NSIG_WORDS != 1);
+       BUILD_BUG_ON(_COMPAT_NSIG_WORDS != 2);
+       seta.sig[1] = (oldset->sig[0] >> 32);
+       seta.sig[0] = oldset->sig[0];
+
+       err |= __put_user(seta.sig[0], &sf->info.si_mask);
+       err |= __copy_to_user(sf->extramask, &seta.sig[1],
                              (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
 
        if (!wsaved) {
@@ -622,16 +610,8 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
        /* Setup sigaltstack */
        err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 
-       switch (_NSIG_WORDS) {
-       case 4: seta.sig[7] = (oldset->sig[3] >> 32);
-               seta.sig[6] = oldset->sig[3];
-       case 3: seta.sig[5] = (oldset->sig[2] >> 32);
-               seta.sig[4] = oldset->sig[2];
-       case 2: seta.sig[3] = (oldset->sig[1] >> 32);
-               seta.sig[2] = oldset->sig[1];
-       case 1: seta.sig[1] = (oldset->sig[0] >> 32);
-               seta.sig[0] = oldset->sig[0];
-       }
+       seta.sig[1] = (oldset->sig[0] >> 32);
+       seta.sig[0] = oldset->sig[0];
        err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
 
        if (!wsaved) {
index 7d5d8e1..9ee72fc 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/switch_to.h>
 
 #include "sigutil.h"
+#include "kernel.h"
 
 extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
                   void *fpqueue, unsigned long *fpqdepth);
@@ -341,7 +342,7 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
        err |= __put_user(0, &sf->extra_size);
 
        if (psr & PSR_EF) {
-               __siginfo_fpu_t *fp = tail;
+               __siginfo_fpu_t __user *fp = tail;
                tail += sizeof(*fp);
                err |= save_fpu_state(regs, fp);
                err |= __put_user(fp, &sf->fpu_save);
@@ -349,7 +350,7 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
                err |= __put_user(0, &sf->fpu_save);
        }
        if (wsaved) {
-               __siginfo_rwin_t *rwp = tail;
+               __siginfo_rwin_t __user *rwp = tail;
                tail += sizeof(*rwp);
                err |= save_rwin_state(wsaved, rwp);
                err |= __put_user(rwp, &sf->rwin_save);
@@ -517,9 +518,9 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
        }
 }
 
-asmlinkage int
-do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr,
-               unsigned long sp)
+asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr,
+                               struct sigstack __user *ossptr,
+                               unsigned long sp)
 {
        int ret = -EFAULT;
 
index cd91d01..1a69998 100644 (file)
 #include <asm/switch_to.h>
 #include <asm/cacheflush.h>
 
-#include "entry.h"
-#include "systbls.h"
 #include "sigutil.h"
+#include "systbls.h"
+#include "kernel.h"
+#include "entry.h"
 
 /* {set, get}context() needed for 64-bit SparcLinux userland. */
 asmlinkage void sparc64_set_context(struct pt_regs *regs)
@@ -492,7 +493,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 
 #ifdef CONFIG_COMPAT
        if (test_thread_flag(TIF_32BIT)) {
-               extern void do_signal32(struct pt_regs *);
                do_signal32(regs);
                return;
        }
index a102bfb..7958242 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/seq_file.h>
 #include <linux/cache.h>
 #include <linux/delay.h>
+#include <linux/profile.h>
 #include <linux/cpu.h>
 
 #include <asm/ptrace.h>
@@ -75,8 +76,6 @@ void smp_store_cpu_info(int id)
 
 void __init smp_cpus_done(unsigned int max_cpus)
 {
-       extern void smp4m_smp_done(void);
-       extern void smp4d_smp_done(void);
        unsigned long bogosum = 0;
        int cpu, num = 0;
 
@@ -183,8 +182,6 @@ int setup_profiling_timer(unsigned int multiplier)
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-       extern void __init smp4m_boot_cpus(void);
-       extern void __init smp4d_boot_cpus(void);
        int i, cpuid, extra;
 
        printk("Entering SMP Mode...\n");
@@ -261,8 +258,6 @@ void __init smp_prepare_boot_cpu(void)
 
 int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-       extern int smp4m_boot_one_cpu(int, struct task_struct *);
-       extern int smp4d_boot_one_cpu(int, struct task_struct *);
        int ret=0;
 
        switch(sparc_cpu_model) {
@@ -297,7 +292,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
        return ret;
 }
 
-void arch_cpu_pre_starting(void *arg)
+static void arch_cpu_pre_starting(void *arg)
 {
        local_ops->cache_all();
        local_ops->tlb_all();
@@ -317,7 +312,7 @@ void arch_cpu_pre_starting(void *arg)
        }
 }
 
-void arch_cpu_pre_online(void *arg)
+static void arch_cpu_pre_online(void *arg)
 {
        unsigned int cpuid = hard_smp_processor_id();
 
@@ -344,7 +339,7 @@ void arch_cpu_pre_online(void *arg)
        }
 }
 
-void sparc_start_secondary(void *arg)
+static void sparc_start_secondary(void *arg)
 {
        unsigned int cpu;
 
index 745a363..41aa247 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ftrace.h>
 #include <linux/cpu.h>
 #include <linux/slab.h>
+#include <linux/kgdb.h>
 
 #include <asm/head.h>
 #include <asm/ptrace.h>
@@ -35,6 +36,7 @@
 #include <asm/hvtramp.h>
 #include <asm/io.h>
 #include <asm/timer.h>
+#include <asm/setup.h>
 
 #include <asm/irq.h>
 #include <asm/irq_regs.h>
@@ -52,6 +54,7 @@
 #include <asm/pcr.h>
 
 #include "cpumap.h"
+#include "kernel.h"
 
 DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
 cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
@@ -272,14 +275,6 @@ static void smp_synchronize_one_tick(int cpu)
 }
 
 #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
-/* XXX Put this in some common place. XXX */
-static unsigned long kimage_addr_to_ra(void *p)
-{
-       unsigned long val = (unsigned long) p;
-
-       return kern_base + (val - KERNBASE);
-}
-
 static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg,
                                void **descrp)
 {
@@ -867,11 +862,6 @@ extern unsigned long xcall_flush_dcache_page_cheetah;
 #endif
 extern unsigned long xcall_flush_dcache_page_spitfire;
 
-#ifdef CONFIG_DEBUG_DCFLUSH
-extern atomic_t dcpage_flushes;
-extern atomic_t dcpage_flushes_xcall;
-#endif
-
 static inline void __local_flush_dcache_page(struct page *page)
 {
 #ifdef DCACHE_ALIASING_POSSIBLE
index f8933be..a1bb267 100644 (file)
@@ -143,7 +143,7 @@ static void sun4d_sbus_handler_irq(int sbusl)
        }
 }
 
-void sun4d_handler_irq(int pil, struct pt_regs *regs)
+void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
        /* SBUS IRQ level (1 - 7) */
@@ -236,7 +236,7 @@ static void sun4d_shutdown_irq(struct irq_data *data)
        irq_unlink(data->irq);
 }
 
-struct irq_chip sun4d_irq = {
+static struct irq_chip sun4d_irq = {
        .name           = "sun4d",
        .irq_startup    = sun4d_startup_irq,
        .irq_shutdown   = sun4d_shutdown_irq,
@@ -285,9 +285,9 @@ static void __init sun4d_load_profile_irqs(void)
        }
 }
 
-unsigned int _sun4d_build_device_irq(unsigned int real_irq,
-                                     unsigned int pil,
-                                     unsigned int board)
+static unsigned int _sun4d_build_device_irq(unsigned int real_irq,
+                                            unsigned int pil,
+                                            unsigned int board)
 {
        struct sun4d_handler_data *handler_data;
        unsigned int irq;
@@ -320,8 +320,8 @@ err_out:
 
 
 
-unsigned int sun4d_build_device_irq(struct platform_device *op,
-                                    unsigned int real_irq)
+static unsigned int sun4d_build_device_irq(struct platform_device *op,
+                                           unsigned int real_irq)
 {
        struct device_node *dp = op->dev.of_node;
        struct device_node *board_parent, *bus = dp->parent;
@@ -383,7 +383,8 @@ err_out:
        return irq;
 }
 
-unsigned int sun4d_build_timer_irq(unsigned int board, unsigned int real_irq)
+static unsigned int sun4d_build_timer_irq(unsigned int board,
+                                          unsigned int real_irq)
 {
        return _sun4d_build_device_irq(real_irq, real_irq, board);
 }
index 7136885..022c30c 100644 (file)
@@ -49,6 +49,8 @@
 #include <asm/mmu_context.h>
 #include <asm/compat_signal.h>
 
+#include "systbls.h"
+
 asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
 {
        if ((int)high < 0)
index 3a8d184..646988d 100644 (file)
@@ -24,6 +24,8 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
+#include "systbls.h"
+
 /* #define DEBUG_UNIMP_SYSCALL */
 
 /* XXX Make this per-binary type, this way we can detect the type of
@@ -68,7 +70,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way unix traditionally does this, though.
  */
-asmlinkage int sparc_pipe(struct pt_regs *regs)
+asmlinkage long sparc_pipe(struct pt_regs *regs)
 {
        int fd[2];
        int error;
@@ -93,7 +95,7 @@ int sparc_mmap_check(unsigned long addr, unsigned long len)
 
 /* Linux version of mmap */
 
-asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
        unsigned long prot, unsigned long flags, unsigned long fd,
        unsigned long pgoff)
 {
@@ -103,7 +105,7 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
                              pgoff >> (PAGE_SHIFT - 12));
 }
 
-asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
        unsigned long prot, unsigned long flags, unsigned long fd,
        unsigned long off)
 {
@@ -197,7 +199,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig,
        return ret;
 }
 
-asmlinkage int sys_getdomainname(char __user *name, int len)
+asmlinkage long sys_getdomainname(char __user *name, int len)
 {
        int nlen, err;
        
index beb0b5a..c85403d 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/unistd.h>
 
 #include "entry.h"
+#include "kernel.h"
 #include "systbls.h"
 
 /* #define DEBUG_UNIMP_SYSCALL */
index 26e6dd7..2dab823 100644 (file)
 #ifndef _SYSTBLS_H
 #define _SYSTBLS_H
 
+#include <linux/signal.h>
 #include <linux/kernel.h>
+#include <linux/compat.h>
 #include <linux/types.h>
-#include <linux/signal.h>
+
 #include <asm/utrap.h>
 
-extern asmlinkage unsigned long sys_getpagesize(void);
-extern asmlinkage long sparc_pipe(struct pt_regs *regs);
-extern asmlinkage long sys_sparc_ipc(unsigned int call, int first,
-                              unsigned long second,
-                              unsigned long third,
-                              void __user *ptr, long fifth);
-extern asmlinkage long sparc64_personality(unsigned long personality);
-extern asmlinkage long sys64_munmap(unsigned long addr, size_t len);
-extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
-                                            unsigned long old_len,
-                                            unsigned long new_len,
-                                            unsigned long flags,
-                                            unsigned long new_addr);
-extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs);
-extern asmlinkage long sys_getdomainname(char __user *name, int len);
-extern asmlinkage long sys_utrap_install(utrap_entry_t type,
-                                        utrap_handler_t new_p,
-                                        utrap_handler_t new_d,
-                                        utrap_handler_t __user *old_p,
-                                        utrap_handler_t __user *old_d);
-extern asmlinkage long sparc_memory_ordering(unsigned long model,
-                                            struct pt_regs *regs);
-extern asmlinkage long sys_rt_sigaction(int sig,
-                                       const struct sigaction __user *act,
-                                       struct sigaction __user *oact,
-                                       void __user *restorer,
-                                       size_t sigsetsize);
+asmlinkage unsigned long sys_getpagesize(void);
+asmlinkage long sparc_pipe(struct pt_regs *regs);
+asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs);
+asmlinkage long sys_getdomainname(char __user *name, int len);
+void do_rt_sigreturn(struct pt_regs *regs);
+asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
+                        unsigned long prot, unsigned long flags,
+                        unsigned long fd, unsigned long off);
+asmlinkage void sparc_breakpoint(struct pt_regs *regs);
+
+#ifdef CONFIG_SPARC32
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+                         unsigned long prot, unsigned long flags,
+                         unsigned long fd, unsigned long pgoff);
+long sparc_remap_file_pages(unsigned long start, unsigned long size,
+                           unsigned long prot, unsigned long pgoff,
+                           unsigned long flags);
 
-extern asmlinkage void sparc64_set_context(struct pt_regs *regs);
-extern asmlinkage void sparc64_get_context(struct pt_regs *regs);
-extern void do_rt_sigreturn(struct pt_regs *regs);
+#endif /* CONFIG_SPARC32 */
 
+#ifdef CONFIG_SPARC64
+asmlinkage long sys_sparc_ipc(unsigned int call, int first,
+                             unsigned long second,
+                             unsigned long third,
+                             void __user *ptr, long fifth);
+asmlinkage long sparc64_personality(unsigned long personality);
+asmlinkage long sys64_munmap(unsigned long addr, size_t len);
+asmlinkage unsigned long sys64_mremap(unsigned long addr,
+                                     unsigned long old_len,
+                                     unsigned long new_len,
+                                     unsigned long flags,
+                                     unsigned long new_addr);
+asmlinkage long sys_utrap_install(utrap_entry_t type,
+                                 utrap_handler_t new_p,
+                                 utrap_handler_t new_d,
+                                 utrap_handler_t __user *old_p,
+                                 utrap_handler_t __user *old_d);
+asmlinkage long sparc_memory_ordering(unsigned long model,
+                                     struct pt_regs *regs);
+asmlinkage void sparc64_set_context(struct pt_regs *regs);
+asmlinkage void sparc64_get_context(struct pt_regs *regs);
+asmlinkage long sys32_truncate64(const char __user * path,
+                                unsigned long high,
+                                unsigned long low);
+asmlinkage long sys32_ftruncate64(unsigned int fd,
+                                 unsigned long high,
+                                 unsigned long low);
+struct compat_stat64;
+asmlinkage long compat_sys_stat64(const char __user * filename,
+                                 struct compat_stat64 __user *statbuf);
+asmlinkage long compat_sys_lstat64(const char __user * filename,
+                                  struct compat_stat64 __user *statbuf);
+asmlinkage long compat_sys_fstat64(unsigned int fd,
+                                  struct compat_stat64 __user * statbuf);
+asmlinkage long compat_sys_fstatat64(unsigned int dfd,
+                                    const char __user *filename,
+                                    struct compat_stat64 __user * statbuf, int flag);
+asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
+                                       char __user *ubuf,
+                                       compat_size_t count,
+                                       unsigned long poshi,
+                                       unsigned long poslo);
+asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd,
+                                        char __user *ubuf,
+                                        compat_size_t count,
+                                        unsigned long poshi,
+                                        unsigned long poslo);
+asmlinkage long compat_sys_readahead(int fd,
+                                    unsigned long offhi,
+                                    unsigned long offlo,
+                                    compat_size_t count);
+long compat_sys_fadvise64(int fd,
+                         unsigned long offhi,
+                         unsigned long offlo,
+                         compat_size_t len, int advice);
+long compat_sys_fadvise64_64(int fd,
+                            unsigned long offhi, unsigned long offlo,
+                            unsigned long lenhi, unsigned long lenlo,
+                            int advice);
+long sys32_sync_file_range(unsigned int fd,
+                          unsigned long off_high, unsigned long off_low,
+                          unsigned long nb_high, unsigned long nb_low,
+                          unsigned int flags);
+asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo,
+                                    u32 lenhi, u32 lenlo);
+asmlinkage long compat_sys_fstat64(unsigned int fd,
+                                  struct compat_stat64 __user * statbuf);
+asmlinkage long compat_sys_fstatat64(unsigned int dfd,
+                                    const char __user *filename,
+                                    struct compat_stat64 __user * statbuf,
+                                    int flag);
+#endif /* CONFIG_SPARC64 */
 #endif /* _SYSTBLS_H */
diff --git a/arch/sparc/kernel/tadpole.c b/arch/sparc/kernel/tadpole.c
deleted file mode 100644 (file)
index 9aba8bd..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* tadpole.c: Probing for the tadpole clock stopping h/w at boot time.
- *
- * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-
-#include <asm/asi.h>
-#include <asm/oplib.h>
-#include <asm/io.h>
-
-#define MACIO_SCSI_CSR_ADDR    0x78400000
-#define MACIO_EN_DMA           0x00000200
-#define CLOCK_INIT_DONE                1
-
-static int clk_state;
-static volatile unsigned char *clk_ctrl;
-void (*cpu_pwr_save)(void);
-
-static inline unsigned int ldphys(unsigned int addr)
-{
-       unsigned long data;
-    
-       __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : 
-                            "=r" (data) :
-                            "r" (addr), "i" (ASI_M_BYPASS));
-       return data;
-}
-
-static void clk_init(void)
-{
-       __asm__ __volatile__("mov 0x6c, %%g1\n\t"
-                            "mov 0x4c, %%g2\n\t"
-                            "mov 0xdf, %%g3\n\t"
-                            "stb %%g1, [%0+3]\n\t"
-                            "stb %%g2, [%0+3]\n\t"
-                            "stb %%g3, [%0+3]\n\t" : :
-                            "r" (clk_ctrl) :
-                            "g1", "g2", "g3");
-}
-
-static void clk_slow(void)
-{
-       __asm__ __volatile__("mov 0xcc, %%g2\n\t"
-                            "mov 0x4c, %%g3\n\t"
-                            "mov 0xcf, %%g4\n\t"
-                            "mov 0xdf, %%g5\n\t"
-                            "stb %%g2, [%0+3]\n\t"
-                            "stb %%g3, [%0+3]\n\t"
-                            "stb %%g4, [%0+3]\n\t"
-                            "stb %%g5, [%0+3]\n\t" : :
-                            "r" (clk_ctrl) :
-                            "g2", "g3", "g4", "g5");
-}
-
-/*
- * Tadpole is guaranteed to be UP, using local_irq_save.
- */
-static void tsu_clockstop(void)
-{
-       unsigned int mcsr;
-       unsigned long flags;
-
-       if (!clk_ctrl)
-               return;
-       if (!(clk_state & CLOCK_INIT_DONE)) {
-               local_irq_save(flags);
-               clk_init();
-               clk_state |= CLOCK_INIT_DONE;       /* all done */
-               local_irq_restore(flags);
-               return;
-       }
-       if (!(clk_ctrl[2] & 1))
-               return;               /* no speed up yet */
-
-       local_irq_save(flags);
-
-       /* if SCSI DMA in progress, don't slow clock */
-       mcsr = ldphys(MACIO_SCSI_CSR_ADDR);
-       if ((mcsr&MACIO_EN_DMA) != 0) {
-               local_irq_restore(flags);
-               return;
-       }
-       /* TODO... the minimum clock setting ought to increase the
-        * memory refresh interval..
-        */
-       clk_slow();
-       local_irq_restore(flags);
-}
-
-static void swift_clockstop(void)
-{
-       if (!clk_ctrl)
-               return;
-       clk_ctrl[0] = 0;
-}
-
-void __init clock_stop_probe(void)
-{
-       phandle node, clk_nd;
-       char name[20];
-    
-       prom_getstring(prom_root_node, "name", name, sizeof(name));
-       if (strncmp(name, "Tadpole", 7))
-               return;
-       node = prom_getchild(prom_root_node);
-       node = prom_searchsiblings(node, "obio");
-       node = prom_getchild(node);
-       clk_nd = prom_searchsiblings(node, "clk-ctrl");
-       if (!clk_nd)
-               return;
-       printk("Clock Stopping h/w detected... ");
-       clk_ctrl = (char *) prom_getint(clk_nd, "address");
-       clk_state = 0;
-       if (name[10] == '\0') {
-               cpu_pwr_save = tsu_clockstop;
-               printk("enabled (S3)\n");
-       } else if ((name[10] == 'X') || (name[10] == 'G')) {
-               cpu_pwr_save = swift_clockstop;
-               printk("enabled (%s)\n",name+7);
-       } else
-               printk("disabled %s\n",name+7);
-}
index c4c27b0..5923d1e 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
+#include <asm/mc146818rtc.h>
 #include <asm/oplib.h>
 #include <asm/timex.h>
 #include <asm/timer.h>
@@ -47,6 +48,7 @@
 #include <asm/irq_regs.h>
 #include <asm/setup.h>
 
+#include "kernel.h"
 #include "irq.h"
 
 static __cacheline_aligned_in_smp DEFINE_SEQLOCK(timer_cs_lock);
@@ -83,7 +85,7 @@ unsigned long profile_pc(struct pt_regs *regs)
 
 EXPORT_SYMBOL(profile_pc);
 
-__volatile__ unsigned int *master_l10_counter;
+volatile u32 __iomem *master_l10_counter;
 
 int update_persistent_clock(struct timespec now)
 {
@@ -143,9 +145,9 @@ static __init void setup_timer_ce(void)
 
 static unsigned int sbus_cycles_offset(void)
 {
-       unsigned int val, offset;
+       u32 val, offset;
 
-       val = *master_l10_counter;
+       val = sbus_readl(master_l10_counter);
        offset = (val >> TIMER_VALUE_SHIFT) & TIMER_VALUE_MASK;
 
        /* Limit hit? */
index 6629829..6fd386c 100644 (file)
@@ -44,7 +44,7 @@ static void instruction_dump(unsigned long *pc)
 #define __SAVE __asm__ __volatile__("save %sp, -0x40, %sp\n\t")
 #define __RESTORE __asm__ __volatile__("restore %g0, %g0, %g0\n\t")
 
-void die_if_kernel(char *str, struct pt_regs *regs)
+void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
 {
        static int die_counter;
        int count = 0;
@@ -219,8 +219,6 @@ static unsigned long fake_fsr;
 static unsigned long fake_queue[32] __attribute__ ((aligned (8)));
 static unsigned long fake_depth;
 
-extern int do_mathemu(struct pt_regs *, struct task_struct *);
-
 void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
                 unsigned long psr)
 {
index 4ced92f..fb6640e 100644 (file)
 #include <asm/prom.h>
 #include <asm/memctrl.h>
 #include <asm/cacheflush.h>
+#include <asm/setup.h>
 
 #include "entry.h"
+#include "kernel.h"
 #include "kstack.h"
 
 /* When an irrecoverable trap occurs at tl > 0, the trap entry
@@ -2209,8 +2211,6 @@ out:
        exception_exit(prev_state);
 }
 
-extern int do_mathemu(struct pt_regs *, struct fpustate *, bool);
-
 void do_fpother(struct pt_regs *regs)
 {
        enum ctx_state prev_state = exception_enter();
@@ -2383,7 +2383,7 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
        return (struct reg_window *) (fp + STACK_BIAS);
 }
 
-void die_if_kernel(char *str, struct pt_regs *regs)
+void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
 {
        static int die_counter;
        int count = 0;
@@ -2433,9 +2433,6 @@ EXPORT_SYMBOL(die_if_kernel);
 #define VIS_OPCODE_MASK        ((0x3 << 30) | (0x3f << 19))
 #define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19))
 
-extern int handle_popc(u32 insn, struct pt_regs *regs);
-extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);
-
 void do_illegal_instruction(struct pt_regs *regs)
 {
        enum ctx_state prev_state = exception_enter();
@@ -2486,8 +2483,6 @@ out:
        exception_exit(prev_state);
 }
 
-extern void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn);
-
 void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr)
 {
        enum ctx_state prev_state = exception_enter();
index c0ec897..c5c61b3 100644 (file)
 #include <linux/smp.h>
 #include <linux/perf_event.h>
 
+#include <asm/setup.h>
+
+#include "kernel.h"
+
 enum direction {
        load,    /* ld, ldd, ldh, ldsh */
        store,   /* st, std, sth, stsh */
index 35ab8b6..62098a8 100644 (file)
 #include <linux/context_tracking.h>
 #include <asm/fpumacro.h>
 #include <asm/cacheflush.h>
+#include <asm/setup.h>
 
 #include "entry.h"
+#include "kernel.h"
 
 enum direction {
        load,    /* ld, ldd, ldh, ldsh */
index 3107381..87bab0a 100644 (file)
 #include <linux/mm.h>
 #include <linux/smp.h>
 
+#include <asm/cacheflush.h>
 #include <asm/uaccess.h>
 
+#include "kernel.h"
+
 /* Do save's until all user register windows are out of the cpu. */
 void flush_user_windows(void)
 {
index dbe119b..3269b02 100644 (file)
@@ -41,7 +41,7 @@ lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o
 lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o
 lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
 
-obj-y                 += iomap.o
+obj-$(CONFIG_SPARC64) += iomap.o
 obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o
 obj-y                 += ksyms.o
 obj-$(CONFIG_SPARC64) += PeeCeeI.o
index d1b2aff..bb587d5 100644 (file)
@@ -4,20 +4,20 @@
 #include <asm/byteorder.h>
 
 #define add_ssaaaa(sh, sl, ah, al, bh, bl)                             \
-  __asm__ ("addcc %r4,%5,%1\n\t"                                               \
+  __asm__ ("addcc %r4,%5,%1\n\t"                                       \
           "addx %r2,%3,%0\n"                                           \
-          : "=r" ((USItype)(sh)),                                      \
-            "=&r" ((USItype)(sl))                                      \
+          : "=r" (sh),                                                 \
+            "=&r" (sl)                                                 \
           : "%rJ" ((USItype)(ah)),                                     \
             "rI" ((USItype)(bh)),                                      \
             "%rJ" ((USItype)(al)),                                     \
             "rI" ((USItype)(bl))                                       \
           : "cc")
 #define sub_ddmmss(sh, sl, ah, al, bh, bl)                             \
-  __asm__ ("subcc %r4,%5,%1\n\t"                                               \
+  __asm__ ("subcc %r4,%5,%1\n\t"                                       \
           "subx %r2,%3,%0\n"                                           \
-          : "=r" ((USItype)(sh)),                                      \
-            "=&r" ((USItype)(sl))                                      \
+          : "=r" (sh),                                                 \
+            "=&r" (sl)                                                 \
           : "rJ" ((USItype)(ah)),                                      \
             "rI" ((USItype)(bh)),                                      \
             "rJ" ((USItype)(al)),                                      \
@@ -65,8 +65,8 @@
        "mulscc %%g1,0,%%g1\n\t"                                        \
        "add    %%g1,%%g2,%0\n\t"                                       \
        "rd     %%y,%1\n"                                               \
-          : "=r" ((USItype)(w1)),                                      \
-            "=r" ((USItype)(w0))                                       \
+          : "=r" (w1),                                                 \
+            "=r" (w0)                                                  \
           : "%rI" ((USItype)(u)),                                      \
             "r" ((USItype)(v))                                         \
           : "%g1", "%g2", "cc")
@@ -98,8 +98,8 @@
           "sub %1,%2,%1\n\t"                                           \
           "3:  xnor    %0,0,%0\n\t"                                    \
           "! End of inline udiv_qrnnd\n"                               \
-          : "=&r" ((USItype)(q)),                                      \
-            "=&r" ((USItype)(r))                                       \
+          : "=&r" (q),                                                 \
+            "=&r" (r)                                                  \
           : "r" ((USItype)(d)),                                        \
             "1" ((USItype)(n1)),                                       \
             "0" ((USItype)(n0)) : "%g1", "cc")
index 425d3cf..51320a8 100644 (file)
@@ -17,8 +17,8 @@
           "bcs,a,pn %%xcc, 1f\n\t"             \
           "add %0, 1, %0\n"                    \
           "1:"                                 \
-          : "=r" ((UDItype)(sh)),              \
-            "=&r" ((UDItype)(sl))              \
+          : "=r" (sh),                         \
+            "=&r" (sl)                         \
           : "r" ((UDItype)(ah)),               \
             "r" ((UDItype)(bh)),               \
             "r" ((UDItype)(al)),               \
@@ -31,8 +31,8 @@
           "bcs,a,pn %%xcc, 1f\n\t"             \
           "sub %0, 1, %0\n"                    \
           "1:"                                 \
-          : "=r" ((UDItype)(sh)),              \
-            "=&r" ((UDItype)(sl))              \
+          : "=r" (sh),                         \
+            "=&r" (sl)                         \
           : "r" ((UDItype)(ah)),               \
             "r" ((UDItype)(bh)),               \
             "r" ((UDItype)(al)),               \
@@ -64,8 +64,8 @@
                   "sllx %3,32,%3\n\t"                  \
                   "add %1,%3,%1\n\t"                   \
                   "add %5,%2,%0"                       \
-          : "=r" ((UDItype)(wh)),                      \
-            "=&r" ((UDItype)(wl)),                     \
+          : "=r" (wh),                                 \
+            "=&r" (wl),                                \
             "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
           : "r" ((UDItype)(u)),                        \
             "r" ((UDItype)(v))                         \
index 59dbd46..908e8c1 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/openprom.h>
 #include <asm/oplib.h>
+#include <asm/setup.h>
 #include <asm/smp.h>
 #include <asm/traps.h>
 #include <asm/uaccess.h>
 
-int show_unhandled_signals = 1;
+#include "mm_32.h"
 
-static void unhandled_fault(unsigned long, struct task_struct *,
-               struct pt_regs *) __attribute__ ((noreturn));
+int show_unhandled_signals = 1;
 
 static void __noreturn unhandled_fault(unsigned long address,
                                       struct task_struct *tsk,
@@ -141,9 +141,6 @@ static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs,
        force_sig_info (sig, &info, current);
 }
 
-extern unsigned long safe_compute_effective_address(struct pt_regs *,
-                                                   unsigned int);
-
 static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
 {
        unsigned int insn;
index 4ced3fc..587cd05 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/lsu.h>
 #include <asm/sections.h>
 #include <asm/mmu_context.h>
+#include <asm/setup.h>
 
 int show_unhandled_signals = 1;
 
@@ -196,9 +197,6 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
        force_sig_info(sig, &info, current);
 }
 
-extern int handle_ldf_stq(u32, struct pt_regs *);
-extern int handle_ld_nf(u32, struct pt_regs *);
-
 static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn)
 {
        if (!insn) {
index db69870..eb82871 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/vaddrs.h>
 #include <asm/pgalloc.h>       /* bug in asm-generic/tlb.h: check_pgt_cache */
+#include <asm/setup.h>
 #include <asm/tlb.h>
 #include <asm/prom.h>
 #include <asm/leon.h>
 
+#include "mm_32.h"
+
 unsigned long *sparc_valid_addr_bitmap;
 EXPORT_SYMBOL(sparc_valid_addr_bitmap);
 
@@ -63,7 +66,6 @@ void show_mem(unsigned int filter)
 }
 
 
-extern unsigned long cmdline_memory_size;
 unsigned long last_valid_pfn;
 
 unsigned long calc_highpages(void)
@@ -246,9 +248,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
  * init routine based upon the Sun model type on the Sparc.
  *
  */
-extern void srmmu_paging_init(void);
-extern void device_scan(void);
-
 void __init paging_init(void)
 {
        srmmu_paging_init();
index ed3c969..16b58ff 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/prom.h>
 #include <asm/mdesc.h>
 #include <asm/cpudata.h>
+#include <asm/setup.h>
 #include <asm/irq.h>
 
 #include "init_64.h"
@@ -794,11 +795,11 @@ struct node_mem_mask {
 static struct node_mem_mask node_masks[MAX_NUMNODES];
 static int num_node_masks;
 
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+
 int numa_cpu_lookup_table[NR_CPUS];
 cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
 
-#ifdef CONFIG_NEED_MULTIPLE_NODES
-
 struct mdesc_mblock {
        u64     base;
        u64     size;
@@ -887,17 +888,21 @@ static void __init allocate_node_data(int nid)
 
 static void init_node_masks_nonnuma(void)
 {
+#ifdef CONFIG_NEED_MULTIPLE_NODES
        int i;
+#endif
 
        numadbg("Initializing tables for non-numa.\n");
 
        node_masks[0].mask = node_masks[0].val = 0;
        num_node_masks = 1;
 
+#ifdef CONFIG_NEED_MULTIPLE_NODES
        for (i = 0; i < NR_CPUS; i++)
                numa_cpu_lookup_table[i] = 0;
 
        cpumask_setall(&numa_cpumask_lookup_table[0]);
+#endif
 }
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
index 5d3782d..0668b36 100644 (file)
@@ -21,7 +21,7 @@ extern unsigned int sparc64_highest_unlocked_tlb_ent;
 extern unsigned long sparc64_kern_pri_context;
 extern unsigned long sparc64_kern_pri_nuc_bits;
 extern unsigned long sparc64_kern_sec_context;
-extern void mmu_info(struct seq_file *m);
+void mmu_info(struct seq_file *m);
 
 struct linux_prom_translation {
        unsigned long virt;
@@ -36,7 +36,7 @@ extern unsigned int prom_trans_ents;
 /* Exported for SMP bootup purposes. */
 extern unsigned long kern_locked_tte_data;
 
-extern void prom_world(int enter);
+void prom_world(int enter);
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 #define VMEMMAP_CHUNK_SHIFT    22
index eb99862..f311bf2 100644 (file)
@@ -25,6 +25,8 @@
 #include <asm/dma.h>
 #include <asm/oplib.h>
 
+#include "mm_32.h"
+
 /* #define IOUNIT_DEBUG */
 #ifdef IOUNIT_DEBUG
 #define IOD(x) printk(x)
@@ -38,7 +40,8 @@
 static void __init iounit_iommu_init(struct platform_device *op)
 {
        struct iounit_struct *iounit;
-       iopte_t *xpt, *xptend;
+       iopte_t __iomem *xpt;
+       iopte_t __iomem *xptend;
 
        iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
        if (!iounit) {
@@ -62,10 +65,10 @@ static void __init iounit_iommu_init(struct platform_device *op)
        op->dev.archdata.iommu = iounit;
        iounit->page_table = xpt;
        spin_lock_init(&iounit->lock);
-       
-       for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t);
-            xpt < xptend;)
-               iopte_val(*xpt++) = 0;
+
+       xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t);
+       for (; xpt < xptend; xpt++)
+               sbus_writel(0, xpt);
 }
 
 static int __init iounit_init(void)
@@ -130,7 +133,7 @@ nexti:      scan = find_next_zero_bit(iounit->bmap, limit, scan);
        vaddr = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + (vaddr & ~PAGE_MASK);
        for (k = 0; k < npages; k++, iopte = __iopte(iopte_val(iopte) + 0x100), scan++) {
                set_bit(scan, iounit->bmap);
-               iounit->page_table[scan] = iopte;
+               sbus_writel(iopte, &iounit->page_table[scan]);
        }
        IOD(("%08lx\n", vaddr));
        return vaddr;
@@ -202,7 +205,7 @@ static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned lon
        struct iounit_struct *iounit = dev->archdata.iommu;
        unsigned long page, end;
        pgprot_t dvma_prot;
-       iopte_t *iopte;
+       iopte_t __iomem *iopte;
 
        *pba = addr;
 
@@ -224,8 +227,8 @@ static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned lon
                        
                        i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT);
 
-                       iopte = (iopte_t *)(iounit->page_table + i);
-                       *iopte = MKIOPTE(__pa(page));
+                       iopte = iounit->page_table + i;
+                       sbus_writel(MKIOPTE(__pa(page)), iopte);
                }
                addr += PAGE_SIZE;
                va += PAGE_SIZE;
index 28f96f2..491511d 100644 (file)
@@ -27,6 +27,8 @@
 #include <asm/iommu.h>
 #include <asm/dma.h>
 
+#include "mm_32.h"
+
 /*
  * This can be sized dynamically, but we will do this
  * only when we have a guidance about actual I/O pressures.
@@ -37,9 +39,6 @@
 #define IOMMU_NPTES    (IOMMU_WINSIZE/PAGE_SIZE)       /* 64K PTEs, 256KB */
 #define IOMMU_ORDER    6                               /* 4096 * (1<<6) */
 
-/* srmmu.c */
-extern int viking_mxcc_present;
-extern int flush_page_for_dma_global;
 static int viking_flush;
 /* viking.S */
 extern void viking_flush_page(unsigned long page);
@@ -59,6 +58,8 @@ static void __init sbus_iommu_init(struct platform_device *op)
        struct iommu_struct *iommu;
        unsigned int impl, vers;
        unsigned long *bitmap;
+       unsigned long control;
+       unsigned long base;
        unsigned long tmp;
 
        iommu = kmalloc(sizeof(struct iommu_struct), GFP_KERNEL);
@@ -73,12 +74,14 @@ static void __init sbus_iommu_init(struct platform_device *op)
                prom_printf("Cannot map IOMMU registers\n");
                prom_halt();
        }
-       impl = (iommu->regs->control & IOMMU_CTRL_IMPL) >> 28;
-       vers = (iommu->regs->control & IOMMU_CTRL_VERS) >> 24;
-       tmp = iommu->regs->control;
-       tmp &= ~(IOMMU_CTRL_RNGE);
-       tmp |= (IOMMU_RNGE_256MB | IOMMU_CTRL_ENAB);
-       iommu->regs->control = tmp;
+
+       control = sbus_readl(&iommu->regs->control);
+       impl = (control & IOMMU_CTRL_IMPL) >> 28;
+       vers = (control & IOMMU_CTRL_VERS) >> 24;
+       control &= ~(IOMMU_CTRL_RNGE);
+       control |= (IOMMU_RNGE_256MB | IOMMU_CTRL_ENAB);
+       sbus_writel(control, &iommu->regs->control);
+
        iommu_invalidate(iommu->regs);
        iommu->start = IOMMU_START;
        iommu->end = 0xffffffff;
@@ -100,7 +103,9 @@ static void __init sbus_iommu_init(struct platform_device *op)
        memset(iommu->page_table, 0, IOMMU_NPTES*sizeof(iopte_t));
        flush_cache_all();
        flush_tlb_all();
-       iommu->regs->base = __pa((unsigned long) iommu->page_table) >> 4;
+
+       base = __pa((unsigned long)iommu->page_table) >> 4;
+       sbus_writel(base, &iommu->regs->base);
        iommu_invalidate(iommu->regs);
 
        bitmap = kmalloc(IOMMU_NPTES>>3, GFP_KERNEL);
index 5bed085..3b17b6f 100644 (file)
 #include <asm/leon.h>
 #include <asm/tlbflush.h>
 
-#include "srmmu.h"
+#include "mm_32.h"
 
 int leon_flush_during_switch = 1;
-int srmmu_swprobe_trace;
+static int srmmu_swprobe_trace;
 
 static inline unsigned long leon_get_ctable_ptr(void)
 {
diff --git a/arch/sparc/mm/mm_32.h b/arch/sparc/mm/mm_32.h
new file mode 100644 (file)
index 0000000..a6c27ca
--- /dev/null
@@ -0,0 +1,24 @@
+/* fault_32.c - visible as they are called from assembler */
+asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
+                            unsigned long address);
+asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
+                               unsigned long address);
+
+void window_overflow_fault(void);
+void window_underflow_fault(unsigned long sp);
+void window_ret_fault(struct pt_regs *regs);
+
+/* srmmu.c */
+extern char *srmmu_name;
+extern int viking_mxcc_present;
+extern int flush_page_for_dma_global;
+
+extern void (*poke_srmmu)(void);
+
+void __init srmmu_paging_init(void);
+
+/* iommu.c */
+void ld_mmu_iommu(void);
+
+/* io-unit.c */
+void ld_mmu_iounit(void);
index cfbe53c..be65f03 100644 (file)
@@ -49,7 +49,7 @@
 #include <asm/mxcc.h>
 #include <asm/ross.h>
 
-#include "srmmu.h"
+#include "mm_32.h"
 
 enum mbus_module srmmu_modtype;
 static unsigned int hwbug_bitmask;
@@ -100,7 +100,6 @@ static unsigned long srmmu_nocache_end;
 #define SRMMU_NOCACHE_ALIGN_MAX (sizeof(ctxd_t)*SRMMU_MAX_CONTEXTS)
 
 void *srmmu_nocache_pool;
-void *srmmu_nocache_bitmap;
 static struct bit_map srmmu_nocache_map;
 
 static inline int srmmu_pmd_none(pmd_t pmd)
@@ -173,7 +172,7 @@ static void *__srmmu_get_nocache(int size, int align)
                printk(KERN_ERR "srmmu: out of nocache %d: %d/%d\n",
                       size, (int) srmmu_nocache_size,
                       srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT);
-               return 0;
+               return NULL;
        }
 
        addr = SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT);
@@ -269,6 +268,7 @@ static void __init srmmu_nocache_calcsize(void)
 
 static void __init srmmu_nocache_init(void)
 {
+       void *srmmu_nocache_bitmap;
        unsigned int bitmap_bits;
        pgd_t *pgd;
        pmd_t *pmd;
@@ -728,7 +728,7 @@ static inline unsigned long srmmu_probe(unsigned long vaddr)
                                     "=r" (retval) :
                                     "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
        } else {
-               retval = leon_swprobe(vaddr, 0);
+               retval = leon_swprobe(vaddr, NULL);
        }
        return retval;
 }
@@ -865,8 +865,6 @@ static void __init map_kernel(void)
 
 void (*poke_srmmu)(void) = NULL;
 
-extern unsigned long bootmem_init(unsigned long *pages_avail);
-
 void __init srmmu_paging_init(void)
 {
        int i;
@@ -1771,9 +1769,6 @@ static struct sparc32_cachetlb_ops smp_cachetlb_ops = {
 /* Load up routines and constants for sun4m and sun4d mmu */
 void __init load_mmu(void)
 {
-       extern void ld_mmu_iommu(void);
-       extern void ld_mmu_iounit(void);
-
        /* Functions */
        get_srmmu_type();
 
diff --git a/arch/sparc/mm/srmmu.h b/arch/sparc/mm/srmmu.h
deleted file mode 100644 (file)
index 5703274..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/* srmmu.c */
-extern char *srmmu_name;
-
-extern void (*poke_srmmu)(void);
index fe19b81..a065766 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
+#include <asm/setup.h>
 #include <asm/tsb.h>
 #include <asm/tlb.h>
 #include <asm/oplib.h>
index f178b9d..53a696d 100644 (file)
@@ -81,11 +81,6 @@ void prom_feval(const char *fstring)
 }
 EXPORT_SYMBOL(prom_feval);
 
-#ifdef CONFIG_SMP
-extern void smp_capture(void);
-extern void smp_release(void);
-#endif
-
 /* Drop into the prom, with the chance to continue with the 'go'
  * prom command.
  */
index aafad6f..928237a 100644 (file)
@@ -51,9 +51,6 @@ config ARCH_HAS_ILOG2_U32
 config ARCH_HAS_ILOG2_U64
        bool
 
-config ARCH_HAS_CPUFREQ
-       bool
-
 config GENERIC_HWEIGHT
        def_bool y
 
@@ -87,7 +84,6 @@ config ARCH_PUV3
        select GENERIC_CLOCKEVENTS
        select HAVE_CLK
        select ARCH_REQUIRE_GPIOLIB
-       select ARCH_HAS_CPUFREQ
 
 # CONFIGs for ARCH_PUV3
 
@@ -198,9 +194,7 @@ menu "Power management options"
 
 source "kernel/power/Kconfig"
 
-if ARCH_HAS_CPUFREQ
 source "drivers/cpufreq/Kconfig"
-endif
 
 config ARCH_SUSPEND_POSSIBLE
        def_bool y if !ARCH_FPGA
index 39decb6..cb1d8fd 100644 (file)
@@ -39,10 +39,37 @@ extern void __uc32_iounmap(volatile void __iomem *addr);
 #define ioremap_nocache(cookie, size)  __uc32_ioremap(cookie, size)
 #define iounmap(cookie)                        __uc32_iounmap(cookie)
 
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+
 #define HAVE_ARCH_PIO_SIZE
 #define PIO_OFFSET             (unsigned int)(PCI_IOBASE)
 #define PIO_MASK               (unsigned int)(IO_SPACE_LIMIT)
 #define PIO_RESERVED           (PIO_OFFSET + PIO_MASK + 1)
 
+#ifdef CONFIG_STRICT_DEVMEM
+
+#include <linux/ioport.h>
+#include <linux/mm.h>
+
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain
+ * address is valid. The argument is a physical page number.
+ * We mimic x86 here by disallowing access to system RAM as well as
+ * device-exclusive MMIO regions. This effectively disable read()/write()
+ * on /dev/mem.
+ */
+static inline int devmem_is_allowed(unsigned long pfn)
+{
+       if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+               return 0;
+       if (!page_is_ram(pfn))
+               return 1;
+       return 0;
+}
+
+#endif /* CONFIG_STRICT_DEVMEM */
+
 #endif /* __KERNEL__ */
 #endif /* __UNICORE_IO_H__ */
index 233c258..ed6f7d0 100644 (file)
@@ -87,16 +87,16 @@ extern pgprot_t pgprot_kernel;
 
 #define PAGE_NONE              pgprot_user
 #define PAGE_SHARED            __pgprot(pgprot_val(pgprot_user | PTE_READ \
-                                                               | PTE_WRITE)
+                                                               | PTE_WRITE))
 #define PAGE_SHARED_EXEC       __pgprot(pgprot_val(pgprot_user | PTE_READ \
                                                                | PTE_WRITE \
-                                                               | PTE_EXEC)
+                                                               | PTE_EXEC))
 #define PAGE_COPY              __pgprot(pgprot_val(pgprot_user | PTE_READ)
 #define PAGE_COPY_EXEC         __pgprot(pgprot_val(pgprot_user | PTE_READ \
-                                                               | PTE_EXEC)
-#define PAGE_READONLY          __pgprot(pgprot_val(pgprot_user | PTE_READ)
+                                                               | PTE_EXEC))
+#define PAGE_READONLY          __pgprot(pgprot_val(pgprot_user | PTE_READ))
 #define PAGE_READONLY_EXEC     __pgprot(pgprot_val(pgprot_user | PTE_READ \
-                                                               | PTE_EXEC)
+                                                               | PTE_EXEC))
 #define PAGE_KERNEL            pgprot_kernel
 #define PAGE_KERNEL_EXEC       __pgprot(pgprot_val(pgprot_kernel | PTE_EXEC))
 
index 9df53d9..02bf5a4 100644 (file)
@@ -55,6 +55,7 @@ static inline int valid_user_regs(struct pt_regs *regs)
 
 #define instruction_pointer(regs)      ((regs)->UCreg_pc)
 #define user_stack_pointer(regs)       ((regs)->UCreg_sp)
+#define profile_pc(regs)               instruction_pointer(regs)
 
 #endif /* __ASSEMBLY__ */
 #endif
index 18d4563..b1ca775 100644 (file)
@@ -179,7 +179,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        }
 #ifdef CONFIG_CPU_FREQ
        if (clk == &clk_mclk_clk) {
-               u32 pll_rate, divstatus = PM_DIVSTATUS;
+               u32 pll_rate, divstatus = readl(PM_DIVSTATUS);
                int ret, i;
 
                /* lookup mclk_clk_table */
@@ -201,10 +201,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
                                / (((divstatus & 0x0000f000) >> 12) + 1);
 
                /* set pll sys cfg reg. */
-               PM_PLLSYSCFG = pll_rate;
+               writel(pll_rate, PM_PLLSYSCFG);
 
-               PM_PMCR = PM_PMCR_CFBSYS;
-               while ((PM_PLLDFCDONE & PM_PLLDFCDONE_SYSDFC)
+               writel(PM_PMCR_CFBSYS, PM_PMCR);
+               while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_SYSDFC)
                                != PM_PLLDFCDONE_SYSDFC)
                        udelay(100);
                        /* about 1ms */
index d285d71..0323528 100644 (file)
 
 #include "ksyms.h"
 
+EXPORT_SYMBOL(find_first_bit);
+EXPORT_SYMBOL(find_first_zero_bit);
 EXPORT_SYMBOL(find_next_zero_bit);
 EXPORT_SYMBOL(find_next_bit);
 
-EXPORT_SYMBOL(__backtrace);
-
        /* platform dependent support */
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__const_udelay);
 
-       /* networking */
-EXPORT_SYMBOL(csum_partial);
-EXPORT_SYMBOL(csum_partial_copy_from_user);
-EXPORT_SYMBOL(csum_partial_copy_nocheck);
-EXPORT_SYMBOL(__csum_ipv6_magic);
-
-       /* io */
-#ifndef __raw_readsb
-EXPORT_SYMBOL(__raw_readsb);
-#endif
-#ifndef __raw_readsw
-EXPORT_SYMBOL(__raw_readsw);
-#endif
-#ifndef __raw_readsl
-EXPORT_SYMBOL(__raw_readsl);
-#endif
-#ifndef __raw_writesb
-EXPORT_SYMBOL(__raw_writesb);
-#endif
-#ifndef __raw_writesw
-EXPORT_SYMBOL(__raw_writesw);
-#endif
-#ifndef __raw_writesl
-EXPORT_SYMBOL(__raw_writesl);
-#endif
-
        /* string / mem functions */
 EXPORT_SYMBOL(strchr);
 EXPORT_SYMBOL(strrchr);
@@ -76,23 +50,12 @@ EXPORT_SYMBOL(__copy_from_user);
 EXPORT_SYMBOL(__copy_to_user);
 EXPORT_SYMBOL(__clear_user);
 
-EXPORT_SYMBOL(__get_user_1);
-EXPORT_SYMBOL(__get_user_2);
-EXPORT_SYMBOL(__get_user_4);
-
-EXPORT_SYMBOL(__put_user_1);
-EXPORT_SYMBOL(__put_user_2);
-EXPORT_SYMBOL(__put_user_4);
-EXPORT_SYMBOL(__put_user_8);
-
 EXPORT_SYMBOL(__ashldi3);
 EXPORT_SYMBOL(__ashrdi3);
 EXPORT_SYMBOL(__divsi3);
 EXPORT_SYMBOL(__lshrdi3);
 EXPORT_SYMBOL(__modsi3);
-EXPORT_SYMBOL(__muldi3);
 EXPORT_SYMBOL(__ucmpdi2);
 EXPORT_SYMBOL(__udivsi3);
 EXPORT_SYMBOL(__umodsi3);
-EXPORT_SYMBOL(__bswapsi2);
 
index 185cdc7..31472ad 100644 (file)
@@ -8,8 +8,6 @@ extern void __ashrdi3(void);
 extern void __divsi3(void);
 extern void __lshrdi3(void);
 extern void __modsi3(void);
-extern void __muldi3(void);
 extern void __ucmpdi2(void);
 extern void __udivsi3(void);
 extern void __umodsi3(void);
-extern void __bswapsi2(void);
index 16bd149..dc41f6d 100644 (file)
 
 void *module_alloc(unsigned long size)
 {
-       struct vm_struct *area;
-
-       size = PAGE_ALIGN(size);
-       area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
-       if (!area)
-               return NULL;
-
-       return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
+       return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+                               GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE,
+                               __builtin_return_address(0));
 }
 
 int
index 778ebba..b008e99 100644 (file)
@@ -60,6 +60,7 @@ void machine_halt(void)
  * Function pointers to optional machine specific functions
  */
 void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
 
 void machine_power_off(void)
 {
index 87adbf5..3fa317f 100644 (file)
@@ -53,6 +53,10 @@ struct stack {
 
 static struct stack stacks[NR_CPUS];
 
+#ifdef CONFIG_VGA_CONSOLE
+struct screen_info screen_info;
+#endif
+
 char elf_platform[ELF_PLATFORM_SIZE];
 EXPORT_SYMBOL(elf_platform);
 
index de7dc5f..24e8360 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/uaccess.h>
 
+#include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/unaligned.h>
 
index f30071e..21c00fc 100644 (file)
@@ -19,5 +19,7 @@
 EXPORT_SYMBOL(cpu_dcache_clean_area);
 EXPORT_SYMBOL(cpu_set_pte);
 
+EXPORT_SYMBOL(__cpuc_coherent_kern_range);
+
 EXPORT_SYMBOL(__cpuc_dma_flush_range);
 EXPORT_SYMBOL(__cpuc_dma_clean_range);
index fcefdda..a8f749e 100644 (file)
@@ -1672,7 +1672,6 @@ config RELOCATABLE
 config RANDOMIZE_BASE
        bool "Randomize the address of the kernel image"
        depends on RELOCATABLE
-       depends on !HIBERNATION
        default n
        ---help---
           Randomizes the physical and virtual address at which the
index 4dbf967..fc6091a 100644 (file)
@@ -289,10 +289,17 @@ unsigned char *choose_kernel_location(unsigned char *input,
        unsigned long choice = (unsigned long)output;
        unsigned long random;
 
+#ifdef CONFIG_HIBERNATION
+       if (!cmdline_find_option_bool("kaslr")) {
+               debug_putstr("KASLR disabled by default...\n");
+               goto out;
+       }
+#else
        if (cmdline_find_option_bool("nokaslr")) {
-               debug_putstr("KASLR disabled...\n");
+               debug_putstr("KASLR disabled by cmdline...\n");
                goto out;
        }
+#endif
 
        /* Record the various known unsafe memory ranges. */
        mem_avoid_init((unsigned long)input, input_size,
index cb6cfcd..a80cbb8 100644 (file)
@@ -43,7 +43,7 @@ extern int vector_used_by_percpu_irq(unsigned int vector);
 extern void init_ISA_irqs(void);
 
 #ifdef CONFIG_X86_LOCAL_APIC
-void arch_trigger_all_cpu_backtrace(void);
+void arch_trigger_all_cpu_backtrace(bool);
 #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
 #endif
 
index c3fcb5d..6a1e71b 100644 (file)
@@ -33,31 +33,41 @@ static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
 /* "in progress" flag of arch_trigger_all_cpu_backtrace */
 static unsigned long backtrace_flag;
 
-void arch_trigger_all_cpu_backtrace(void)
+void arch_trigger_all_cpu_backtrace(bool include_self)
 {
        int i;
+       int cpu = get_cpu();
 
-       if (test_and_set_bit(0, &backtrace_flag))
+       if (test_and_set_bit(0, &backtrace_flag)) {
                /*
                 * If there is already a trigger_all_cpu_backtrace() in progress
                 * (backtrace_flag == 1), don't output double cpu dump infos.
                 */
+               put_cpu();
                return;
+       }
 
        cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask);
+       if (!include_self)
+               cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
 
-       printk(KERN_INFO "sending NMI to all CPUs:\n");
-       apic->send_IPI_all(NMI_VECTOR);
+       if (!cpumask_empty(to_cpumask(backtrace_mask))) {
+               pr_info("sending NMI to %s CPUs:\n",
+                       (include_self ? "all" : "other"));
+               apic->send_IPI_mask(to_cpumask(backtrace_mask), NMI_VECTOR);
+       }
 
        /* Wait for up to 10 seconds for all CPUs to do the backtrace */
        for (i = 0; i < 10 * 1000; i++) {
                if (cpumask_empty(to_cpumask(backtrace_mask)))
                        break;
                mdelay(1);
+               touch_softlockup_watchdog();
        }
 
        clear_bit(0, &backtrace_flag);
        smp_mb__after_atomic();
+       put_cpu();
 }
 
 static int
index f0da82b..dbaa23e 100644 (file)
@@ -423,9 +423,10 @@ sysenter_past_esp:
        jnz sysenter_audit
 sysenter_do_call:
        cmpl $(NR_syscalls), %eax
-       jae syscall_badsys
+       jae sysenter_badsys
        call *sys_call_table(,%eax,4)
        movl %eax,PT_EAX(%esp)
+sysenter_after_call:
        LOCKDEP_SYS_EXIT
        DISABLE_INTERRUPTS(CLBR_ANY)
        TRACE_IRQS_OFF
@@ -675,7 +676,12 @@ END(syscall_fault)
 
 syscall_badsys:
        movl $-ENOSYS,PT_EAX(%esp)
-       jmp resume_userspace
+       jmp syscall_exit
+END(syscall_badsys)
+
+sysenter_badsys:
+       movl $-ENOSYS,PT_EAX(%esp)
+       jmp sysenter_after_call
 END(syscall_badsys)
        CFI_ENDPROC
 
index a0da58d..2851d63 100644 (file)
@@ -363,7 +363,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
 
                /* Set up to return from userspace.  */
                restorer = current->mm->context.vdso +
-                       selected_vdso32->sym___kernel_sigreturn;
+                       selected_vdso32->sym___kernel_rt_sigreturn;
                if (ksig->ka.sa.sa_flags & SA_RESTORER)
                        restorer = ksig->ka.sa.sa_restorer;
                put_user_ex(restorer, &frame->pretcode);
index c6eb418..0d0e922 100644 (file)
@@ -343,6 +343,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
        if (poke_int3_handler(regs))
                return;
 
+       prev_state = exception_enter();
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
        if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
                                SIGTRAP) == NOTIFY_STOP)
@@ -351,9 +352,8 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 
 #ifdef CONFIG_KPROBES
        if (kprobe_int3_handler(regs))
-               return;
+               goto exit;
 #endif
-       prev_state = exception_enter();
 
        if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
                        SIGTRAP) == NOTIFY_STOP)
@@ -433,6 +433,8 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
        unsigned long dr6;
        int si_code;
 
+       prev_state = exception_enter();
+
        get_debugreg(dr6, 6);
 
        /* Filter out all the reserved bits which are preset to 1 */
@@ -465,7 +467,6 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
        if (kprobe_debug_handler(regs))
                goto exit;
 #endif
-       prev_state = exception_enter();
 
        if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code,
                                                        SIGTRAP) == NOTIFY_STOP)
index 3c0809a..61b04fe 100644 (file)
@@ -11,7 +11,6 @@ VDSO32-$(CONFIG_COMPAT)               := y
 
 # files to link into the vdso
 vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vdso-fakesections.o
-vobjs-nox32 := vdso-fakesections.o
 
 # files to link into kernel
 obj-y                          += vma.o
@@ -67,7 +66,8 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso2c FORCE
 #
 CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
        $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \
-       -fno-omit-frame-pointer -foptimize-sibling-calls
+       -fno-omit-frame-pointer -foptimize-sibling-calls \
+       -DDISABLE_BRANCH_PROFILING
 
 $(vobjs): KBUILD_CFLAGS += $(CFL)
 
@@ -134,7 +134,7 @@ override obj-dirs = $(dir $(obj)) $(obj)/vdso32/
 
 targets += vdso32/vdso32.lds
 targets += vdso32/note.o vdso32/vclock_gettime.o $(vdso32.so-y:%=vdso32/%.o)
-targets += vdso32/vclock_gettime.o
+targets += vdso32/vclock_gettime.o vdso32/vdso-fakesections.o
 
 $(obj)/vdso32.o: $(vdso32-images:%=$(obj)/%)
 
@@ -150,11 +150,13 @@ KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
 KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
 KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
 KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
+KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
 $(vdso32-images:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
 
 $(vdso32-images:%=$(obj)/%.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
                                 $(obj)/vdso32/vdso32.lds \
                                 $(obj)/vdso32/vclock_gettime.o \
+                                $(obj)/vdso32/vdso-fakesections.o \
                                 $(obj)/vdso32/note.o \
                                 $(obj)/vdso32/%.o
        $(call if_changed,vdso)
@@ -169,14 +171,24 @@ quiet_cmd_vdso = VDSO    $@
                 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
 
 VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \
-       -Wl,-Bsymbolic $(LTO_CFLAGS)
+       $(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS)
 GCOV_PROFILE := n
 
 #
-# Install the unstripped copies of vdso*.so.
+# Install the unstripped copies of vdso*.so.  If our toolchain supports
+# build-id, install .build-id links as well.
 #
 quiet_cmd_vdso_install = INSTALL $(@:install_%=%)
-      cmd_vdso_install = cp $< $(MODLIB)/vdso/$(@:install_%=%)
+define cmd_vdso_install
+       cp $< "$(MODLIB)/vdso/$(@:install_%=%)"; \
+       if readelf -n $< |grep -q 'Build ID'; then \
+         buildid=`readelf -n $< |grep 'Build ID' |sed -e 's/^.*Build ID: \(.*\)$$/\1/'`; \
+         first=`echo $$buildid | cut -b-2`; \
+         last=`echo $$buildid | cut -b3-`; \
+         mkdir -p "$(MODLIB)/vdso/.build-id/$$first"; \
+         ln -sf "../../$(@:install_%=%)" "$(MODLIB)/vdso/.build-id/$$first/$$last.debug"; \
+       fi
+endef
 
 vdso_img_insttargets := $(vdso_img_sodbg:%.dbg=install_%)
 
index b2e4f49..9793322 100644 (file)
@@ -11,9 +11,6 @@
  * Check with readelf after changing.
  */
 
-/* Disable profiling for userspace code: */
-#define DISABLE_BRANCH_PROFILING
-
 #include <uapi/linux/time.h>
 #include <asm/vgtod.h>
 #include <asm/hpet.h>
index cb8a8d7..aa5fbfa 100644 (file)
@@ -2,31 +2,20 @@
  * Copyright 2014 Andy Lutomirski
  * Subject to the GNU Public License, v.2
  *
- * Hack to keep broken Go programs working.
- *
- * The Go runtime had a couple of bugs: it would read the section table to try
- * to figure out how many dynamic symbols there were (it shouldn't have looked
- * at the section table at all) and, if there were no SHT_SYNDYM section table
- * entry, it would use an uninitialized value for the number of symbols.  As a
- * workaround, we supply a minimal section table.  vdso2c will adjust the
- * in-memory image so that "vdso_fake_sections" becomes the section table.
- *
- * The bug was introduced by:
- * https://code.google.com/p/go/source/detail?r=56ea40aac72b (2012-08-31)
- * and is being addressed in the Go runtime in this issue:
- * https://code.google.com/p/go/issues/detail?id=8197
+ * String table for loadable section headers.  See vdso2c.h for why
+ * this exists.
  */
 
-#ifndef __x86_64__
-#error This hack is specific to the 64-bit vDSO
-#endif
-
-#include <linux/elf.h>
-
-extern const __visible struct elf64_shdr vdso_fake_sections[];
-const __visible struct elf64_shdr vdso_fake_sections[] = {
-       {
-               .sh_type = SHT_DYNSYM,
-               .sh_entsize = sizeof(Elf64_Sym),
-       }
-};
+const char fake_shstrtab[] __attribute__((section(".fake_shstrtab"))) =
+       ".hash\0"
+       ".dynsym\0"
+       ".dynstr\0"
+       ".gnu.version\0"
+       ".gnu.version_d\0"
+       ".dynamic\0"
+       ".rodata\0"
+       ".fake_shstrtab\0"  /* Yay, self-referential code. */
+       ".note\0"
+       ".eh_frame_hdr\0"
+       ".eh_frame\0"
+       ".text";
index 2ec72f6..9197544 100644 (file)
@@ -6,6 +6,16 @@
  * This script controls its layout.
  */
 
+#if defined(BUILD_VDSO64)
+# define SHDR_SIZE 64
+#elif defined(BUILD_VDSO32) || defined(BUILD_VDSOX32)
+# define SHDR_SIZE 40
+#else
+# error unknown VDSO target
+#endif
+
+#define NUM_FAKE_SHDRS 13
+
 SECTIONS
 {
        . = SIZEOF_HEADERS;
@@ -18,35 +28,52 @@ SECTIONS
        .gnu.version_d  : { *(.gnu.version_d) }
        .gnu.version_r  : { *(.gnu.version_r) }
 
+       .dynamic        : { *(.dynamic) }               :text   :dynamic
+
+       .rodata         : {
+               *(.rodata*)
+               *(.data*)
+               *(.sdata*)
+               *(.got.plt) *(.got)
+               *(.gnu.linkonce.d.*)
+               *(.bss*)
+               *(.dynbss*)
+               *(.gnu.linkonce.b.*)
+
+               /*
+                * Ideally this would live in a C file, but that won't
+                * work cleanly for x32 until we start building the x32
+                * C code using an x32 toolchain.
+                */
+               VDSO_FAKE_SECTION_TABLE_START = .;
+               . = . + NUM_FAKE_SHDRS * SHDR_SIZE;
+               VDSO_FAKE_SECTION_TABLE_END = .;
+       }                                               :text
+
+       .fake_shstrtab  : { *(.fake_shstrtab) }         :text
+
+
        .note           : { *(.note.*) }                :text   :note
 
        .eh_frame_hdr   : { *(.eh_frame_hdr) }          :text   :eh_frame_hdr
        .eh_frame       : { KEEP (*(.eh_frame)) }       :text
 
-       .dynamic        : { *(.dynamic) }               :text   :dynamic
-
-       .rodata         : { *(.rodata*) }               :text
-       .data           : {
-             *(.data*)
-             *(.sdata*)
-             *(.got.plt) *(.got)
-             *(.gnu.linkonce.d.*)
-             *(.bss*)
-             *(.dynbss*)
-             *(.gnu.linkonce.b.*)
-       }
-
-       .altinstructions        : { *(.altinstructions) }
-       .altinstr_replacement   : { *(.altinstr_replacement) }
 
        /*
-        * Align the actual code well away from the non-instruction data.
-        * This is the best thing for the I-cache.
+        * Text is well-separated from actual data: there's plenty of
+        * stuff that isn't used at runtime in between.
         */
-       . = ALIGN(0x100);
 
        .text           : { *(.text*) }                 :text   =0x90909090,
 
+       /*
+        * At the end so that eu-elflint stays happy when vdso2c strips
+        * these.  A better implementation would avoid allocating space
+        * for these.
+        */
+       .altinstructions        : { *(.altinstructions) }       :text
+       .altinstr_replacement   : { *(.altinstr_replacement) }  :text
+
        /*
         * The remainder of the vDSO consists of special pages that are
         * shared between the kernel and userspace.  It needs to be at the
@@ -75,6 +102,7 @@ SECTIONS
        /DISCARD/ : {
                *(.discard)
                *(.discard.*)
+               *(__bug_table)
        }
 }
 
index 75e3404..6807932 100644 (file)
@@ -6,6 +6,8 @@
  * the DSO.
  */
 
+#define BUILD_VDSO64
+
 #include "vdso-layout.lds.S"
 
 /*
index 7a6bf50..238dbe8 100644 (file)
@@ -23,6 +23,8 @@ enum {
        sym_vvar_page,
        sym_hpet_page,
        sym_end_mapping,
+       sym_VDSO_FAKE_SECTION_TABLE_START,
+       sym_VDSO_FAKE_SECTION_TABLE_END,
 };
 
 const int special_pages[] = {
@@ -30,15 +32,26 @@ const int special_pages[] = {
        sym_hpet_page,
 };
 
-char const * const required_syms[] = {
-       [sym_vvar_page] = "vvar_page",
-       [sym_hpet_page] = "hpet_page",
-       [sym_end_mapping] = "end_mapping",
-       "VDSO32_NOTE_MASK",
-       "VDSO32_SYSENTER_RETURN",
-       "__kernel_vsyscall",
-       "__kernel_sigreturn",
-       "__kernel_rt_sigreturn",
+struct vdso_sym {
+       const char *name;
+       bool export;
+};
+
+struct vdso_sym required_syms[] = {
+       [sym_vvar_page] = {"vvar_page", true},
+       [sym_hpet_page] = {"hpet_page", true},
+       [sym_end_mapping] = {"end_mapping", true},
+       [sym_VDSO_FAKE_SECTION_TABLE_START] = {
+               "VDSO_FAKE_SECTION_TABLE_START", false
+       },
+       [sym_VDSO_FAKE_SECTION_TABLE_END] = {
+               "VDSO_FAKE_SECTION_TABLE_END", false
+       },
+       {"VDSO32_NOTE_MASK", true},
+       {"VDSO32_SYSENTER_RETURN", true},
+       {"__kernel_vsyscall", true},
+       {"__kernel_sigreturn", true},
+       {"__kernel_rt_sigreturn", true},
 };
 
 __attribute__((format(printf, 1, 2))) __attribute__((noreturn))
@@ -83,37 +96,21 @@ extern void bad_put_le(void);
 
 #define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
 
-#define BITS 64
-#define GOFUNC go64
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Phdr Elf64_Phdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Dyn Elf64_Dyn
+#define BITSFUNC3(name, bits) name##bits
+#define BITSFUNC2(name, bits) BITSFUNC3(name, bits)
+#define BITSFUNC(name) BITSFUNC2(name, ELF_BITS)
+
+#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x
+#define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x)
+#define ELF(x) ELF_BITS_XFORM(ELF_BITS, x)
+
+#define ELF_BITS 64
 #include "vdso2c.h"
-#undef BITS
-#undef GOFUNC
-#undef Elf_Ehdr
-#undef Elf_Shdr
-#undef Elf_Phdr
-#undef Elf_Sym
-#undef Elf_Dyn
-
-#define BITS 32
-#define GOFUNC go32
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Phdr Elf32_Phdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Dyn Elf32_Dyn
+#undef ELF_BITS
+
+#define ELF_BITS 32
 #include "vdso2c.h"
-#undef BITS
-#undef GOFUNC
-#undef Elf_Ehdr
-#undef Elf_Shdr
-#undef Elf_Phdr
-#undef Elf_Sym
-#undef Elf_Dyn
+#undef ELF_BITS
 
 static void go(void *addr, size_t len, FILE *outfile, const char *name)
 {
index c6eefaf..df95a2f 100644 (file)
  * are built for 32-bit userspace.
  */
 
-static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
+/*
+ * We're writing a section table for a few reasons:
+ *
+ * The Go runtime had a couple of bugs: it would read the section
+ * table to try to figure out how many dynamic symbols there were (it
+ * shouldn't have looked at the section table at all) and, if there
+ * were no SHT_SYNDYM section table entry, it would use an
+ * uninitialized value for the number of symbols.  An empty DYNSYM
+ * table would work, but I see no reason not to write a valid one (and
+ * keep full performance for old Go programs).  This hack is only
+ * needed on x86_64.
+ *
+ * The bug was introduced on 2012-08-31 by:
+ * https://code.google.com/p/go/source/detail?r=56ea40aac72b
+ * and was fixed on 2014-06-13 by:
+ * https://code.google.com/p/go/source/detail?r=fc1cd5e12595
+ *
+ * Binutils has issues debugging the vDSO: it reads the section table to
+ * find SHT_NOTE; it won't look at PT_NOTE for the in-memory vDSO, which
+ * would break build-id if we removed the section table.  Binutils
+ * also requires that shstrndx != 0.  See:
+ * https://sourceware.org/bugzilla/show_bug.cgi?id=17064
+ *
+ * elfutils might not look for PT_NOTE if there is a section table at
+ * all.  I don't know whether this matters for any practical purpose.
+ *
+ * For simplicity, rather than hacking up a partial section table, we
+ * just write a mostly complete one.  We omit non-dynamic symbols,
+ * though, since they're rather large.
+ *
+ * Once binutils gets fixed, we might be able to drop this for all but
+ * the 64-bit vdso, since build-id only works in kernel RPMs, and
+ * systems that update to new enough kernel RPMs will likely update
+ * binutils in sync.  build-id has never worked for home-built kernel
+ * RPMs without manual symlinking, and I suspect that no one ever does
+ * that.
+ */
+struct BITSFUNC(fake_sections)
+{
+       ELF(Shdr) *table;
+       unsigned long table_offset;
+       int count, max_count;
+
+       int in_shstrndx;
+       unsigned long shstr_offset;
+       const char *shstrtab;
+       size_t shstrtab_len;
+
+       int out_shstrndx;
+};
+
+static unsigned int BITSFUNC(find_shname)(struct BITSFUNC(fake_sections) *out,
+                                         const char *name)
+{
+       const char *outname = out->shstrtab;
+       while (outname - out->shstrtab < out->shstrtab_len) {
+               if (!strcmp(name, outname))
+                       return (outname - out->shstrtab) + out->shstr_offset;
+               outname += strlen(outname) + 1;
+       }
+
+       if (*name)
+               printf("Warning: could not find output name \"%s\"\n", name);
+       return out->shstr_offset + out->shstrtab_len - 1;  /* Use a null. */
+}
+
+static void BITSFUNC(init_sections)(struct BITSFUNC(fake_sections) *out)
+{
+       if (!out->in_shstrndx)
+               fail("didn't find the fake shstrndx\n");
+
+       memset(out->table, 0, out->max_count * sizeof(ELF(Shdr)));
+
+       if (out->max_count < 1)
+               fail("we need at least two fake output sections\n");
+
+       PUT_LE(&out->table[0].sh_type, SHT_NULL);
+       PUT_LE(&out->table[0].sh_name, BITSFUNC(find_shname)(out, ""));
+
+       out->count = 1;
+}
+
+static void BITSFUNC(copy_section)(struct BITSFUNC(fake_sections) *out,
+                                  int in_idx, const ELF(Shdr) *in,
+                                  const char *name)
+{
+       uint64_t flags = GET_LE(&in->sh_flags);
+
+       bool copy = flags & SHF_ALLOC &&
+               strcmp(name, ".altinstructions") &&
+               strcmp(name, ".altinstr_replacement");
+
+       if (!copy)
+               return;
+
+       if (out->count >= out->max_count)
+               fail("too many copied sections (max = %d)\n", out->max_count);
+
+       if (in_idx == out->in_shstrndx)
+               out->out_shstrndx = out->count;
+
+       out->table[out->count] = *in;
+       PUT_LE(&out->table[out->count].sh_name,
+              BITSFUNC(find_shname)(out, name));
+
+       /* elfutils requires that a strtab have the correct type. */
+       if (!strcmp(name, ".fake_shstrtab"))
+               PUT_LE(&out->table[out->count].sh_type, SHT_STRTAB);
+
+       out->count++;
+}
+
+static void BITSFUNC(go)(void *addr, size_t len,
+                        FILE *outfile, const char *name)
 {
        int found_load = 0;
        unsigned long load_size = -1;  /* Work around bogus warning */
        unsigned long data_size;
-       Elf_Ehdr *hdr = (Elf_Ehdr *)addr;
+       ELF(Ehdr) *hdr = (ELF(Ehdr) *)addr;
        int i;
        unsigned long j;
-       Elf_Shdr *symtab_hdr = NULL, *strtab_hdr, *secstrings_hdr,
+       ELF(Shdr) *symtab_hdr = NULL, *strtab_hdr, *secstrings_hdr,
                *alt_sec = NULL;
-       Elf_Dyn *dyn = 0, *dyn_end = 0;
+       ELF(Dyn) *dyn = 0, *dyn_end = 0;
        const char *secstrings;
        uint64_t syms[NSYMS] = {};
 
-       uint64_t fake_sections_value = 0, fake_sections_size = 0;
+       struct BITSFUNC(fake_sections) fake_sections = {};
 
-       Elf_Phdr *pt = (Elf_Phdr *)(addr + GET_LE(&hdr->e_phoff));
+       ELF(Phdr) *pt = (ELF(Phdr) *)(addr + GET_LE(&hdr->e_phoff));
 
        /* Walk the segment table. */
        for (i = 0; i < GET_LE(&hdr->e_phnum); i++) {
@@ -51,7 +164,7 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
        for (i = 0; dyn + i < dyn_end &&
                     GET_LE(&dyn[i].d_tag) != DT_NULL; i++) {
                typeof(dyn[i].d_tag) tag = GET_LE(&dyn[i].d_tag);
-               if (tag == DT_REL || tag == DT_RELSZ ||
+               if (tag == DT_REL || tag == DT_RELSZ || tag == DT_RELA ||
                    tag == DT_RELENT || tag == DT_TEXTREL)
                        fail("vdso image contains dynamic relocations\n");
        }
@@ -61,7 +174,7 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
                GET_LE(&hdr->e_shentsize)*GET_LE(&hdr->e_shstrndx);
        secstrings = addr + GET_LE(&secstrings_hdr->sh_offset);
        for (i = 0; i < GET_LE(&hdr->e_shnum); i++) {
-               Elf_Shdr *sh = addr + GET_LE(&hdr->e_shoff) +
+               ELF(Shdr) *sh = addr + GET_LE(&hdr->e_shoff) +
                        GET_LE(&hdr->e_shentsize) * i;
                if (GET_LE(&sh->sh_type) == SHT_SYMTAB)
                        symtab_hdr = sh;
@@ -82,29 +195,63 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
             i < GET_LE(&symtab_hdr->sh_size) / GET_LE(&symtab_hdr->sh_entsize);
             i++) {
                int k;
-               Elf_Sym *sym = addr + GET_LE(&symtab_hdr->sh_offset) +
+               ELF(Sym) *sym = addr + GET_LE(&symtab_hdr->sh_offset) +
                        GET_LE(&symtab_hdr->sh_entsize) * i;
                const char *name = addr + GET_LE(&strtab_hdr->sh_offset) +
                        GET_LE(&sym->st_name);
 
                for (k = 0; k < NSYMS; k++) {
-                       if (!strcmp(name, required_syms[k])) {
+                       if (!strcmp(name, required_syms[k].name)) {
                                if (syms[k]) {
                                        fail("duplicate symbol %s\n",
-                                            required_syms[k]);
+                                            required_syms[k].name);
                                }
                                syms[k] = GET_LE(&sym->st_value);
                        }
                }
 
-               if (!strcmp(name, "vdso_fake_sections")) {
-                       if (fake_sections_value)
-                               fail("duplicate vdso_fake_sections\n");
-                       fake_sections_value = GET_LE(&sym->st_value);
-                       fake_sections_size = GET_LE(&sym->st_size);
+               if (!strcmp(name, "fake_shstrtab")) {
+                       ELF(Shdr) *sh;
+
+                       fake_sections.in_shstrndx = GET_LE(&sym->st_shndx);
+                       fake_sections.shstrtab = addr + GET_LE(&sym->st_value);
+                       fake_sections.shstrtab_len = GET_LE(&sym->st_size);
+                       sh = addr + GET_LE(&hdr->e_shoff) +
+                               GET_LE(&hdr->e_shentsize) *
+                               fake_sections.in_shstrndx;
+                       fake_sections.shstr_offset = GET_LE(&sym->st_value) -
+                               GET_LE(&sh->sh_addr);
                }
        }
 
+       /* Build the output section table. */
+       if (!syms[sym_VDSO_FAKE_SECTION_TABLE_START] ||
+           !syms[sym_VDSO_FAKE_SECTION_TABLE_END])
+               fail("couldn't find fake section table\n");
+       if ((syms[sym_VDSO_FAKE_SECTION_TABLE_END] -
+            syms[sym_VDSO_FAKE_SECTION_TABLE_START]) % sizeof(ELF(Shdr)))
+               fail("fake section table size isn't a multiple of sizeof(Shdr)\n");
+       fake_sections.table = addr + syms[sym_VDSO_FAKE_SECTION_TABLE_START];
+       fake_sections.table_offset = syms[sym_VDSO_FAKE_SECTION_TABLE_START];
+       fake_sections.max_count = (syms[sym_VDSO_FAKE_SECTION_TABLE_END] -
+                                  syms[sym_VDSO_FAKE_SECTION_TABLE_START]) /
+               sizeof(ELF(Shdr));
+
+       BITSFUNC(init_sections)(&fake_sections);
+       for (i = 0; i < GET_LE(&hdr->e_shnum); i++) {
+               ELF(Shdr) *sh = addr + GET_LE(&hdr->e_shoff) +
+                       GET_LE(&hdr->e_shentsize) * i;
+               BITSFUNC(copy_section)(&fake_sections, i, sh,
+                                      secstrings + GET_LE(&sh->sh_name));
+       }
+       if (!fake_sections.out_shstrndx)
+               fail("didn't generate shstrndx?!?\n");
+
+       PUT_LE(&hdr->e_shoff, fake_sections.table_offset);
+       PUT_LE(&hdr->e_shentsize, sizeof(ELF(Shdr)));
+       PUT_LE(&hdr->e_shnum, fake_sections.count);
+       PUT_LE(&hdr->e_shstrndx, fake_sections.out_shstrndx);
+
        /* Validate mapping addresses. */
        for (i = 0; i < sizeof(special_pages) / sizeof(special_pages[0]); i++) {
                if (!syms[i])
@@ -112,25 +259,17 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
 
                if (syms[i] % 4096)
                        fail("%s must be a multiple of 4096\n",
-                            required_syms[i]);
+                            required_syms[i].name);
                if (syms[i] < data_size)
                        fail("%s must be after the text mapping\n",
-                            required_syms[i]);
+                            required_syms[i].name);
                if (syms[sym_end_mapping] < syms[i] + 4096)
-                       fail("%s overruns end_mapping\n", required_syms[i]);
+                       fail("%s overruns end_mapping\n",
+                            required_syms[i].name);
        }
        if (syms[sym_end_mapping] % 4096)
                fail("end_mapping must be a multiple of 4096\n");
 
-       /* Remove sections or use fakes */
-       if (fake_sections_size % sizeof(Elf_Shdr))
-               fail("vdso_fake_sections size is not a multiple of %ld\n",
-                    (long)sizeof(Elf_Shdr));
-       PUT_LE(&hdr->e_shoff, fake_sections_value);
-       PUT_LE(&hdr->e_shentsize, fake_sections_value ? sizeof(Elf_Shdr) : 0);
-       PUT_LE(&hdr->e_shnum, fake_sections_size / sizeof(Elf_Shdr));
-       PUT_LE(&hdr->e_shstrndx, SHN_UNDEF);
-
        if (!name) {
                fwrite(addr, load_size, 1, outfile);
                return;
@@ -168,9 +307,9 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
                        (unsigned long)GET_LE(&alt_sec->sh_size));
        }
        for (i = 0; i < NSYMS; i++) {
-               if (syms[i])
+               if (required_syms[i].export && syms[i])
                        fprintf(outfile, "\t.sym_%s = 0x%" PRIx64 ",\n",
-                               required_syms[i], syms[i]);
+                               required_syms[i].name, syms[i]);
        }
        fprintf(outfile, "};\n");
 }
diff --git a/arch/x86/vdso/vdso32/vdso-fakesections.c b/arch/x86/vdso/vdso32/vdso-fakesections.c
new file mode 100644 (file)
index 0000000..541468e
--- /dev/null
@@ -0,0 +1 @@
+#include "../vdso-fakesections.c"
index 46b991b..697c11e 100644 (file)
@@ -6,6 +6,8 @@
  * the DSO.
  */
 
+#define BUILD_VDSOX32
+
 #include "vdso-layout.lds.S"
 
 /*
index f17b292..ffb101e 100644 (file)
@@ -1537,7 +1537,10 @@ asmlinkage __visible void __init xen_start_kernel(void)
        if (!xen_pvh_domain())
                pv_cpu_ops = xen_cpu_ops;
 
-       x86_init.resources.memory_setup = xen_memory_setup;
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               x86_init.resources.memory_setup = xen_auto_xlated_memory_setup;
+       else
+               x86_init.resources.memory_setup = xen_memory_setup;
        x86_init.oem.arch_setup = xen_arch_setup;
        x86_init.oem.banner = xen_banner;
 
index 821a11a..2e55516 100644 (file)
@@ -27,7 +27,6 @@
 #include <xen/interface/memory.h>
 #include <xen/interface/physdev.h>
 #include <xen/features.h>
-#include "mmu.h"
 #include "xen-ops.h"
 #include "vdso.h"
 
@@ -82,9 +81,6 @@ static void __init xen_add_extra_mem(u64 start, u64 size)
 
        memblock_reserve(start, size);
 
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return;
-
        xen_max_p2m_pfn = PFN_DOWN(start + size);
        for (pfn = PFN_DOWN(start); pfn < xen_max_p2m_pfn; pfn++) {
                unsigned long mfn = pfn_to_mfn(pfn);
@@ -107,7 +103,6 @@ static unsigned long __init xen_do_chunk(unsigned long start,
                .domid        = DOMID_SELF
        };
        unsigned long len = 0;
-       int xlated_phys = xen_feature(XENFEAT_auto_translated_physmap);
        unsigned long pfn;
        int ret;
 
@@ -121,7 +116,7 @@ static unsigned long __init xen_do_chunk(unsigned long start,
                                continue;
                        frame = mfn;
                } else {
-                       if (!xlated_phys && mfn != INVALID_P2M_ENTRY)
+                       if (mfn != INVALID_P2M_ENTRY)
                                continue;
                        frame = pfn;
                }
@@ -159,13 +154,6 @@ static unsigned long __init xen_do_chunk(unsigned long start,
 static unsigned long __init xen_release_chunk(unsigned long start,
                                              unsigned long end)
 {
-       /*
-        * Xen already ballooned out the E820 non RAM regions for us
-        * and set them up properly in EPT.
-        */
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return end - start;
-
        return xen_do_chunk(start, end, true);
 }
 
@@ -234,13 +222,7 @@ static void __init xen_set_identity_and_release_chunk(
         * (except for the ISA region which must be 1:1 mapped) to
         * release the refcounts (in Xen) on the original frames.
         */
-
-       /*
-        * PVH E820 matches the hypervisor's P2M which means we need to
-        * account for the proper values of *release and *identity.
-        */
-       for (pfn = start_pfn; !xen_feature(XENFEAT_auto_translated_physmap) &&
-            pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) {
+       for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) {
                pte_t pte = __pte_ma(0);
 
                if (pfn < PFN_UP(ISA_END_ADDRESS))
@@ -517,6 +499,35 @@ char * __init xen_memory_setup(void)
        return "Xen";
 }
 
+/*
+ * Machine specific memory setup for auto-translated guests.
+ */
+char * __init xen_auto_xlated_memory_setup(void)
+{
+       static struct e820entry map[E820MAX] __initdata;
+
+       struct xen_memory_map memmap;
+       int i;
+       int rc;
+
+       memmap.nr_entries = E820MAX;
+       set_xen_guest_handle(memmap.buffer, map);
+
+       rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
+       if (rc < 0)
+               panic("No memory map (%d)\n", rc);
+
+       sanitize_e820_map(map, ARRAY_SIZE(map), &memmap.nr_entries);
+
+       for (i = 0; i < memmap.nr_entries; i++)
+               e820_add_region(map[i].addr, map[i].size, map[i].type);
+
+       memblock_reserve(__pa(xen_start_info->mfn_list),
+                        xen_start_info->pt_base - xen_start_info->mfn_list);
+
+       return "Xen";
+}
+
 /*
  * Set the bit indicating "nosegneg" library variants should be used.
  * We only need to bother in pure 32-bit mode; compat 32-bit processes
@@ -590,13 +601,7 @@ void xen_enable_syscall(void)
        }
 #endif /* CONFIG_X86_64 */
 }
-void xen_enable_nmi(void)
-{
-#ifdef CONFIG_X86_64
-       if (register_callback(CALLBACKTYPE_nmi, (char *)nmi))
-               BUG();
-#endif
-}
+
 void __init xen_pvmmu_arch_setup(void)
 {
        HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
@@ -611,7 +616,6 @@ void __init xen_pvmmu_arch_setup(void)
 
        xen_enable_sysenter();
        xen_enable_syscall();
-       xen_enable_nmi();
 }
 
 /* This function is not called for HVM domains */
index c834d4b..97d8765 100644 (file)
@@ -36,6 +36,7 @@ void xen_mm_unpin_all(void);
 void xen_set_pat(u64);
 
 char * __init xen_memory_setup(void);
+char * xen_auto_xlated_memory_setup(void);
 void __init xen_arch_setup(void);
 void xen_enable_sysenter(void);
 void xen_enable_syscall(void);
index 8c2e55e..0ec61c9 100644 (file)
@@ -746,6 +746,14 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
 
                        goto done;
                }
+
+               /*
+                * If the queue doesn't support SG gaps and adding this
+                * offset would create a gap, disallow it.
+                */
+               if (q->queue_flags & (1 << QUEUE_FLAG_SG_GAPS) &&
+                   bvec_gap_to_prev(prev, offset))
+                       return 0;
        }
 
        if (bio->bi_vcnt >= bio->bi_max_vecs)
index 069bc20..b9f4cc4 100644 (file)
@@ -80,7 +80,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
        blkg->q = q;
        INIT_LIST_HEAD(&blkg->q_node);
        blkg->blkcg = blkcg;
-       blkg->refcnt = 1;
+       atomic_set(&blkg->refcnt, 1);
 
        /* root blkg uses @q->root_rl, init rl only for !root blkgs */
        if (blkcg != &blkcg_root) {
@@ -399,11 +399,8 @@ void __blkg_release_rcu(struct rcu_head *rcu_head)
 
        /* release the blkcg and parent blkg refs this blkg has been holding */
        css_put(&blkg->blkcg->css);
-       if (blkg->parent) {
-               spin_lock_irq(blkg->q->queue_lock);
+       if (blkg->parent)
                blkg_put(blkg->parent);
-               spin_unlock_irq(blkg->q->queue_lock);
-       }
 
        blkg_free(blkg);
 }
@@ -1093,7 +1090,7 @@ EXPORT_SYMBOL_GPL(blkcg_deactivate_policy);
  * Register @pol with blkcg core.  Might sleep and @pol may be modified on
  * successful registration.  Returns 0 on success and -errno on failure.
  */
-int __init blkcg_policy_register(struct blkcg_policy *pol)
+int blkcg_policy_register(struct blkcg_policy *pol)
 {
        int i, ret;
 
index cbb7f94..d3fd7aa 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/seq_file.h>
 #include <linux/radix-tree.h>
 #include <linux/blkdev.h>
+#include <linux/atomic.h>
 
 /* Max limits for throttle policy */
 #define THROTL_IOPS_MAX                UINT_MAX
@@ -104,7 +105,7 @@ struct blkcg_gq {
        struct request_list             rl;
 
        /* reference count */
-       int                             refcnt;
+       atomic_t                        refcnt;
 
        /* is this blkg online? protected by both blkcg and q locks */
        bool                            online;
@@ -145,7 +146,7 @@ void blkcg_drain_queue(struct request_queue *q);
 void blkcg_exit_queue(struct request_queue *q);
 
 /* Blkio controller policy registration */
-int __init blkcg_policy_register(struct blkcg_policy *pol);
+int blkcg_policy_register(struct blkcg_policy *pol);
 void blkcg_policy_unregister(struct blkcg_policy *pol);
 int blkcg_activate_policy(struct request_queue *q,
                          const struct blkcg_policy *pol);
@@ -257,13 +258,12 @@ static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen)
  * blkg_get - get a blkg reference
  * @blkg: blkg to get
  *
- * The caller should be holding queue_lock and an existing reference.
+ * The caller should be holding an existing reference.
  */
 static inline void blkg_get(struct blkcg_gq *blkg)
 {
-       lockdep_assert_held(blkg->q->queue_lock);
-       WARN_ON_ONCE(!blkg->refcnt);
-       blkg->refcnt++;
+       WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
+       atomic_inc(&blkg->refcnt);
 }
 
 void __blkg_release_rcu(struct rcu_head *rcu);
@@ -271,14 +271,11 @@ void __blkg_release_rcu(struct rcu_head *rcu);
 /**
  * blkg_put - put a blkg reference
  * @blkg: blkg to put
- *
- * The caller should be holding queue_lock.
  */
 static inline void blkg_put(struct blkcg_gq *blkg)
 {
-       lockdep_assert_held(blkg->q->queue_lock);
-       WARN_ON_ONCE(blkg->refcnt <= 0);
-       if (!--blkg->refcnt)
+       WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
+       if (atomic_dec_and_test(&blkg->refcnt))
                call_rcu(&blkg->rcu_head, __blkg_release_rcu);
 }
 
@@ -580,7 +577,7 @@ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { ret
 static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
 static inline void blkcg_drain_queue(struct request_queue *q) { }
 static inline void blkcg_exit_queue(struct request_queue *q) { }
-static inline int __init blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
+static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
 static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
 static inline int blkcg_activate_policy(struct request_queue *q,
                                        const struct blkcg_policy *pol) { return 0; }
index f6f6b9a..6f8dba1 100644 (file)
@@ -3312,8 +3312,7 @@ int __init blk_dev_init(void)
 
        /* used for unplugging and affects IO latency/throughput - HIGHPRI */
        kblockd_workqueue = alloc_workqueue("kblockd",
-                                           WQ_MEM_RECLAIM | WQ_HIGHPRI |
-                                           WQ_POWER_EFFICIENT, 0);
+                                           WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
        if (!kblockd_workqueue)
                panic("Failed to create kblockd\n");
 
index 8ffee4b..3cb5e9e 100644 (file)
@@ -421,44 +421,6 @@ void blk_insert_flush(struct request *rq)
        blk_flush_complete_seq(rq, REQ_FSEQ_ACTIONS & ~policy, 0);
 }
 
-/**
- * blk_abort_flushes - @q is being aborted, abort flush requests
- * @q: request_queue being aborted
- *
- * To be called from elv_abort_queue().  @q is being aborted.  Prepare all
- * FLUSH/FUA requests for abortion.
- *
- * CONTEXT:
- * spin_lock_irq(q->queue_lock)
- */
-void blk_abort_flushes(struct request_queue *q)
-{
-       struct request *rq, *n;
-       int i;
-
-       /*
-        * Requests in flight for data are already owned by the dispatch
-        * queue or the device driver.  Just restore for normal completion.
-        */
-       list_for_each_entry_safe(rq, n, &q->flush_data_in_flight, flush.list) {
-               list_del_init(&rq->flush.list);
-               blk_flush_restore_request(rq);
-       }
-
-       /*
-        * We need to give away requests on flush queues.  Restore for
-        * normal completion and put them on the dispatch queue.
-        */
-       for (i = 0; i < ARRAY_SIZE(q->flush_queue); i++) {
-               list_for_each_entry_safe(rq, n, &q->flush_queue[i],
-                                        flush.list) {
-                       list_del_init(&rq->flush.list);
-                       blk_flush_restore_request(rq);
-                       list_add_tail(&rq->queuelist, &q->queue_head);
-               }
-       }
-}
-
 /**
  * blkdev_issue_flush - queue a flush
  * @bdev:      blockdev to issue flush for
index b3bf0df..5453583 100644 (file)
@@ -568,6 +568,8 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
 
 bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 {
+       struct request_queue *q = rq->q;
+
        if (!rq_mergeable(rq) || !bio_mergeable(bio))
                return false;
 
@@ -591,6 +593,14 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
            !blk_write_same_mergeable(rq->bio, bio))
                return false;
 
+       if (q->queue_flags & (1 << QUEUE_FLAG_SG_GAPS)) {
+               struct bio_vec *bprev;
+
+               bprev = &rq->biotail->bi_io_vec[bio->bi_vcnt - 1];
+               if (bvec_gap_to_prev(bprev, bio->bi_io_vec[0].bv_offset))
+                       return false;
+       }
+
        return true;
 }
 
index 1aab39f..c1b9242 100644 (file)
@@ -43,9 +43,16 @@ bool blk_mq_has_free_tags(struct blk_mq_tags *tags)
        return bt_has_free_tags(&tags->bitmap_tags);
 }
 
-static inline void bt_index_inc(unsigned int *index)
+static inline int bt_index_inc(int index)
 {
-       *index = (*index + 1) & (BT_WAIT_QUEUES - 1);
+       return (index + 1) & (BT_WAIT_QUEUES - 1);
+}
+
+static inline void bt_index_atomic_inc(atomic_t *index)
+{
+       int old = atomic_read(index);
+       int new = bt_index_inc(old);
+       atomic_cmpxchg(index, old, new);
 }
 
 /*
@@ -69,14 +76,14 @@ static void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags)
        int i, wake_index;
 
        bt = &tags->bitmap_tags;
-       wake_index = bt->wake_index;
+       wake_index = atomic_read(&bt->wake_index);
        for (i = 0; i < BT_WAIT_QUEUES; i++) {
                struct bt_wait_state *bs = &bt->bs[wake_index];
 
                if (waitqueue_active(&bs->wait))
                        wake_up(&bs->wait);
 
-               bt_index_inc(&wake_index);
+               wake_index = bt_index_inc(wake_index);
        }
 }
 
@@ -212,12 +219,14 @@ static struct bt_wait_state *bt_wait_ptr(struct blk_mq_bitmap_tags *bt,
                                         struct blk_mq_hw_ctx *hctx)
 {
        struct bt_wait_state *bs;
+       int wait_index;
 
        if (!hctx)
                return &bt->bs[0];
 
-       bs = &bt->bs[hctx->wait_index];
-       bt_index_inc(&hctx->wait_index);
+       wait_index = atomic_read(&hctx->wait_index);
+       bs = &bt->bs[wait_index];
+       bt_index_atomic_inc(&hctx->wait_index);
        return bs;
 }
 
@@ -239,18 +248,12 @@ static int bt_get(struct blk_mq_alloc_data *data,
 
        bs = bt_wait_ptr(bt, hctx);
        do {
-               bool was_empty;
-
-               was_empty = list_empty(&wait.task_list);
                prepare_to_wait(&bs->wait, &wait, TASK_UNINTERRUPTIBLE);
 
                tag = __bt_get(hctx, bt, last_tag);
                if (tag != -1)
                        break;
 
-               if (was_empty)
-                       atomic_set(&bs->wait_cnt, bt->wake_cnt);
-
                blk_mq_put_ctx(data->ctx);
 
                io_schedule();
@@ -313,18 +316,19 @@ static struct bt_wait_state *bt_wake_ptr(struct blk_mq_bitmap_tags *bt)
 {
        int i, wake_index;
 
-       wake_index = bt->wake_index;
+       wake_index = atomic_read(&bt->wake_index);
        for (i = 0; i < BT_WAIT_QUEUES; i++) {
                struct bt_wait_state *bs = &bt->bs[wake_index];
 
                if (waitqueue_active(&bs->wait)) {
-                       if (wake_index != bt->wake_index)
-                               bt->wake_index = wake_index;
+                       int o = atomic_read(&bt->wake_index);
+                       if (wake_index != o)
+                               atomic_cmpxchg(&bt->wake_index, o, wake_index);
 
                        return bs;
                }
 
-               bt_index_inc(&wake_index);
+               wake_index = bt_index_inc(wake_index);
        }
 
        return NULL;
@@ -334,6 +338,7 @@ static void bt_clear_tag(struct blk_mq_bitmap_tags *bt, unsigned int tag)
 {
        const int index = TAG_TO_INDEX(bt, tag);
        struct bt_wait_state *bs;
+       int wait_cnt;
 
        /*
         * The unlock memory barrier need to order access to req in free
@@ -342,10 +347,19 @@ static void bt_clear_tag(struct blk_mq_bitmap_tags *bt, unsigned int tag)
        clear_bit_unlock(TAG_TO_BIT(bt, tag), &bt->map[index].word);
 
        bs = bt_wake_ptr(bt);
-       if (bs && atomic_dec_and_test(&bs->wait_cnt)) {
-               atomic_set(&bs->wait_cnt, bt->wake_cnt);
-               bt_index_inc(&bt->wake_index);
+       if (!bs)
+               return;
+
+       wait_cnt = atomic_dec_return(&bs->wait_cnt);
+       if (wait_cnt == 0) {
+wake:
+               atomic_add(bt->wake_cnt, &bs->wait_cnt);
+               bt_index_atomic_inc(&bt->wake_index);
                wake_up(&bs->wait);
+       } else if (wait_cnt < 0) {
+               wait_cnt = atomic_inc_return(&bs->wait_cnt);
+               if (!wait_cnt)
+                       goto wake;
        }
 }
 
@@ -499,10 +513,13 @@ static int bt_alloc(struct blk_mq_bitmap_tags *bt, unsigned int depth,
                return -ENOMEM;
        }
 
-       for (i = 0; i < BT_WAIT_QUEUES; i++)
+       bt_update_count(bt, depth);
+
+       for (i = 0; i < BT_WAIT_QUEUES; i++) {
                init_waitqueue_head(&bt->bs[i].wait);
+               atomic_set(&bt->bs[i].wait_cnt, bt->wake_cnt);
+       }
 
-       bt_update_count(bt, depth);
        return 0;
 }
 
index 98696a6..6206ed1 100644 (file)
@@ -24,7 +24,7 @@ struct blk_mq_bitmap_tags {
        unsigned int map_nr;
        struct blk_align_bitmap *map;
 
-       unsigned int wake_index;
+       atomic_t wake_index;
        struct bt_wait_state *bs;
 };
 
index e11f5f8..ad69ef6 100644 (file)
@@ -109,7 +109,7 @@ static void blk_mq_queue_exit(struct request_queue *q)
        __percpu_counter_add(&q->mq_usage_counter, -1, 1000000);
 }
 
-static void __blk_mq_drain_queue(struct request_queue *q)
+void blk_mq_drain_queue(struct request_queue *q)
 {
        while (true) {
                s64 count;
@@ -120,7 +120,7 @@ static void __blk_mq_drain_queue(struct request_queue *q)
 
                if (count == 0)
                        break;
-               blk_mq_run_queues(q, false);
+               blk_mq_start_hw_queues(q);
                msleep(10);
        }
 }
@@ -139,12 +139,7 @@ static void blk_mq_freeze_queue(struct request_queue *q)
        spin_unlock_irq(q->queue_lock);
 
        if (drain)
-               __blk_mq_drain_queue(q);
-}
-
-void blk_mq_drain_queue(struct request_queue *q)
-{
-       __blk_mq_drain_queue(q);
+               blk_mq_drain_queue(q);
 }
 
 static void blk_mq_unfreeze_queue(struct request_queue *q)
@@ -883,7 +878,7 @@ void blk_mq_start_hw_queue(struct blk_mq_hw_ctx *hctx)
        clear_bit(BLK_MQ_S_STOPPED, &hctx->state);
 
        preempt_disable();
-       __blk_mq_run_hw_queue(hctx);
+       blk_mq_run_hw_queue(hctx, false);
        preempt_enable();
 }
 EXPORT_SYMBOL(blk_mq_start_hw_queue);
index 45385e9..6748c4f 100644 (file)
@@ -84,7 +84,6 @@ static inline void blk_clear_rq_complete(struct request *rq)
 #define ELV_ON_HASH(rq) ((rq)->cmd_flags & REQ_HASHED)
 
 void blk_insert_flush(struct request *rq);
-void blk_abort_flushes(struct request_queue *q);
 
 static inline struct request *__elv_next_request(struct request_queue *q)
 {
index f35eddd..24c28b6 100644 (file)
@@ -729,26 +729,6 @@ int elv_may_queue(struct request_queue *q, int rw)
        return ELV_MQUEUE_MAY;
 }
 
-void elv_abort_queue(struct request_queue *q)
-{
-       struct request *rq;
-
-       blk_abort_flushes(q);
-
-       while (!list_empty(&q->queue_head)) {
-               rq = list_entry_rq(q->queue_head.next);
-               rq->cmd_flags |= REQ_QUIET;
-               trace_block_rq_abort(q, rq);
-               /*
-                * Mark this request as started so we don't trigger
-                * any debug logic in the end I/O path.
-                */
-               blk_start_request(rq);
-               __blk_end_request_all(rq, -EIO);
-       }
-}
-EXPORT_SYMBOL(elv_abort_queue);
-
 void elv_completed_request(struct request_queue *q, struct request *rq)
 {
        struct elevator_queue *e = q->elevator;
@@ -845,7 +825,7 @@ void elv_unregister_queue(struct request_queue *q)
 }
 EXPORT_SYMBOL(elv_unregister_queue);
 
-int __init elv_register(struct elevator_type *e)
+int elv_register(struct elevator_type *e)
 {
        char *def = "";
 
index 63407d2..9cb65b0 100644 (file)
@@ -34,6 +34,9 @@ ACPI_MODULE_NAME("acpi_lpss");
 
 /* Offsets relative to LPSS_PRIVATE_OFFSET */
 #define LPSS_CLK_DIVIDER_DEF_MASK      (BIT(1) | BIT(16))
+#define LPSS_RESETS                    0x04
+#define LPSS_RESETS_RESET_FUNC         BIT(0)
+#define LPSS_RESETS_RESET_APB          BIT(1)
 #define LPSS_GENERAL                   0x08
 #define LPSS_GENERAL_LTR_MODE_SW       BIT(2)
 #define LPSS_GENERAL_UART_RTS_OVRD     BIT(3)
@@ -99,6 +102,17 @@ static void lpss_uart_setup(struct lpss_private_data *pdata)
        writel(reg | LPSS_GENERAL_UART_RTS_OVRD, pdata->mmio_base + offset);
 }
 
+static void lpss_i2c_setup(struct lpss_private_data *pdata)
+{
+       unsigned int offset;
+       u32 val;
+
+       offset = pdata->dev_desc->prv_offset + LPSS_RESETS;
+       val = readl(pdata->mmio_base + offset);
+       val |= LPSS_RESETS_RESET_APB | LPSS_RESETS_RESET_FUNC;
+       writel(val, pdata->mmio_base + offset);
+}
+
 static struct lpss_device_desc lpt_dev_desc = {
        .clk_required = true,
        .prv_offset = 0x800,
@@ -171,6 +185,7 @@ static struct lpss_device_desc byt_i2c_dev_desc = {
        .prv_offset = 0x800,
        .save_ctx = true,
        .shared_clock = &i2c_clock,
+       .setup = lpss_i2c_setup,
 };
 
 #else
index e48fc98..0d7116f 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/jiffies.h>
 #include <linux/async.h>
 #include <linux/dmi.h>
+#include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
 #include <asm/unaligned.h>
@@ -70,6 +71,7 @@ MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
 static int battery_bix_broken_package;
+static int battery_notification_delay_ms;
 static unsigned int cache_time = 1000;
 module_param(cache_time, uint, 0644);
 MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
@@ -930,7 +932,10 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
                goto end;
        }
        alarm_string[count] = '\0';
-       battery->alarm = simple_strtol(alarm_string, NULL, 0);
+       if (kstrtoint(alarm_string, 0, &battery->alarm)) {
+               result = -EINVAL;
+               goto end;
+       }
        result = acpi_battery_set_alarm(battery);
       end:
        if (!result)
@@ -1062,6 +1067,14 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
        if (!battery)
                return;
        old = battery->bat.dev;
+       /*
+       * On Acer Aspire V5-573G notifications are sometimes triggered too
+       * early. For example, when AC is unplugged and notification is
+       * triggered, battery state is still reported as "Full", and changes to
+       * "Discharging" only after short delay, without any notification.
+       */
+       if (battery_notification_delay_ms > 0)
+               msleep(battery_notification_delay_ms);
        if (event == ACPI_BATTERY_NOTIFY_INFO)
                acpi_battery_refresh(battery);
        acpi_battery_update(battery, false);
@@ -1106,14 +1119,35 @@ static int battery_notify(struct notifier_block *nb,
        return 0;
 }
 
+static int battery_bix_broken_package_quirk(const struct dmi_system_id *d)
+{
+       battery_bix_broken_package = 1;
+       return 0;
+}
+
+static int battery_notification_delay_quirk(const struct dmi_system_id *d)
+{
+       battery_notification_delay_ms = 1000;
+       return 0;
+}
+
 static struct dmi_system_id bat_dmi_table[] = {
        {
+               .callback = battery_bix_broken_package_quirk,
                .ident = "NEC LZ750/LS",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
                },
        },
+       {
+               .callback = battery_notification_delay_quirk,
+               .ident = "Acer Aspire V5-573G",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
+               },
+       },
        {},
 };
 
@@ -1227,8 +1261,7 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
        if (acpi_disabled)
                return;
 
-       if (dmi_check_system(bat_dmi_table))
-               battery_bix_broken_package = 1;
+       dmi_check_system(bat_dmi_table);
        
 #ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_battery_dir = acpi_lock_battery_dir();
index 3f2bdc8..bad25b0 100644 (file)
@@ -235,7 +235,8 @@ void acpi_os_vprintf(const char *fmt, va_list args)
 static unsigned long acpi_rsdp;
 static int __init setup_acpi_rsdp(char *arg)
 {
-       acpi_rsdp = simple_strtoul(arg, NULL, 16);
+       if (kstrtoul(arg, 16, &acpi_rsdp))
+               return -EINVAL;
        return 0;
 }
 early_param("acpi_rsdp", setup_acpi_rsdp);
index 05550ba..6d5a6cd 100644 (file)
@@ -360,7 +360,8 @@ static int __init acpi_parse_apic_instance(char *str)
        if (!str)
                return -EINVAL;
 
-       acpi_apic_instance = simple_strtoul(str, NULL, 0);
+       if (kstrtoint(str, 0, &acpi_apic_instance))
+               return -EINVAL;
 
        pr_notice("Shall use APIC/MADT table %d\n", acpi_apic_instance);
 
index 83969f8..6467c91 100644 (file)
@@ -176,14 +176,24 @@ static int __init cma_activate_area(struct cma *cma)
                base_pfn = pfn;
                for (j = pageblock_nr_pages; j; --j, pfn++) {
                        WARN_ON_ONCE(!pfn_valid(pfn));
+                       /*
+                        * alloc_contig_range requires the pfn range
+                        * specified to be in the same zone. Make this
+                        * simple by forcing the entire CMA resv range
+                        * to be in the same zone.
+                        */
                        if (page_zone(pfn_to_page(pfn)) != zone)
-                               return -EINVAL;
+                               goto err;
                }
                init_cma_reserved_pageblock(pfn_to_page(base_pfn));
        } while (--i);
 
        mutex_init(&cma->lock);
        return 0;
+
+err:
+       kfree(cma->bitmap);
+       return -EINVAL;
 }
 
 static struct cma cma_areas[MAX_CMA_AREAS];
index b6c8aaf..5b17ec8 100644 (file)
@@ -1337,8 +1337,11 @@ int drbd_submit_peer_request(struct drbd_device *device,
                return 0;
        }
 
+       /* Discards don't have any payload.
+        * But the scsi layer still expects a bio_vec it can use internally,
+        * see sd_setup_discard_cmnd() and blk_add_request_payload(). */
        if (peer_req->flags & EE_IS_TRIM)
-               nr_pages = 0; /* discards don't have any payload. */
+               nr_pages = 1;
 
        /* In most cases, we will only need one bio.  But in case the lower
         * level restrictions happen to be different at this offset on this
index 677db04..56d46ff 100644 (file)
@@ -3777,7 +3777,7 @@ static void floppy_rb0_cb(struct bio *bio, int err)
        int drive = cbdata->drive;
 
        if (err) {
-               pr_info("floppy: error %d while reading block 0", err);
+               pr_info("floppy: error %d while reading block 0\n", err);
                set_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
        }
        complete(&cbdata->complete);
index 77087a2..a3b042c 100644 (file)
@@ -79,7 +79,7 @@ MODULE_PARM_DESC(home_node, "Home node for the device");
 
 static int queue_mode = NULL_Q_MQ;
 module_param(queue_mode, int, S_IRUGO);
-MODULE_PARM_DESC(use_mq, "Use blk-mq interface (0=bio,1=rq,2=multiqueue)");
+MODULE_PARM_DESC(queue_mode, "Block interface to use (0=bio,1=rq,2=multiqueue)");
 
 static int gb = 250;
 module_param(gb, int, S_IRUGO);
@@ -227,7 +227,10 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd)
 
 static void null_softirq_done_fn(struct request *rq)
 {
-       end_cmd(blk_mq_rq_to_pdu(rq));
+       if (queue_mode == NULL_Q_MQ)
+               end_cmd(blk_mq_rq_to_pdu(rq));
+       else
+               end_cmd(rq->special);
 }
 
 static inline void null_handle_cmd(struct nullb_cmd *cmd)
index bbeb404..b2c98c1 100644 (file)
@@ -1431,6 +1431,14 @@ static bool obj_request_exists_test(struct rbd_obj_request *obj_request)
        return test_bit(OBJ_REQ_EXISTS, &obj_request->flags) != 0;
 }
 
+static bool obj_request_overlaps_parent(struct rbd_obj_request *obj_request)
+{
+       struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
+
+       return obj_request->img_offset <
+           round_up(rbd_dev->parent_overlap, rbd_obj_bytes(&rbd_dev->header));
+}
+
 static void rbd_obj_request_get(struct rbd_obj_request *obj_request)
 {
        dout("%s: obj %p (was %d)\n", __func__, obj_request,
@@ -2748,7 +2756,7 @@ static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request)
         */
        if (!img_request_write_test(img_request) ||
                !img_request_layered_test(img_request) ||
-               rbd_dev->parent_overlap <= obj_request->img_offset ||
+               !obj_request_overlaps_parent(obj_request) ||
                ((known = obj_request_known_test(obj_request)) &&
                        obj_request_exists_test(obj_request))) {
 
index a118ec1..1f37d98 100644 (file)
@@ -45,7 +45,7 @@ config OMAP_INTERCONNECT
 
 config ARM_CCI
        bool "ARM CCI driver support"
-       depends on ARM
+       depends on ARM && OF && CPU_V7
        help
          Driver supporting the CCI cache coherent interconnect for ARM
          platforms.
index 4ad71ef..0a7ac0a 100644 (file)
@@ -980,7 +980,6 @@ static void push_to_pool(struct work_struct *work)
 static size_t account(struct entropy_store *r, size_t nbytes, int min,
                      int reserved)
 {
-       int have_bytes;
        int entropy_count, orig;
        size_t ibytes;
 
@@ -989,17 +988,19 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
        /* Can we pull enough? */
 retry:
        entropy_count = orig = ACCESS_ONCE(r->entropy_count);
-       have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
        ibytes = nbytes;
        /* If limited, never pull more than available */
-       if (r->limit)
-               ibytes = min_t(size_t, ibytes, have_bytes - reserved);
+       if (r->limit) {
+               int have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
+
+               if ((have_bytes -= reserved) < 0)
+                       have_bytes = 0;
+               ibytes = min_t(size_t, ibytes, have_bytes);
+       }
        if (ibytes < min)
                ibytes = 0;
-       if (have_bytes >= ibytes + reserved)
-               entropy_count -= ibytes << (ENTROPY_SHIFT + 3);
-       else
-               entropy_count = reserved << (ENTROPY_SHIFT + 3);
+       if ((entropy_count -= ibytes << (ENTROPY_SHIFT + 3)) < 0)
+               entropy_count = 0;
 
        if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
                goto retry;
index 8d64200..f71d55f 100644 (file)
@@ -153,13 +153,10 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset)
 }
 
 /* Clocksource handling */
-static void exynos4_mct_frc_start(u32 hi, u32 lo)
+static void exynos4_mct_frc_start(void)
 {
        u32 reg;
 
-       exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
-       exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
-
        reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
        reg |= MCT_G_TCON_START;
        exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
@@ -181,7 +178,7 @@ static cycle_t exynos4_frc_read(struct clocksource *cs)
 
 static void exynos4_frc_resume(struct clocksource *cs)
 {
-       exynos4_mct_frc_start(0, 0);
+       exynos4_mct_frc_start();
 }
 
 struct clocksource mct_frc = {
@@ -200,7 +197,7 @@ static u64 notrace exynos4_read_sched_clock(void)
 
 static void __init exynos4_clocksource_init(void)
 {
-       exynos4_mct_frc_start(0, 0);
+       exynos4_mct_frc_start();
 
        if (clocksource_register_hz(&mct_frc, clk_rate))
                panic("%s: can't register clocksource\n", mct_frc.name);
index e473d65..ffe350f 100644 (file)
@@ -186,6 +186,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
 config GENERIC_CPUFREQ_CPU0
        tristate "Generic CPU0 cpufreq driver"
        depends on HAVE_CLK && OF
+       # if CPU_THERMAL is on and THERMAL=m, CPU0 cannot be =y:
+       depends on !CPU_THERMAL || THERMAL
        select PM_OPP
        help
          This adds a generic cpufreq driver for CPU0 frequency management.
index aed2b0c..62259d2 100644 (file)
@@ -2242,10 +2242,8 @@ int cpufreq_update_policy(unsigned int cpu)
        struct cpufreq_policy new_policy;
        int ret;
 
-       if (!policy) {
-               ret = -ENODEV;
-               goto no_policy;
-       }
+       if (!policy)
+               return -ENODEV;
 
        down_write(&policy->rwsem);
 
@@ -2264,7 +2262,7 @@ int cpufreq_update_policy(unsigned int cpu)
                new_policy.cur = cpufreq_driver->get(cpu);
                if (WARN_ON(!new_policy.cur)) {
                        ret = -EIO;
-                       goto no_policy;
+                       goto unlock;
                }
 
                if (!policy->cur) {
@@ -2279,10 +2277,10 @@ int cpufreq_update_policy(unsigned int cpu)
 
        ret = cpufreq_set_policy(policy, &new_policy);
 
+unlock:
        up_write(&policy->rwsem);
 
        cpufreq_cpu_put(policy);
-no_policy:
        return ret;
 }
 EXPORT_SYMBOL(cpufreq_update_policy);
index 4e7f492..924bb2d 100644 (file)
@@ -196,10 +196,7 @@ static signed int pid_calc(struct _pid *pid, int32_t busy)
        pid->last_err = fp_error;
 
        result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm;
-       if (result >= 0)
-               result = result + (1 << (FRAC_BITS-1));
-       else
-               result = result - (1 << (FRAC_BITS-1));
+       result = result + (1 << (FRAC_BITS-1));
        return (signed int)fp_toint(result);
 }
 
index 28587d0..a5fba02 100644 (file)
@@ -55,7 +55,7 @@ static struct cpuidle_driver armada_370_xp_idle_driver = {
                .power_usage            = 50,
                .target_residency       = 100,
                .flags                  = CPUIDLE_FLAG_TIME_VALID,
-               .name                   = "MV CPU IDLE",
+               .name                   = "Idle",
                .desc                   = "CPU power down",
        },
        .states[2]              = {
@@ -65,7 +65,7 @@ static struct cpuidle_driver armada_370_xp_idle_driver = {
                .target_residency       = 1000,
                .flags                  = CPUIDLE_FLAG_TIME_VALID |
                                                ARMADA_370_XP_FLAG_DEEP_IDLE,
-               .name                   = "MV CPU DEEP IDLE",
+               .name                   = "Deep idle",
                .desc                   = "CPU and L2 Fabric power down",
        },
        .state_count = ARMADA_370_XP_MAX_STATES,
index 4b9dc83..e992abc 100644 (file)
@@ -40,7 +40,7 @@ struct pstore_read_data {
 static inline u64 generic_id(unsigned long timestamp,
                             unsigned int part, int count)
 {
-       return (timestamp * 100 + part) * 1000 + count;
+       return ((u64) timestamp * 100 + part) * 1000 + count;
 }
 
 static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
index cd36deb..eff1a2f 100644 (file)
@@ -353,10 +353,10 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
                                       int depth, void *data)
 {
        struct param_info *info = data;
-       void *prop, *dest;
-       unsigned long len;
+       const void *prop;
+       void *dest;
        u64 val;
-       int i;
+       int i, len;
 
        if (depth != 1 ||
            (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
index 5c6a8e8..82d7741 100644 (file)
@@ -63,7 +63,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
         */
        prev = 0;
        for (;;) {
-               const char *type, *name;
+               const char *type;
                int len;
 
                node = fdt_next_node(fdt, prev, NULL);
old mode 100644 (file)
new mode 100755 (executable)
index 03711d0..8218078
@@ -419,8 +419,9 @@ long drm_ioctl(struct file *filp,
                        retcode = -EFAULT;
                        goto err_i1;
                }
-       } else
+       } else if (cmd & IOC_OUT) {
                memset(kdata, 0, usize);
+       }
 
        if (ioctl->flags & DRM_UNLOCKED)
                retcode = func(dev, kdata, file_priv);
index 7c2497d..0dc57d5 100644 (file)
@@ -64,6 +64,7 @@
 void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx,
                uint32_t flags)
 {
+       memset(ctx, 0, sizeof(*ctx));
        ww_acquire_init(&ctx->ww_ctx, &crtc_ww_class);
        INIT_LIST_HEAD(&ctx->locked);
 }
index 482127f..9e530f2 100644 (file)
@@ -40,7 +40,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool force)
 {
        struct exynos_dpi *ctx = connector_to_dpi(connector);
 
-       if (!ctx->panel->connector)
+       if (ctx->panel && !ctx->panel->connector)
                drm_panel_attach(ctx->panel, &ctx->connector);
 
        return connector_status_connected;
index d91f277..ab7d182 100644 (file)
@@ -765,24 +765,24 @@ static int exynos_drm_init(void)
 
        return 0;
 
-err_unregister_pd:
-       platform_device_unregister(exynos_drm_pdev);
-
 err_remove_vidi:
 #ifdef CONFIG_DRM_EXYNOS_VIDI
        exynos_drm_remove_vidi();
+
+err_unregister_pd:
 #endif
+       platform_device_unregister(exynos_drm_pdev);
 
        return ret;
 }
 
 static void exynos_drm_exit(void)
 {
+       platform_driver_unregister(&exynos_drm_platform_driver);
 #ifdef CONFIG_DRM_EXYNOS_VIDI
        exynos_drm_remove_vidi();
 #endif
        platform_device_unregister(exynos_drm_pdev);
-       platform_driver_unregister(&exynos_drm_platform_driver);
 }
 
 module_init(exynos_drm_init);
index 36535f3..06cde45 100644 (file)
@@ -343,7 +343,7 @@ struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
 int exynos_dpi_remove(struct device *dev);
 #else
 static inline struct exynos_drm_display *
-exynos_dpi_probe(struct device *dev) { return 0; }
+exynos_dpi_probe(struct device *dev) { return NULL; }
 static inline int exynos_dpi_remove(struct device *dev) { return 0; }
 #endif
 
index bb45ab2..33161ad 100644 (file)
@@ -741,6 +741,8 @@ static void fimd_apply(struct exynos_drm_manager *mgr)
                win_data = &ctx->win_data[i];
                if (win_data->enabled)
                        fimd_win_commit(mgr, i);
+               else
+                       fimd_win_disable(mgr, i);
        }
 
        fimd_commit(mgr);
index c104d0c..aa259b0 100644 (file)
@@ -2090,6 +2090,11 @@ out:
 
 static void hdmi_dpms(struct exynos_drm_display *display, int mode)
 {
+       struct hdmi_context *hdata = display->ctx;
+       struct drm_encoder *encoder = hdata->encoder;
+       struct drm_crtc *crtc = encoder->crtc;
+       struct drm_crtc_helper_funcs *funcs = NULL;
+
        DRM_DEBUG_KMS("mode %d\n", mode);
 
        switch (mode) {
@@ -2099,6 +2104,20 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
+               /*
+                * The SFRs of VP and Mixer are updated by Vertical Sync of
+                * Timing generator which is a part of HDMI so the sequence
+                * to disable TV Subsystem should be as following,
+                *      VP -> Mixer -> HDMI
+                *
+                * Below codes will try to disable Mixer and VP(if used)
+                * prior to disabling HDMI.
+                */
+               if (crtc)
+                       funcs = crtc->helper_private;
+               if (funcs && funcs->dpms)
+                       (*funcs->dpms)(crtc, mode);
+
                hdmi_poweroff(display);
                break;
        default:
index 4c5aed7..7529946 100644 (file)
@@ -377,6 +377,20 @@ static void mixer_run(struct mixer_context *ctx)
        mixer_regs_dump(ctx);
 }
 
+static void mixer_stop(struct mixer_context *ctx)
+{
+       struct mixer_resources *res = &ctx->mixer_res;
+       int timeout = 20;
+
+       mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
+
+       while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
+                       --timeout)
+               usleep_range(10000, 12000);
+
+       mixer_regs_dump(ctx);
+}
+
 static void vp_video_buffer(struct mixer_context *ctx, int win)
 {
        struct mixer_resources *res = &ctx->mixer_res;
@@ -497,13 +511,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
 static void mixer_layer_update(struct mixer_context *ctx)
 {
        struct mixer_resources *res = &ctx->mixer_res;
-       u32 val;
-
-       val = mixer_reg_read(res, MXR_CFG);
 
-       /* allow one update per vsync only */
-       if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
-               mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
+       mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
 }
 
 static void mixer_graph_buffer(struct mixer_context *ctx, int win)
@@ -1010,6 +1019,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
        }
        mutex_unlock(&mixer_ctx->mixer_mutex);
 
+       drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe);
+
        atomic_set(&mixer_ctx->wait_vsync_event, 1);
 
        /*
@@ -1020,6 +1031,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
                                !atomic_read(&mixer_ctx->wait_vsync_event),
                                HZ/20))
                DRM_DEBUG_KMS("vblank wait timed out.\n");
+
+       drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe);
 }
 
 static void mixer_window_suspend(struct exynos_drm_manager *mgr)
@@ -1061,7 +1074,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
                mutex_unlock(&ctx->mixer_mutex);
                return;
        }
-       ctx->powered = true;
+
        mutex_unlock(&ctx->mixer_mutex);
 
        pm_runtime_get_sync(ctx->dev);
@@ -1072,6 +1085,12 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
                clk_prepare_enable(res->sclk_mixer);
        }
 
+       mutex_lock(&ctx->mixer_mutex);
+       ctx->powered = true;
+       mutex_unlock(&ctx->mixer_mutex);
+
+       mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
+
        mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
        mixer_win_reset(ctx);
 
@@ -1084,14 +1103,21 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
        struct mixer_resources *res = &ctx->mixer_res;
 
        mutex_lock(&ctx->mixer_mutex);
-       if (!ctx->powered)
-               goto out;
+       if (!ctx->powered) {
+               mutex_unlock(&ctx->mixer_mutex);
+               return;
+       }
        mutex_unlock(&ctx->mixer_mutex);
 
+       mixer_stop(ctx);
        mixer_window_suspend(mgr);
 
        ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
 
+       mutex_lock(&ctx->mixer_mutex);
+       ctx->powered = false;
+       mutex_unlock(&ctx->mixer_mutex);
+
        clk_disable_unprepare(res->mixer);
        if (ctx->vp_enabled) {
                clk_disable_unprepare(res->vp);
@@ -1099,12 +1125,6 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
        }
 
        pm_runtime_put_sync(ctx->dev);
-
-       mutex_lock(&ctx->mixer_mutex);
-       ctx->powered = false;
-
-out:
-       mutex_unlock(&ctx->mixer_mutex);
 }
 
 static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
index 4537026..5f32e1a 100644 (file)
@@ -78,6 +78,7 @@
 #define MXR_STATUS_BIG_ENDIAN          (1 << 3)
 #define MXR_STATUS_ENDIAN_MASK         (1 << 3)
 #define MXR_STATUS_SYNC_ENABLE         (1 << 2)
+#define MXR_STATUS_REG_IDLE            (1 << 1)
 #define MXR_STATUS_REG_RUN             (1 << 0)
 
 /* bits for MXR_CFG */
index 601caa8..b8c6892 100644 (file)
@@ -446,7 +446,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
 
                memset(&stats, 0, sizeof(stats));
                stats.file_priv = file->driver_priv;
+               spin_lock(&file->table_lock);
                idr_for_each(&file->object_idr, per_file_stats, &stats);
+               spin_unlock(&file->table_lock);
                /*
                 * Although we have a valid reference on file->pid, that does
                 * not guarantee that the task_struct who called get_pid() is
index 4c22a5b..6c65639 100644 (file)
@@ -36,6 +36,8 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include <linux/pci.h>
+#include <linux/console.h>
+#include <linux/vt.h>
 #include <linux/vgaarb.h>
 #include <linux/acpi.h>
 #include <linux/pnp.h>
@@ -1386,7 +1388,6 @@ cleanup_gem:
        i915_gem_context_fini(dev);
        mutex_unlock(&dev->struct_mutex);
        WARN_ON(dev_priv->mm.aliasing_ppgtt);
-       drm_mm_takedown(&dev_priv->gtt.base.mm);
 cleanup_irq:
        drm_irq_uninstall(dev);
 cleanup_gem_stolen:
@@ -1450,6 +1451,38 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
 }
 #endif
 
+#if !defined(CONFIG_VGA_CONSOLE)
+static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
+{
+       return 0;
+}
+#elif !defined(CONFIG_DUMMY_CONSOLE)
+static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
+{
+       return -ENODEV;
+}
+#else
+static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
+{
+       int ret;
+
+       DRM_INFO("Replacing VGA console driver\n");
+
+       console_lock();
+       ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
+       if (ret == 0) {
+               ret = do_unregister_con_driver(&vga_con);
+
+               /* Ignore "already unregistered". */
+               if (ret == -ENODEV)
+                       ret = 0;
+       }
+       console_unlock();
+
+       return ret;
+}
+#endif
+
 static void i915_dump_device_info(struct drm_i915_private *dev_priv)
 {
        const struct intel_device_info *info = &dev_priv->info;
@@ -1623,8 +1656,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        if (ret)
                goto out_regs;
 
-       if (drm_core_check_feature(dev, DRIVER_MODESET))
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               ret = i915_kick_out_vgacon(dev_priv);
+               if (ret) {
+                       DRM_ERROR("failed to remove conflicting VGA console\n");
+                       goto out_gtt;
+               }
+
                i915_kick_out_firmware_fb(dev_priv);
+       }
 
        pci_set_master(dev->pdev);
 
@@ -1756,8 +1796,6 @@ out_mtrrfree:
        arch_phys_wc_del(dev_priv->gtt.mtrr);
        io_mapping_free(dev_priv->gtt.mappable);
 out_gtt:
-       list_del(&dev_priv->gtt.base.global_link);
-       drm_mm_takedown(&dev_priv->gtt.base.mm);
        dev_priv->gtt.base.cleanup(&dev_priv->gtt.base);
 out_regs:
        intel_uncore_fini(dev);
@@ -1846,7 +1884,6 @@ int i915_driver_unload(struct drm_device *dev)
                        i915_free_hws(dev);
        }
 
-       list_del(&dev_priv->gtt.base.global_link);
        WARN_ON(!list_empty(&dev_priv->vm_list));
 
        drm_vblank_cleanup(dev);
index 49414d3..a47fbf6 100644 (file)
@@ -977,6 +977,8 @@ struct i915_power_well {
        bool always_on;
        /* power well enable/disable usage count */
        int count;
+       /* cached hw enabled state */
+       bool hw_enabled;
        unsigned long domains;
        unsigned long data;
        const struct i915_power_well_ops *ops;
index 3ffe308..a5ddf3b 100644 (file)
@@ -598,6 +598,7 @@ static int do_switch(struct intel_engine_cs *ring,
        struct intel_context *from = ring->last_context;
        struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to);
        u32 hw_flags = 0;
+       bool uninitialized = false;
        int ret, i;
 
        if (from != NULL && ring == &dev_priv->ring[RCS]) {
@@ -696,19 +697,20 @@ static int do_switch(struct intel_engine_cs *ring,
                i915_gem_context_unreference(from);
        }
 
+       uninitialized = !to->is_initialized && from == NULL;
+       to->is_initialized = true;
+
 done:
        i915_gem_context_reference(to);
        ring->last_context = to;
        to->last_ring = ring;
 
-       if (ring->id == RCS && !to->is_initialized && from == NULL) {
+       if (uninitialized) {
                ret = i915_gem_render_state_init(ring);
                if (ret)
                        DRM_ERROR("init render state: %d\n", ret);
        }
 
-       to->is_initialized = true;
-
        return 0;
 
 unpin_out:
index eec820a..8b3cde7 100644 (file)
@@ -1992,7 +1992,10 @@ static void gen6_gmch_remove(struct i915_address_space *vm)
 
        struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base);
 
-       drm_mm_takedown(&vm->mm);
+       if (drm_mm_initialized(&vm->mm)) {
+               drm_mm_takedown(&vm->mm);
+               list_del(&vm->global_link);
+       }
        iounmap(gtt->gsm);
        teardown_scratch_page(vm->dev);
 }
@@ -2025,6 +2028,10 @@ static int i915_gmch_probe(struct drm_device *dev,
 
 static void i915_gmch_remove(struct i915_address_space *vm)
 {
+       if (drm_mm_initialized(&vm->mm)) {
+               drm_mm_takedown(&vm->mm);
+               list_del(&vm->global_link);
+       }
        intel_gmch_remove();
 }
 
index 87ec60e..66cf417 100644 (file)
@@ -888,6 +888,8 @@ static void i915_gem_record_rings(struct drm_device *dev,
        for (i = 0; i < I915_NUM_RINGS; i++) {
                struct intel_engine_cs *ring = &dev_priv->ring[i];
 
+               error->ring[i].pid = -1;
+
                if (ring->dev == NULL)
                        continue;
 
@@ -895,7 +897,6 @@ static void i915_gem_record_rings(struct drm_device *dev,
 
                i915_record_ring_state(dev, ring, &error->ring[i]);
 
-               error->ring[i].pid = -1;
                request = i915_gem_find_active_request(ring);
                if (request) {
                        /* We need to copy these to an anonymous buffer
index 6f8017a..267f069 100644 (file)
@@ -2847,10 +2847,14 @@ static int semaphore_passed(struct intel_engine_cs *ring)
        struct intel_engine_cs *signaller;
        u32 seqno, ctl;
 
-       ring->hangcheck.deadlock = true;
+       ring->hangcheck.deadlock++;
 
        signaller = semaphore_waits_for(ring, &seqno);
-       if (signaller == NULL || signaller->hangcheck.deadlock)
+       if (signaller == NULL)
+               return -1;
+
+       /* Prevent pathological recursion due to driver bugs */
+       if (signaller->hangcheck.deadlock >= I915_NUM_RINGS)
                return -1;
 
        /* cursory check for an unkickable deadlock */
@@ -2858,7 +2862,13 @@ static int semaphore_passed(struct intel_engine_cs *ring)
        if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0)
                return -1;
 
-       return i915_seqno_passed(signaller->get_seqno(signaller, false), seqno);
+       if (i915_seqno_passed(signaller->get_seqno(signaller, false), seqno))
+               return 1;
+
+       if (signaller->hangcheck.deadlock)
+               return -1;
+
+       return 0;
 }
 
 static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
@@ -2867,7 +2877,7 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
        int i;
 
        for_each_ring(ring, dev_priv, i)
-               ring->hangcheck.deadlock = false;
+               ring->hangcheck.deadlock = 0;
 }
 
 static enum intel_ring_hangcheck_action
index 1ee98f1..827498e 100644 (file)
@@ -315,9 +315,6 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
        const struct bdb_lfp_backlight_data *backlight_data;
        const struct bdb_lfp_backlight_data_entry *entry;
 
-       /* Err to enabling backlight if no backlight block. */
-       dev_priv->vbt.backlight.present = true;
-
        backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
        if (!backlight_data)
                return;
@@ -1088,6 +1085,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
 
        dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC;
 
+       /* Default to having backlight */
+       dev_priv->vbt.backlight.present = true;
+
        /* LFP panel data */
        dev_priv->vbt.lvds_dither = 1;
        dev_priv->vbt.lvds_vbt = 0;
index efd3cf5..5f285fb 100644 (file)
@@ -4564,7 +4564,10 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
        if (intel_crtc->active)
                return;
 
-       vlv_prepare_pll(intel_crtc);
+       is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI);
+
+       if (!is_dsi && !IS_CHERRYVIEW(dev))
+               vlv_prepare_pll(intel_crtc);
 
        /* Set up the display plane register */
        dspcntr = DISPPLANE_GAMMA_ENABLE;
@@ -4598,8 +4601,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
                if (encoder->pre_pll_enable)
                        encoder->pre_pll_enable(encoder);
 
-       is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI);
-
        if (!is_dsi) {
                if (IS_CHERRYVIEW(dev))
                        chv_enable_pll(intel_crtc);
@@ -12411,8 +12412,8 @@ intel_display_capture_error_state(struct drm_device *dev)
 
        for_each_pipe(i) {
                error->pipe[i].power_domain_on =
-                       intel_display_power_enabled_sw(dev_priv,
-                                                      POWER_DOMAIN_PIPE(i));
+                       intel_display_power_enabled_unlocked(dev_priv,
+                                                          POWER_DOMAIN_PIPE(i));
                if (!error->pipe[i].power_domain_on)
                        continue;
 
@@ -12447,7 +12448,7 @@ intel_display_capture_error_state(struct drm_device *dev)
                enum transcoder cpu_transcoder = transcoders[i];
 
                error->transcoder[i].power_domain_on =
-                       intel_display_power_enabled_sw(dev_priv,
+                       intel_display_power_enabled_unlocked(dev_priv,
                                POWER_DOMAIN_TRANSCODER(cpu_transcoder));
                if (!error->transcoder[i].power_domain_on)
                        continue;
index bda0ae3..eaa27ee 100644 (file)
@@ -950,8 +950,8 @@ int intel_power_domains_init(struct drm_i915_private *);
 void intel_power_domains_remove(struct drm_i915_private *);
 bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
                                 enum intel_display_power_domain domain);
-bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
-                                   enum intel_display_power_domain domain);
+bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv,
+                                         enum intel_display_power_domain domain);
 void intel_display_power_get(struct drm_i915_private *dev_priv,
                             enum intel_display_power_domain domain);
 void intel_display_power_put(struct drm_i915_private *dev_priv,
index 5e6c888..38a9857 100644 (file)
@@ -798,9 +798,6 @@ static void i965_enable_backlight(struct intel_connector *connector)
        ctl = freq << 16;
        I915_WRITE(BLC_PWM_CTL, ctl);
 
-       /* XXX: combine this into above write? */
-       intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
        ctl2 = BLM_PIPE(pipe);
        if (panel->backlight.combination_mode)
                ctl2 |= BLM_COMBINATION_MODE;
@@ -809,6 +806,8 @@ static void i965_enable_backlight(struct intel_connector *connector)
        I915_WRITE(BLC_PWM_CTL2, ctl2);
        POSTING_READ(BLC_PWM_CTL2);
        I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
+
+       intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
 static void vlv_enable_backlight(struct intel_connector *connector)
index d1e53ab..9ad0c6a 100644 (file)
@@ -511,8 +511,7 @@ void intel_update_fbc(struct drm_device *dev)
        obj = intel_fb->obj;
        adjusted_mode = &intel_crtc->config.adjusted_mode;
 
-       if (i915.enable_fbc < 0 &&
-           INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) {
+       if (i915.enable_fbc < 0) {
                if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT))
                        DRM_DEBUG_KMS("disabled per chip default\n");
                goto out_disable;
@@ -3506,15 +3505,11 @@ static void gen8_enable_rps(struct drm_device *dev)
 
        I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
 
-       /* WaDisablePwrmtrEvent:chv (pre-production hw) */
-       I915_WRITE(0xA80C, I915_READ(0xA80C) & 0x00ffffff);
-       I915_WRITE(0xA810, I915_READ(0xA810) & 0xffffff00);
-
        /* 5: Enable RPS */
        I915_WRITE(GEN6_RP_CONTROL,
                   GEN6_RP_MEDIA_TURBO |
                   GEN6_RP_MEDIA_HW_NORMAL_MODE |
-                  GEN6_RP_MEDIA_IS_GFX | /* WaSetMaskForGfxBusyness:chv (pre-production hw ?) */
+                  GEN6_RP_MEDIA_IS_GFX |
                   GEN6_RP_ENABLE |
                   GEN6_RP_UP_BUSY_AVG |
                   GEN6_RP_DOWN_IDLE_AVG);
@@ -5608,8 +5603,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
                     (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
 }
 
-bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
-                                   enum intel_display_power_domain domain)
+bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv,
+                                         enum intel_display_power_domain domain)
 {
        struct i915_power_domains *power_domains;
        struct i915_power_well *power_well;
@@ -5620,16 +5615,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
                return false;
 
        power_domains = &dev_priv->power_domains;
+
        is_enabled = true;
+
        for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
                if (power_well->always_on)
                        continue;
 
-               if (!power_well->count) {
+               if (!power_well->hw_enabled) {
                        is_enabled = false;
                        break;
                }
        }
+
        return is_enabled;
 }
 
@@ -5637,30 +5635,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
                                 enum intel_display_power_domain domain)
 {
        struct i915_power_domains *power_domains;
-       struct i915_power_well *power_well;
-       bool is_enabled;
-       int i;
-
-       if (dev_priv->pm.suspended)
-               return false;
+       bool ret;
 
        power_domains = &dev_priv->power_domains;
 
-       is_enabled = true;
-
        mutex_lock(&power_domains->lock);
-       for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
-               if (power_well->always_on)
-                       continue;
-
-               if (!power_well->ops->is_enabled(dev_priv, power_well)) {
-                       is_enabled = false;
-                       break;
-               }
-       }
+       ret = intel_display_power_enabled_unlocked(dev_priv, domain);
        mutex_unlock(&power_domains->lock);
 
-       return is_enabled;
+       return ret;
 }
 
 /*
@@ -5981,6 +5964,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
                if (!power_well->count++) {
                        DRM_DEBUG_KMS("enabling %s\n", power_well->name);
                        power_well->ops->enable(dev_priv, power_well);
+                       power_well->hw_enabled = true;
                }
 
                check_power_well_state(dev_priv, power_well);
@@ -6010,6 +5994,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 
                if (!--power_well->count && i915.disable_power_well) {
                        DRM_DEBUG_KMS("disabling %s\n", power_well->name);
+                       power_well->hw_enabled = false;
                        power_well->ops->disable(dev_priv, power_well);
                }
 
@@ -6024,30 +6009,32 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 static struct i915_power_domains *hsw_pwr;
 
 /* Display audio driver power well request */
-void i915_request_power_well(void)
+int i915_request_power_well(void)
 {
        struct drm_i915_private *dev_priv;
 
-       if (WARN_ON(!hsw_pwr))
-               return;
+       if (!hsw_pwr)
+               return -ENODEV;
 
        dev_priv = container_of(hsw_pwr, struct drm_i915_private,
                                power_domains);
        intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(i915_request_power_well);
 
 /* Display audio driver power well release */
-void i915_release_power_well(void)
+int i915_release_power_well(void)
 {
        struct drm_i915_private *dev_priv;
 
-       if (WARN_ON(!hsw_pwr))
-               return;
+       if (!hsw_pwr)
+               return -ENODEV;
 
        dev_priv = container_of(hsw_pwr, struct drm_i915_private,
                                power_domains);
        intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(i915_release_power_well);
 
@@ -6270,8 +6257,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
        int i;
 
        mutex_lock(&power_domains->lock);
-       for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains)
+       for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
                power_well->ops->sync_hw(dev_priv, power_well);
+               power_well->hw_enabled = power_well->ops->is_enabled(dev_priv,
+                                                                    power_well);
+       }
        mutex_unlock(&power_domains->lock);
 }
 
index 910c83c..e72017b 100644 (file)
@@ -55,7 +55,7 @@ struct intel_ring_hangcheck {
        u32 seqno;
        int score;
        enum intel_ring_hangcheck_action action;
-       bool deadlock;
+       int deadlock;
 };
 
 struct intel_ringbuffer {
index 6a4d5bc..20375cc 100644 (file)
@@ -1385,7 +1385,9 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
                         >> SDVO_PORT_MULTIPLY_SHIFT) + 1;
        }
 
-       dotclock = pipe_config->port_clock / pipe_config->pixel_multiplier;
+       dotclock = pipe_config->port_clock;
+       if (pipe_config->pixel_multiplier)
+               dotclock /= pipe_config->pixel_multiplier;
 
        if (HAS_PCH_SPLIT(dev))
                ironlake_check_encoder_dotclock(pipe_config, dotclock);
index 79cba59..4f6fef7 100644 (file)
@@ -320,7 +320,8 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
-       del_timer_sync(&dev_priv->uncore.force_wake_timer);
+       if (del_timer_sync(&dev_priv->uncore.force_wake_timer))
+               gen6_force_wake_timer((unsigned long)dev_priv);
 
        /* Hold uncore.lock across reset to prevent any register access
         * with forcewake not set correctly
index ae750f6..7f7aade 100644 (file)
@@ -277,6 +277,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
        static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"};
        static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"};
        static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"};
+       static unsigned long hpd_clk_freq[] = {0, 19200000, 0};
        static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"};
 
        config.phy_init      = hdmi_phy_8x74_init;
@@ -286,6 +287,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
        config.pwr_reg_names = pwr_reg_names;
        config.pwr_reg_cnt   = ARRAY_SIZE(pwr_reg_names);
        config.hpd_clk_names = hpd_clk_names;
+       config.hpd_freq      = hpd_clk_freq;
        config.hpd_clk_cnt   = ARRAY_SIZE(hpd_clk_names);
        config.pwr_clk_names = pwr_clk_names;
        config.pwr_clk_cnt   = ARRAY_SIZE(pwr_clk_names);
index 9fafee6..9d7723c 100644 (file)
@@ -87,6 +87,7 @@ struct hdmi_platform_config {
 
        /* clks that need to be on for hpd: */
        const char **hpd_clk_names;
+       const long unsigned *hpd_freq;
        int hpd_clk_cnt;
 
        /* clks that need to be on for screen pwr (ie pixel clk): */
index e56a619..28f7e3e 100644 (file)
@@ -127,6 +127,14 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
        }
 
        for (i = 0; i < config->hpd_clk_cnt; i++) {
+               if (config->hpd_freq && config->hpd_freq[i]) {
+                       ret = clk_set_rate(hdmi->hpd_clks[i],
+                                       config->hpd_freq[i]);
+                       if (ret)
+                               dev_warn(dev->dev, "failed to set clk %s (%d)\n",
+                                               config->hpd_clk_names[i], ret);
+               }
+
                ret = clk_prepare_enable(hdmi->hpd_clks[i]);
                if (ret) {
                        dev_err(dev->dev, "failed to enable hpd clk: %s (%d)\n",
index 42caf7f..71510ee 100644 (file)
 #include "msm_mmu.h"
 #include "mdp5_kms.h"
 
+static const char *iommu_ports[] = {
+               "mdp_0",
+};
+
 static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev);
 
 static int mdp5_hw_init(struct msm_kms *kms)
@@ -104,6 +108,12 @@ static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file)
 static void mdp5_destroy(struct msm_kms *kms)
 {
        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+       struct msm_mmu *mmu = mdp5_kms->mmu;
+
+       if (mmu) {
+               mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
+               mmu->funcs->destroy(mmu);
+       }
        kfree(mdp5_kms);
 }
 
@@ -216,10 +226,6 @@ fail:
        return ret;
 }
 
-static const char *iommu_ports[] = {
-               "mdp_0",
-};
-
 static int get_clk(struct platform_device *pdev, struct clk **clkp,
                const char *name)
 {
@@ -317,17 +323,23 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
                mmu = msm_iommu_new(dev, config->iommu);
                if (IS_ERR(mmu)) {
                        ret = PTR_ERR(mmu);
+                       dev_err(dev->dev, "failed to init iommu: %d\n", ret);
                        goto fail;
                }
+
                ret = mmu->funcs->attach(mmu, iommu_ports,
                                ARRAY_SIZE(iommu_ports));
-               if (ret)
+               if (ret) {
+                       dev_err(dev->dev, "failed to attach iommu: %d\n", ret);
+                       mmu->funcs->destroy(mmu);
                        goto fail;
+               }
        } else {
                dev_info(dev->dev, "no iommu, fallback to phys "
                                "contig buffers for scanout\n");
                mmu = NULL;
        }
+       mdp5_kms->mmu = mmu;
 
        mdp5_kms->id = msm_register_mmu(dev, mmu);
        if (mdp5_kms->id < 0) {
index c8b1a25..6e981b6 100644 (file)
@@ -33,6 +33,7 @@ struct mdp5_kms {
 
        /* mapper-id used to request GEM buffer mapped for scanout: */
        int id;
+       struct msm_mmu *mmu;
 
        /* for tracking smp allocation amongst pipes: */
        mdp5_smp_state_t smp_state;
index 0d2562f..9a5d87d 100644 (file)
@@ -159,7 +159,7 @@ static int msm_unload(struct drm_device *dev)
 static int get_mdp_ver(struct platform_device *pdev)
 {
 #ifdef CONFIG_OF
-       const static struct of_device_id match_types[] = { {
+       static const struct of_device_id match_types[] = { {
                .compatible = "qcom,mdss_mdp",
                .data   = (void *)5,
        }, {
index a752ab8..5107fc4 100644 (file)
@@ -59,7 +59,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
        struct drm_framebuffer *fb = NULL;
        struct fb_info *fbi = NULL;
        struct drm_mode_fb_cmd2 mode_cmd = {0};
-       dma_addr_t paddr;
+       uint32_t paddr;
        int ret, size;
 
        sizes->surface_bpp = 32;
index bb8026d..690d7e7 100644 (file)
@@ -278,6 +278,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
                uint32_t *iova)
 {
        struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       struct drm_device *dev = obj->dev;
        int ret = 0;
 
        if (!msm_obj->domain[id].iova) {
@@ -285,6 +286,11 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
                struct msm_mmu *mmu = priv->mmus[id];
                struct page **pages = get_pages(obj);
 
+               if (!mmu) {
+                       dev_err(dev->dev, "null MMU pointer\n");
+                       return -EINVAL;
+               }
+
                if (IS_ERR(pages))
                        return PTR_ERR(pages);
 
index 92b7459..4b2ad91 100644 (file)
@@ -28,7 +28,7 @@ static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev,
                unsigned long iova, int flags, void *arg)
 {
        DBG("*** fault: iova=%08lx, flags=%d", iova, flags);
-       return 0;
+       return -ENOSYS;
 }
 
 static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt)
@@ -40,8 +40,10 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt)
        for (i = 0; i < cnt; i++) {
                struct device *msm_iommu_get_ctx(const char *ctx_name);
                struct device *ctx = msm_iommu_get_ctx(names[i]);
-               if (IS_ERR_OR_NULL(ctx))
+               if (IS_ERR_OR_NULL(ctx)) {
+                       dev_warn(dev->dev, "couldn't get %s context", names[i]);
                        continue;
+               }
                ret = iommu_attach_device(iommu->domain, ctx);
                if (ret) {
                        dev_warn(dev->dev, "could not attach iommu to %s", names[i]);
@@ -52,6 +54,20 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt)
        return 0;
 }
 
+static void msm_iommu_detach(struct msm_mmu *mmu, const char **names, int cnt)
+{
+       struct msm_iommu *iommu = to_msm_iommu(mmu);
+       int i;
+
+       for (i = 0; i < cnt; i++) {
+               struct device *msm_iommu_get_ctx(const char *ctx_name);
+               struct device *ctx = msm_iommu_get_ctx(names[i]);
+               if (IS_ERR_OR_NULL(ctx))
+                       continue;
+               iommu_detach_device(iommu->domain, ctx);
+       }
+}
+
 static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova,
                struct sg_table *sgt, unsigned len, int prot)
 {
@@ -110,7 +126,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint32_t iova,
 
                VERB("unmap[%d]: %08x(%x)", i, iova, bytes);
 
-               BUG_ON(!IS_ALIGNED(bytes, PAGE_SIZE));
+               BUG_ON(!PAGE_ALIGNED(bytes));
 
                da += bytes;
        }
@@ -127,6 +143,7 @@ static void msm_iommu_destroy(struct msm_mmu *mmu)
 
 static const struct msm_mmu_funcs funcs = {
                .attach = msm_iommu_attach,
+               .detach = msm_iommu_detach,
                .map = msm_iommu_map,
                .unmap = msm_iommu_unmap,
                .destroy = msm_iommu_destroy,
index 0303244..21da6d1 100644 (file)
@@ -22,6 +22,7 @@
 
 struct msm_mmu_funcs {
        int (*attach)(struct msm_mmu *mmu, const char **names, int cnt);
+       void (*detach)(struct msm_mmu *mmu, const char **names, int cnt);
        int (*map)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt,
                        unsigned len, int prot);
        int (*unmap)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt,
index 2b6156d..8b307e1 100644 (file)
@@ -140,6 +140,7 @@ nouveau-y += core/subdev/i2c/nv4e.o
 nouveau-y += core/subdev/i2c/nv50.o
 nouveau-y += core/subdev/i2c/nv94.o
 nouveau-y += core/subdev/i2c/nvd0.o
+nouveau-y += core/subdev/i2c/gf117.o
 nouveau-y += core/subdev/i2c/nve0.o
 nouveau-y += core/subdev/ibus/nvc0.o
 nouveau-y += core/subdev/ibus/nve0.o
index f199957..8d55ed6 100644 (file)
@@ -314,7 +314,7 @@ nvc0_identify(struct nouveau_device *device)
                device->cname = "GF117";
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  nvd0_gpio_oclass;
-               device->oclass[NVDEV_SUBDEV_I2C    ] =  nvd0_i2c_oclass;
+               device->oclass[NVDEV_SUBDEV_I2C    ] =  gf117_i2c_oclass;
                device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
index c41f656..9c38c5e 100644 (file)
@@ -99,8 +99,10 @@ _nouveau_disp_dtor(struct nouveau_object *object)
 
        nouveau_event_destroy(&disp->vblank);
 
-       list_for_each_entry_safe(outp, outt, &disp->outp, head) {
-               nouveau_object_ref(NULL, (struct nouveau_object **)&outp);
+       if (disp->outp.next) {
+               list_for_each_entry_safe(outp, outt, &disp->outp, head) {
+                       nouveau_object_ref(NULL, (struct nouveau_object **)&outp);
+               }
        }
 
        nouveau_engine_destroy(&disp->base);
index 39562d4..5a5b59b 100644 (file)
@@ -241,7 +241,9 @@ dp_link_train_eq(struct dp_state *dp)
                dp_set_training_pattern(dp, 2);
 
        do {
-               if (dp_link_train_update(dp, dp->pc2, 400))
+               if ((tries &&
+                   dp_link_train_commit(dp, dp->pc2)) ||
+                   dp_link_train_update(dp, dp->pc2, 400))
                        break;
 
                eq_done = !!(dp->stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE);
@@ -253,9 +255,6 @@ dp_link_train_eq(struct dp_state *dp)
                            !(lane & DPCD_LS02_LANE0_SYMBOL_LOCKED))
                                eq_done = false;
                }
-
-               if (dp_link_train_commit(dp, dp->pc2))
-                       break;
        } while (!eq_done && cr_done && ++tries <= 5);
 
        return eq_done ? 0 : -1;
index 1e85f36..26e962b 100644 (file)
@@ -1270,7 +1270,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf)
        i--;
 
        outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info1);
-       if (!data)
+       if (!outp)
                return NULL;
 
        if (outp->info.location == 0) {
index 2f7345f..7445f12 100644 (file)
@@ -54,7 +54,7 @@ mmio_list_base:
 #ifdef INCLUDE_CODE
 // reports an exception to the host
 //
-// In: $r15 error code (see nvc0.fuc)
+// In: $r15 error code (see os.h)
 //
 error:
        push $r14
index c8ddb8d..b4ad18b 100644 (file)
@@ -49,7 +49,7 @@ hub_mmio_list_next:
 #ifdef INCLUDE_CODE
 // reports an exception to the host
 //
-// In: $r15 error code (see nvc0.fuc)
+// In: $r15 error code (see os.h)
 //
 error:
        nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(5), 0, $r15)
@@ -343,13 +343,25 @@ ih:
        ih_no_ctxsw:
        and $r11 $r10 NV_PGRAPH_FECS_INTR_FWMTHD
        bra e #ih_no_fwmthd
-               // none we handle, ack, and fall-through to unhandled
+               // none we handle; report to host and ack
+               nv_rd32($r15, NV_PGRAPH_TRAPPED_DATA_LO)
+               nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(4), 0, $r15)
+               nv_rd32($r15, NV_PGRAPH_TRAPPED_ADDR)
+               nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(3), 0, $r15)
+               extr $r14 $r15 16:18
+               shl b32 $r14 $r14 2
+               imm32($r15, NV_PGRAPH_FE_OBJECT_TABLE(0))
+               add b32 $r14 $r15
+               call(nv_rd32)
+               nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(2), 0, $r15)
+               mov $r15 E_BAD_FWMTHD
+               call(error)
                mov $r11 0x100
                nv_wr32(0x400144, $r11)
 
        // anything we didn't handle, bring it to the host's attention
        ih_no_fwmthd:
-       mov $r11 0x104 // FIFO | CHSW
+       mov $r11 0x504 // FIFO | CHSW | FWMTHD
        not b32 $r11
        and $r11 $r10 $r11
        bra e #ih_no_other
index 214dd16..5f953c5 100644 (file)
@@ -478,10 +478,10 @@ uint32_t gm107_grhub_code[] = {
        0x01040080,
        0xbd0001f6,
        0x01004104,
-       0x627e020f,
-       0x717e0006,
+       0xa87e020f,
+       0xb77e0006,
        0x100f0006,
-       0x0006b37e,
+       0x0006f97e,
        0x98000e98,
        0x207e010f,
        0x14950001,
@@ -523,8 +523,8 @@ uint32_t gm107_grhub_code[] = {
        0x800040b7,
        0xf40132b6,
        0x000fb41b,
-       0x0006b37e,
-       0x627e000f,
+       0x0006f97e,
+       0xa87e000f,
        0x00800006,
        0x01f60201,
        0xbd04bd00,
@@ -554,7 +554,7 @@ uint32_t gm107_grhub_code[] = {
        0x0009f602,
        0x32f404bd,
        0x0231f401,
-       0x0008367e,
+       0x00087c7e,
        0x99f094bd,
        0x17008007,
        0x0009f602,
@@ -563,7 +563,7 @@ uint32_t gm107_grhub_code[] = {
        0x37008006,
        0x0009f602,
        0x31f404bd,
-       0x08367e01,
+       0x087c7e01,
        0xf094bd00,
        0x00800699,
        0x09f60217,
@@ -572,7 +572,7 @@ uint32_t gm107_grhub_code[] = {
        0x20f92f0e,
        0x32f412b2,
        0x0232f401,
-       0x0008367e,
+       0x00087c7e,
        0x008020fc,
        0x02f602c0,
        0xf404bd00,
@@ -580,7 +580,7 @@ uint32_t gm107_grhub_code[] = {
        0x23c8130e,
        0x0d0bf41f,
        0xf40131f4,
-       0x367e0232,
+       0x7c7e0232,
 /* 0x054e: chsw_done */
        0x01020008,
        0x02c30080,
@@ -593,7 +593,7 @@ uint32_t gm107_grhub_code[] = {
        0xb0ff2a0e,
        0x1bf401e4,
        0x7ef2b20c,
-       0xf40007d6,
+       0xf400081c,
 /* 0x057a: main_not_ctx_chan */
        0xe4b0400e,
        0x2c1bf402,
@@ -602,7 +602,7 @@ uint32_t gm107_grhub_code[] = {
        0x0009f602,
        0x32f404bd,
        0x0232f401,
-       0x0008367e,
+       0x00087c7e,
        0x99f094bd,
        0x17008007,
        0x0009f602,
@@ -642,238 +642,238 @@ uint32_t gm107_grhub_code[] = {
 /* 0x061a: ih_no_ctxsw */
        0xabe40000,
        0x0bf40400,
-       0x01004b10,
-       0x448ebfb2,
-       0x8f7e4001,
-/* 0x062e: ih_no_fwmthd */
-       0x044b0000,
-       0xffb0bd01,
-       0x0bf4b4ab,
-       0x0700800c,
-       0x000bf603,
-/* 0x0642: ih_no_other */
-       0x004004bd,
-       0x000af601,
-       0xf0fc04bd,
-       0xd0fce0fc,
-       0xa0fcb0fc,
-       0x80fc90fc,
-       0xfc0088fe,
-       0x0032f480,
-/* 0x0662: ctx_4170s */
-       0xf5f001f8,
-       0x8effb210,
-       0x7e404170,
-       0xf800008f,
-/* 0x0671: ctx_4170w */
-       0x41708e00,
+       0x07088e56,
        0x00657e40,
-       0xf0ffb200,
-       0x1bf410f4,
-/* 0x0683: ctx_redswitch */
-       0x4e00f8f3,
-       0xe5f00200,
-       0x20e5f040,
-       0x8010e5f0,
-       0xf6018500,
-       0x04bd000e,
-/* 0x069a: ctx_redswitch_delay */
-       0xf2b6080f,
-       0xfd1bf401,
-       0x0400e5f1,
-       0x0100e5f1,
-       0x01850080,
-       0xbd000ef6,
-/* 0x06b3: ctx_86c */
-       0x8000f804,
-       0xf6022300,
+       0x80ffb200,
+       0xf6020400,
        0x04bd000f,
-       0x148effb2,
-       0x8f7e408a,
-       0xffb20000,
-       0x41a88c8e,
+       0x4007048e,
+       0x0000657e,
+       0x0080ffb2,
+       0x0ff60203,
+       0xc704bd00,
+       0xee9450fe,
+       0x07008f02,
+       0x00efbb40,
+       0x0000657e,
+       0x02020080,
+       0xbd000ff6,
+       0x7e030f04,
+       0x4b0002f8,
+       0xbfb20100,
+       0x4001448e,
        0x00008f7e,
-/* 0x06d2: ctx_mem */
-       0x008000f8,
-       0x0ff60284,
-/* 0x06db: ctx_mem_wait */
-       0x8f04bd00,
-       0xcf028400,
-       0xfffd00ff,
-       0xf61bf405,
-/* 0x06ea: ctx_load */
-       0x94bd00f8,
-       0x800599f0,
-       0xf6023700,
-       0x04bd0009,
-       0xb87e0c0a,
-       0xf4bd0000,
-       0x02890080,
+/* 0x0674: ih_no_fwmthd */
+       0xbd05044b,
+       0xb4abffb0,
+       0x800c0bf4,
+       0xf6030700,
+       0x04bd000b,
+/* 0x0688: ih_no_other */
+       0xf6010040,
+       0x04bd000a,
+       0xe0fcf0fc,
+       0xb0fcd0fc,
+       0x90fca0fc,
+       0x88fe80fc,
+       0xf480fc00,
+       0x01f80032,
+/* 0x06a8: ctx_4170s */
+       0xb210f5f0,
+       0x41708eff,
+       0x008f7e40,
+/* 0x06b7: ctx_4170w */
+       0x8e00f800,
+       0x7e404170,
+       0xb2000065,
+       0x10f4f0ff,
+       0xf8f31bf4,
+/* 0x06c9: ctx_redswitch */
+       0x02004e00,
+       0xf040e5f0,
+       0xe5f020e5,
+       0x85008010,
+       0x000ef601,
+       0x080f04bd,
+/* 0x06e0: ctx_redswitch_delay */
+       0xf401f2b6,
+       0xe5f1fd1b,
+       0xe5f10400,
+       0x00800100,
+       0x0ef60185,
+       0xf804bd00,
+/* 0x06f9: ctx_86c */
+       0x23008000,
+       0x000ff602,
+       0xffb204bd,
+       0x408a148e,
+       0x00008f7e,
+       0x8c8effb2,
+       0x8f7e41a8,
+       0x00f80000,
+/* 0x0718: ctx_mem */
+       0x02840080,
        0xbd000ff6,
-       0xc1008004,
-       0x0002f602,
-       0x008004bd,
-       0x02f60283,
-       0x0f04bd00,
-       0x06d27e07,
-       0xc0008000,
-       0x0002f602,
-       0x0bfe04bd,
-       0x1f2af000,
-       0xb60424b6,
-       0x94bd0220,
-       0x800899f0,
-       0xf6023700,
-       0x04bd0009,
-       0x02810080,
-       0xbd0002f6,
-       0x0000d204,
-       0x25f08000,
-       0x88008002,
-       0x0002f602,
-       0x100104bd,
-       0xf0020042,
-       0x12fa0223,
-       0xbd03f805,
-       0x0899f094,
-       0x02170080,
-       0xbd0009f6,
-       0x81019804,
-       0x981814b6,
-       0x25b68002,
-       0x0512fd08,
-       0xbd1601b5,
-       0x0999f094,
-       0x02370080,
-       0xbd0009f6,
-       0x81008004,
-       0x0001f602,
-       0x010204bd,
-       0x02880080,
+/* 0x0721: ctx_mem_wait */
+       0x84008f04,
+       0x00ffcf02,
+       0xf405fffd,
+       0x00f8f61b,
+/* 0x0730: ctx_load */
+       0x99f094bd,
+       0x37008005,
+       0x0009f602,
+       0x0c0a04bd,
+       0x0000b87e,
+       0x0080f4bd,
+       0x0ff60289,
+       0x8004bd00,
+       0xf602c100,
+       0x04bd0002,
+       0x02830080,
        0xbd0002f6,
-       0x01004104,
-       0xfa0613f0,
-       0x03f80501,
+       0x7e070f04,
+       0x80000718,
+       0xf602c000,
+       0x04bd0002,
+       0xf0000bfe,
+       0x24b61f2a,
+       0x0220b604,
        0x99f094bd,
-       0x17008009,
+       0x37008008,
        0x0009f602,
-       0x94bd04bd,
-       0x800599f0,
+       0x008004bd,
+       0x02f60281,
+       0xd204bd00,
+       0x80000000,
+       0x800225f0,
+       0xf6028800,
+       0x04bd0002,
+       0x00421001,
+       0x0223f002,
+       0xf80512fa,
+       0xf094bd03,
+       0x00800899,
+       0x09f60217,
+       0x9804bd00,
+       0x14b68101,
+       0x80029818,
+       0xfd0825b6,
+       0x01b50512,
+       0xf094bd16,
+       0x00800999,
+       0x09f60237,
+       0x8004bd00,
+       0xf6028100,
+       0x04bd0001,
+       0x00800102,
+       0x02f60288,
+       0x4104bd00,
+       0x13f00100,
+       0x0501fa06,
+       0x94bd03f8,
+       0x800999f0,
        0xf6021700,
        0x04bd0009,
-/* 0x07d6: ctx_chan */
-       0xea7e00f8,
-       0x0c0a0006,
-       0x0000b87e,
-       0xd27e050f,
-       0x00f80006,
-/* 0x07e8: ctx_mmio_exec */
-       0x80410398,
+       0x99f094bd,
+       0x17008005,
+       0x0009f602,
+       0x00f804bd,
+/* 0x081c: ctx_chan */
+       0x0007307e,
+       0xb87e0c0a,
+       0x050f0000,
+       0x0007187e,
+/* 0x082e: ctx_mmio_exec */
+       0x039800f8,
+       0x81008041,
+       0x0003f602,
+       0x34bd04bd,
+/* 0x083c: ctx_mmio_loop */
+       0xf4ff34c4,
+       0x00450e1b,
+       0x0653f002,
+       0xf80535fa,
+/* 0x084d: ctx_mmio_pull */
+       0x804e9803,
+       0x7e814f98,
+       0xb600008f,
+       0x12b60830,
+       0xdf1bf401,
+/* 0x0860: ctx_mmio_done */
+       0x80160398,
        0xf6028100,
        0x04bd0003,
-/* 0x07f6: ctx_mmio_loop */
-       0x34c434bd,
-       0x0e1bf4ff,
-       0xf0020045,
-       0x35fa0653,
-/* 0x0807: ctx_mmio_pull */
-       0x9803f805,
-       0x4f98804e,
-       0x008f7e81,
-       0x0830b600,
-       0xf40112b6,
-/* 0x081a: ctx_mmio_done */
-       0x0398df1b,
-       0x81008016,
-       0x0003f602,
-       0x00b504bd,
-       0x01004140,
-       0xfa0613f0,
-       0x03f80601,
-/* 0x0836: ctx_xfer */
-       0x040e00f8,
-       0x03020080,
-       0xbd000ef6,
-/* 0x0841: ctx_xfer_idle */
-       0x00008e04,
-       0x00eecf03,
-       0x2000e4f1,
-       0xf4f51bf4,
-       0x02f40611,
-/* 0x0855: ctx_xfer_pre */
-       0x7e100f0c,
-       0xf40006b3,
-/* 0x085e: ctx_xfer_pre_load */
-       0x020f1b11,
-       0x0006627e,
-       0x0006717e,
-       0x0006837e,
-       0x627ef4bd,
-       0xea7e0006,
-/* 0x0876: ctx_xfer_exec */
-       0x01980006,
-       0x8024bd16,
-       0xf6010500,
-       0x04bd0002,
-       0x008e1fb2,
-       0x8f7e41a5,
-       0xfcf00000,
-       0x022cf001,
-       0xfd0124b6,
-       0xffb205f2,
-       0x41a5048e,
+       0x414000b5,
+       0x13f00100,
+       0x0601fa06,
+       0x00f803f8,
+/* 0x087c: ctx_xfer */
+       0x0080040e,
+       0x0ef60302,
+/* 0x0887: ctx_xfer_idle */
+       0x8e04bd00,
+       0xcf030000,
+       0xe4f100ee,
+       0x1bf42000,
+       0x0611f4f5,
+/* 0x089b: ctx_xfer_pre */
+       0x0f0c02f4,
+       0x06f97e10,
+       0x1b11f400,
+/* 0x08a4: ctx_xfer_pre_load */
+       0xa87e020f,
+       0xb77e0006,
+       0xc97e0006,
+       0xf4bd0006,
+       0x0006a87e,
+       0x0007307e,
+/* 0x08bc: ctx_xfer_exec */
+       0xbd160198,
+       0x05008024,
+       0x0002f601,
+       0x1fb204bd,
+       0x41a5008e,
        0x00008f7e,
-       0x0002167e,
-       0xfc8024bd,
-       0x02f60247,
-       0xf004bd00,
-       0x20b6012c,
-       0x4afc8003,
-       0x0002f602,
-       0xacf004bd,
-       0x06a5f001,
-       0x0c98000b,
-       0x010d9800,
-       0x3d7e000e,
-       0x080a0001,
-       0x0000ec7e,
-       0x00020a7e,
-       0x0a1201f4,
-       0x00b87e0c,
-       0x7e050f00,
-       0xf40006d2,
-/* 0x08f2: ctx_xfer_post */
-       0x020f2d02,
-       0x0006627e,
-       0xb37ef4bd,
-       0x277e0006,
-       0x717e0002,
+       0xf001fcf0,
+       0x24b6022c,
+       0x05f2fd01,
+       0x048effb2,
+       0x8f7e41a5,
+       0x167e0000,
+       0x24bd0002,
+       0x0247fc80,
+       0xbd0002f6,
+       0x012cf004,
+       0x800320b6,
+       0xf6024afc,
+       0x04bd0002,
+       0xf001acf0,
+       0x000b06a5,
+       0x98000c98,
+       0x000e010d,
+       0x00013d7e,
+       0xec7e080a,
+       0x0a7e0000,
+       0x01f40002,
+       0x7e0c0a12,
+       0x0f0000b8,
+       0x07187e05,
+       0x2d02f400,
+/* 0x0938: ctx_xfer_post */
+       0xa87e020f,
        0xf4bd0006,
-       0x0006627e,
-       0x981011f4,
-       0x11fd4001,
-       0x070bf405,
-       0x0007e87e,
-/* 0x091c: ctx_xfer_no_post_mmio */
-/* 0x091c: ctx_xfer_done */
-       0x000000f8,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
+       0x0006f97e,
+       0x0002277e,
+       0x0006b77e,
+       0xa87ef4bd,
+       0x11f40006,
+       0x40019810,
+       0xf40511fd,
+       0x2e7e070b,
+/* 0x0962: ctx_xfer_no_post_mmio */
+/* 0x0962: ctx_xfer_done */
+       0x00f80008,
        0x00000000,
        0x00000000,
        0x00000000,
index 64dfd75..e49b5a8 100644 (file)
@@ -478,10 +478,10 @@ uint32_t nv108_grhub_code[] = {
        0x01040080,
        0xbd0001f6,
        0x01004104,
-       0x627e020f,
-       0x717e0006,
+       0xa87e020f,
+       0xb77e0006,
        0x100f0006,
-       0x0006b37e,
+       0x0006f97e,
        0x98000e98,
        0x207e010f,
        0x14950001,
@@ -523,8 +523,8 @@ uint32_t nv108_grhub_code[] = {
        0x800040b7,
        0xf40132b6,
        0x000fb41b,
-       0x0006b37e,
-       0x627e000f,
+       0x0006f97e,
+       0xa87e000f,
        0x00800006,
        0x01f60201,
        0xbd04bd00,
@@ -554,7 +554,7 @@ uint32_t nv108_grhub_code[] = {
        0x0009f602,
        0x32f404bd,
        0x0231f401,
-       0x0008367e,
+       0x00087c7e,
        0x99f094bd,
        0x17008007,
        0x0009f602,
@@ -563,7 +563,7 @@ uint32_t nv108_grhub_code[] = {
        0x37008006,
        0x0009f602,
        0x31f404bd,
-       0x08367e01,
+       0x087c7e01,
        0xf094bd00,
        0x00800699,
        0x09f60217,
@@ -572,7 +572,7 @@ uint32_t nv108_grhub_code[] = {
        0x20f92f0e,
        0x32f412b2,
        0x0232f401,
-       0x0008367e,
+       0x00087c7e,
        0x008020fc,
        0x02f602c0,
        0xf404bd00,
@@ -580,7 +580,7 @@ uint32_t nv108_grhub_code[] = {
        0x23c8130e,
        0x0d0bf41f,
        0xf40131f4,
-       0x367e0232,
+       0x7c7e0232,
 /* 0x054e: chsw_done */
        0x01020008,
        0x02c30080,
@@ -593,7 +593,7 @@ uint32_t nv108_grhub_code[] = {
        0xb0ff2a0e,
        0x1bf401e4,
        0x7ef2b20c,
-       0xf40007d6,
+       0xf400081c,
 /* 0x057a: main_not_ctx_chan */
        0xe4b0400e,
        0x2c1bf402,
@@ -602,7 +602,7 @@ uint32_t nv108_grhub_code[] = {
        0x0009f602,
        0x32f404bd,
        0x0232f401,
-       0x0008367e,
+       0x00087c7e,
        0x99f094bd,
        0x17008007,
        0x0009f602,
@@ -642,238 +642,238 @@ uint32_t nv108_grhub_code[] = {
 /* 0x061a: ih_no_ctxsw */
        0xabe40000,
        0x0bf40400,
-       0x01004b10,
-       0x448ebfb2,
-       0x8f7e4001,
-/* 0x062e: ih_no_fwmthd */
-       0x044b0000,
-       0xffb0bd01,
-       0x0bf4b4ab,
-       0x0700800c,
-       0x000bf603,
-/* 0x0642: ih_no_other */
-       0x004004bd,
-       0x000af601,
-       0xf0fc04bd,
-       0xd0fce0fc,
-       0xa0fcb0fc,
-       0x80fc90fc,
-       0xfc0088fe,
-       0x0032f480,
-/* 0x0662: ctx_4170s */
-       0xf5f001f8,
-       0x8effb210,
-       0x7e404170,
-       0xf800008f,
-/* 0x0671: ctx_4170w */
-       0x41708e00,
+       0x07088e56,
        0x00657e40,
-       0xf0ffb200,
-       0x1bf410f4,
-/* 0x0683: ctx_redswitch */
-       0x4e00f8f3,
-       0xe5f00200,
-       0x20e5f040,
-       0x8010e5f0,
-       0xf6018500,
-       0x04bd000e,
-/* 0x069a: ctx_redswitch_delay */
-       0xf2b6080f,
-       0xfd1bf401,
-       0x0400e5f1,
-       0x0100e5f1,
-       0x01850080,
-       0xbd000ef6,
-/* 0x06b3: ctx_86c */
-       0x8000f804,
-       0xf6022300,
+       0x80ffb200,
+       0xf6020400,
        0x04bd000f,
-       0x148effb2,
-       0x8f7e408a,
-       0xffb20000,
-       0x41a88c8e,
+       0x4007048e,
+       0x0000657e,
+       0x0080ffb2,
+       0x0ff60203,
+       0xc704bd00,
+       0xee9450fe,
+       0x07008f02,
+       0x00efbb40,
+       0x0000657e,
+       0x02020080,
+       0xbd000ff6,
+       0x7e030f04,
+       0x4b0002f8,
+       0xbfb20100,
+       0x4001448e,
        0x00008f7e,
-/* 0x06d2: ctx_mem */
-       0x008000f8,
-       0x0ff60284,
-/* 0x06db: ctx_mem_wait */
-       0x8f04bd00,
-       0xcf028400,
-       0xfffd00ff,
-       0xf61bf405,
-/* 0x06ea: ctx_load */
-       0x94bd00f8,
-       0x800599f0,
-       0xf6023700,
-       0x04bd0009,
-       0xb87e0c0a,
-       0xf4bd0000,
-       0x02890080,
+/* 0x0674: ih_no_fwmthd */
+       0xbd05044b,
+       0xb4abffb0,
+       0x800c0bf4,
+       0xf6030700,
+       0x04bd000b,
+/* 0x0688: ih_no_other */
+       0xf6010040,
+       0x04bd000a,
+       0xe0fcf0fc,
+       0xb0fcd0fc,
+       0x90fca0fc,
+       0x88fe80fc,
+       0xf480fc00,
+       0x01f80032,
+/* 0x06a8: ctx_4170s */
+       0xb210f5f0,
+       0x41708eff,
+       0x008f7e40,
+/* 0x06b7: ctx_4170w */
+       0x8e00f800,
+       0x7e404170,
+       0xb2000065,
+       0x10f4f0ff,
+       0xf8f31bf4,
+/* 0x06c9: ctx_redswitch */
+       0x02004e00,
+       0xf040e5f0,
+       0xe5f020e5,
+       0x85008010,
+       0x000ef601,
+       0x080f04bd,
+/* 0x06e0: ctx_redswitch_delay */
+       0xf401f2b6,
+       0xe5f1fd1b,
+       0xe5f10400,
+       0x00800100,
+       0x0ef60185,
+       0xf804bd00,
+/* 0x06f9: ctx_86c */
+       0x23008000,
+       0x000ff602,
+       0xffb204bd,
+       0x408a148e,
+       0x00008f7e,
+       0x8c8effb2,
+       0x8f7e41a8,
+       0x00f80000,
+/* 0x0718: ctx_mem */
+       0x02840080,
        0xbd000ff6,
-       0xc1008004,
-       0x0002f602,
-       0x008004bd,
-       0x02f60283,
-       0x0f04bd00,
-       0x06d27e07,
-       0xc0008000,
-       0x0002f602,
-       0x0bfe04bd,
-       0x1f2af000,
-       0xb60424b6,
-       0x94bd0220,
-       0x800899f0,
-       0xf6023700,
-       0x04bd0009,
-       0x02810080,
-       0xbd0002f6,
-       0x0000d204,
-       0x25f08000,
-       0x88008002,
-       0x0002f602,
-       0x100104bd,
-       0xf0020042,
-       0x12fa0223,
-       0xbd03f805,
-       0x0899f094,
-       0x02170080,
-       0xbd0009f6,
-       0x81019804,
-       0x981814b6,
-       0x25b68002,
-       0x0512fd08,
-       0xbd1601b5,
-       0x0999f094,
-       0x02370080,
-       0xbd0009f6,
-       0x81008004,
-       0x0001f602,
-       0x010204bd,
-       0x02880080,
+/* 0x0721: ctx_mem_wait */
+       0x84008f04,
+       0x00ffcf02,
+       0xf405fffd,
+       0x00f8f61b,
+/* 0x0730: ctx_load */
+       0x99f094bd,
+       0x37008005,
+       0x0009f602,
+       0x0c0a04bd,
+       0x0000b87e,
+       0x0080f4bd,
+       0x0ff60289,
+       0x8004bd00,
+       0xf602c100,
+       0x04bd0002,
+       0x02830080,
        0xbd0002f6,
-       0x01004104,
-       0xfa0613f0,
-       0x03f80501,
+       0x7e070f04,
+       0x80000718,
+       0xf602c000,
+       0x04bd0002,
+       0xf0000bfe,
+       0x24b61f2a,
+       0x0220b604,
        0x99f094bd,
-       0x17008009,
+       0x37008008,
        0x0009f602,
-       0x94bd04bd,
-       0x800599f0,
+       0x008004bd,
+       0x02f60281,
+       0xd204bd00,
+       0x80000000,
+       0x800225f0,
+       0xf6028800,
+       0x04bd0002,
+       0x00421001,
+       0x0223f002,
+       0xf80512fa,
+       0xf094bd03,
+       0x00800899,
+       0x09f60217,
+       0x9804bd00,
+       0x14b68101,
+       0x80029818,
+       0xfd0825b6,
+       0x01b50512,
+       0xf094bd16,
+       0x00800999,
+       0x09f60237,
+       0x8004bd00,
+       0xf6028100,
+       0x04bd0001,
+       0x00800102,
+       0x02f60288,
+       0x4104bd00,
+       0x13f00100,
+       0x0501fa06,
+       0x94bd03f8,
+       0x800999f0,
        0xf6021700,
        0x04bd0009,
-/* 0x07d6: ctx_chan */
-       0xea7e00f8,
-       0x0c0a0006,
-       0x0000b87e,
-       0xd27e050f,
-       0x00f80006,
-/* 0x07e8: ctx_mmio_exec */
-       0x80410398,
+       0x99f094bd,
+       0x17008005,
+       0x0009f602,
+       0x00f804bd,
+/* 0x081c: ctx_chan */
+       0x0007307e,
+       0xb87e0c0a,
+       0x050f0000,
+       0x0007187e,
+/* 0x082e: ctx_mmio_exec */
+       0x039800f8,
+       0x81008041,
+       0x0003f602,
+       0x34bd04bd,
+/* 0x083c: ctx_mmio_loop */
+       0xf4ff34c4,
+       0x00450e1b,
+       0x0653f002,
+       0xf80535fa,
+/* 0x084d: ctx_mmio_pull */
+       0x804e9803,
+       0x7e814f98,
+       0xb600008f,
+       0x12b60830,
+       0xdf1bf401,
+/* 0x0860: ctx_mmio_done */
+       0x80160398,
        0xf6028100,
        0x04bd0003,
-/* 0x07f6: ctx_mmio_loop */
-       0x34c434bd,
-       0x0e1bf4ff,
-       0xf0020045,
-       0x35fa0653,
-/* 0x0807: ctx_mmio_pull */
-       0x9803f805,
-       0x4f98804e,
-       0x008f7e81,
-       0x0830b600,
-       0xf40112b6,
-/* 0x081a: ctx_mmio_done */
-       0x0398df1b,
-       0x81008016,
-       0x0003f602,
-       0x00b504bd,
-       0x01004140,
-       0xfa0613f0,
-       0x03f80601,
-/* 0x0836: ctx_xfer */
-       0x040e00f8,
-       0x03020080,
-       0xbd000ef6,
-/* 0x0841: ctx_xfer_idle */
-       0x00008e04,
-       0x00eecf03,
-       0x2000e4f1,
-       0xf4f51bf4,
-       0x02f40611,
-/* 0x0855: ctx_xfer_pre */
-       0x7e100f0c,
-       0xf40006b3,
-/* 0x085e: ctx_xfer_pre_load */
-       0x020f1b11,
-       0x0006627e,
-       0x0006717e,
-       0x0006837e,
-       0x627ef4bd,
-       0xea7e0006,
-/* 0x0876: ctx_xfer_exec */
-       0x01980006,
-       0x8024bd16,
-       0xf6010500,
-       0x04bd0002,
-       0x008e1fb2,
-       0x8f7e41a5,
-       0xfcf00000,
-       0x022cf001,
-       0xfd0124b6,
-       0xffb205f2,
-       0x41a5048e,
+       0x414000b5,
+       0x13f00100,
+       0x0601fa06,
+       0x00f803f8,
+/* 0x087c: ctx_xfer */
+       0x0080040e,
+       0x0ef60302,
+/* 0x0887: ctx_xfer_idle */
+       0x8e04bd00,
+       0xcf030000,
+       0xe4f100ee,
+       0x1bf42000,
+       0x0611f4f5,
+/* 0x089b: ctx_xfer_pre */
+       0x0f0c02f4,
+       0x06f97e10,
+       0x1b11f400,
+/* 0x08a4: ctx_xfer_pre_load */
+       0xa87e020f,
+       0xb77e0006,
+       0xc97e0006,
+       0xf4bd0006,
+       0x0006a87e,
+       0x0007307e,
+/* 0x08bc: ctx_xfer_exec */
+       0xbd160198,
+       0x05008024,
+       0x0002f601,
+       0x1fb204bd,
+       0x41a5008e,
        0x00008f7e,
-       0x0002167e,
-       0xfc8024bd,
-       0x02f60247,
-       0xf004bd00,
-       0x20b6012c,
-       0x4afc8003,
-       0x0002f602,
-       0xacf004bd,
-       0x06a5f001,
-       0x0c98000b,
-       0x010d9800,
-       0x3d7e000e,
-       0x080a0001,
-       0x0000ec7e,
-       0x00020a7e,
-       0x0a1201f4,
-       0x00b87e0c,
-       0x7e050f00,
-       0xf40006d2,
-/* 0x08f2: ctx_xfer_post */
-       0x020f2d02,
-       0x0006627e,
-       0xb37ef4bd,
-       0x277e0006,
-       0x717e0002,
+       0xf001fcf0,
+       0x24b6022c,
+       0x05f2fd01,
+       0x048effb2,
+       0x8f7e41a5,
+       0x167e0000,
+       0x24bd0002,
+       0x0247fc80,
+       0xbd0002f6,
+       0x012cf004,
+       0x800320b6,
+       0xf6024afc,
+       0x04bd0002,
+       0xf001acf0,
+       0x000b06a5,
+       0x98000c98,
+       0x000e010d,
+       0x00013d7e,
+       0xec7e080a,
+       0x0a7e0000,
+       0x01f40002,
+       0x7e0c0a12,
+       0x0f0000b8,
+       0x07187e05,
+       0x2d02f400,
+/* 0x0938: ctx_xfer_post */
+       0xa87e020f,
        0xf4bd0006,
-       0x0006627e,
-       0x981011f4,
-       0x11fd4001,
-       0x070bf405,
-       0x0007e87e,
-/* 0x091c: ctx_xfer_no_post_mmio */
-/* 0x091c: ctx_xfer_done */
-       0x000000f8,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
-       0x00000000,
+       0x0006f97e,
+       0x0002277e,
+       0x0006b77e,
+       0xa87ef4bd,
+       0x11f40006,
+       0x40019810,
+       0xf40511fd,
+       0x2e7e070b,
+/* 0x0962: ctx_xfer_no_post_mmio */
+/* 0x0962: ctx_xfer_done */
+       0x00f80008,
        0x00000000,
        0x00000000,
        0x00000000,
index f8f7b27..92dfe6a 100644 (file)
@@ -528,10 +528,10 @@ uint32_t nvc0_grhub_code[] = {
        0x0001d001,
        0x17f104bd,
        0xf7f00100,
-       0xb521f502,
-       0xc721f507,
-       0x10f7f007,
-       0x081421f5,
+       0x0d21f502,
+       0x1f21f508,
+       0x10f7f008,
+       0x086c21f5,
        0x98000e98,
        0x21f5010f,
        0x14950150,
@@ -574,9 +574,9 @@ uint32_t nvc0_grhub_code[] = {
        0xb6800040,
        0x1bf40132,
        0x00f7f0be,
-       0x081421f5,
+       0x086c21f5,
        0xf500f7f0,
-       0xf107b521,
+       0xf1080d21,
        0xf0010007,
        0x01d00203,
        0xbd04bd00,
@@ -610,8 +610,8 @@ uint32_t nvc0_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x31f40132,
-       0xe821f502,
-       0xf094bd09,
+       0x4021f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -621,7 +621,7 @@ uint32_t nvc0_grhub_code[] = {
        0x0203f00f,
        0xbd0009d0,
        0x0131f404,
-       0x09e821f5,
+       0x0a4021f5,
        0x99f094bd,
        0x0007f106,
        0x0203f017,
@@ -631,7 +631,7 @@ uint32_t nvc0_grhub_code[] = {
        0x12b920f9,
        0x0132f402,
        0xf50232f4,
-       0xfc09e821,
+       0xfc0a4021,
        0x0007f120,
        0x0203f0c0,
        0xbd0002d0,
@@ -640,7 +640,7 @@ uint32_t nvc0_grhub_code[] = {
        0xf41f23c8,
        0x31f40d0b,
        0x0232f401,
-       0x09e821f5,
+       0x0a4021f5,
 /* 0x063c: chsw_done */
        0xf10127f0,
        0xf0c30007,
@@ -654,7 +654,7 @@ uint32_t nvc0_grhub_code[] = {
 /* 0x0660: main_not_ctx_switch */
        0xf401e4b0,
        0xf2b90d1b,
-       0x7821f502,
+       0xd021f502,
        0x460ef409,
 /* 0x0670: main_not_ctx_chan */
        0xf402e4b0,
@@ -664,8 +664,8 @@ uint32_t nvc0_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x32f40132,
-       0xe821f502,
-       0xf094bd09,
+       0x4021f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -710,18 +710,40 @@ uint32_t nvc0_grhub_code[] = {
 /* 0x072b: ih_no_ctxsw */
        0xe40421f4,
        0xf40400ab,
-       0xb7f1140b,
+       0xe7f16c0b,
+       0xe3f00708,
+       0x6821f440,
+       0xf102ffb9,
+       0xf0040007,
+       0x0fd00203,
+       0xf104bd00,
+       0xf00704e7,
+       0x21f440e3,
+       0x02ffb968,
+       0x030007f1,
+       0xd00203f0,
+       0x04bd000f,
+       0x9450fec7,
+       0xf7f102ee,
+       0xf3f00700,
+       0x00efbb40,
+       0xf16821f4,
+       0xf0020007,
+       0x0fd00203,
+       0xf004bd00,
+       0x21f503f7,
+       0xb7f1037e,
        0xbfb90100,
        0x44e7f102,
        0x40e3f001,
-/* 0x0743: ih_no_fwmthd */
+/* 0x079b: ih_no_fwmthd */
        0xf19d21f4,
-       0xbd0104b7,
+       0xbd0504b7,
        0xb4abffb0,
        0xf10f0bf4,
        0xf0070007,
        0x0bd00303,
-/* 0x075b: ih_no_other */
+/* 0x07b3: ih_no_other */
        0xf104bd00,
        0xf0010007,
        0x0ad00003,
@@ -731,36 +753,36 @@ uint32_t nvc0_grhub_code[] = {
        0xfc90fca0,
        0x0088fe80,
        0x32f480fc,
-/* 0x077f: ctx_4160s */
+/* 0x07d7: ctx_4160s */
        0xf001f800,
        0xffb901f7,
        0x60e7f102,
        0x40e3f041,
-/* 0x078f: ctx_4160s_wait */
+/* 0x07e7: ctx_4160s_wait */
        0xf19d21f4,
        0xf04160e7,
        0x21f440e3,
        0x02ffb968,
        0xf404ffc8,
        0x00f8f00b,
-/* 0x07a4: ctx_4160c */
+/* 0x07fc: ctx_4160c */
        0xffb9f4bd,
        0x60e7f102,
        0x40e3f041,
        0xf89d21f4,
-/* 0x07b5: ctx_4170s */
+/* 0x080d: ctx_4170s */
        0x10f5f000,
        0xf102ffb9,
        0xf04170e7,
        0x21f440e3,
-/* 0x07c7: ctx_4170w */
+/* 0x081f: ctx_4170w */
        0xf100f89d,
        0xf04170e7,
        0x21f440e3,
        0x02ffb968,
        0xf410f4f0,
        0x00f8f01b,
-/* 0x07dc: ctx_redswitch */
+/* 0x0834: ctx_redswitch */
        0x0200e7f1,
        0xf040e5f0,
        0xe5f020e5,
@@ -768,7 +790,7 @@ uint32_t nvc0_grhub_code[] = {
        0x0103f085,
        0xbd000ed0,
        0x08f7f004,
-/* 0x07f8: ctx_redswitch_delay */
+/* 0x0850: ctx_redswitch_delay */
        0xf401f2b6,
        0xe5f1fd1b,
        0xe5f10400,
@@ -776,7 +798,7 @@ uint32_t nvc0_grhub_code[] = {
        0x03f08500,
        0x000ed001,
        0x00f804bd,
-/* 0x0814: ctx_86c */
+/* 0x086c: ctx_86c */
        0x1b0007f1,
        0xd00203f0,
        0x04bd000f,
@@ -787,16 +809,16 @@ uint32_t nvc0_grhub_code[] = {
        0xa86ce7f1,
        0xf441e3f0,
        0x00f89d21,
-/* 0x083c: ctx_mem */
+/* 0x0894: ctx_mem */
        0x840007f1,
        0xd00203f0,
        0x04bd000f,
-/* 0x0848: ctx_mem_wait */
+/* 0x08a0: ctx_mem_wait */
        0x8400f7f1,
        0xcf02f3f0,
        0xfffd00ff,
        0xf31bf405,
-/* 0x085a: ctx_load */
+/* 0x08b2: ctx_load */
        0x94bd00f8,
        0xf10599f0,
        0xf00f0007,
@@ -814,7 +836,7 @@ uint32_t nvc0_grhub_code[] = {
        0x02d00203,
        0xf004bd00,
        0x21f507f7,
-       0x07f1083c,
+       0x07f10894,
        0x03f0c000,
        0x0002d002,
        0x0bfe04bd,
@@ -869,31 +891,31 @@ uint32_t nvc0_grhub_code[] = {
        0x03f01700,
        0x0009d002,
        0x00f804bd,
-/* 0x0978: ctx_chan */
-       0x077f21f5,
-       0x085a21f5,
+/* 0x09d0: ctx_chan */
+       0x07d721f5,
+       0x08b221f5,
        0xf40ca7f0,
        0xf7f0d021,
-       0x3c21f505,
-       0xa421f508,
-/* 0x0993: ctx_mmio_exec */
+       0x9421f505,
+       0xfc21f508,
+/* 0x09eb: ctx_mmio_exec */
        0x9800f807,
        0x07f14103,
        0x03f08100,
        0x0003d002,
        0x34bd04bd,
-/* 0x09a4: ctx_mmio_loop */
+/* 0x09fc: ctx_mmio_loop */
        0xf4ff34c4,
        0x57f10f1b,
        0x53f00200,
        0x0535fa06,
-/* 0x09b6: ctx_mmio_pull */
+/* 0x0a0e: ctx_mmio_pull */
        0x4e9803f8,
        0x814f9880,
        0xb69d21f4,
        0x12b60830,
        0xdf1bf401,
-/* 0x09c8: ctx_mmio_done */
+/* 0x0a20: ctx_mmio_done */
        0xf1160398,
        0xf0810007,
        0x03d00203,
@@ -902,30 +924,30 @@ uint32_t nvc0_grhub_code[] = {
        0x13f00100,
        0x0601fa06,
        0x00f803f8,
-/* 0x09e8: ctx_xfer */
+/* 0x0a40: ctx_xfer */
        0xf104e7f0,
        0xf0020007,
        0x0ed00303,
-/* 0x09f7: ctx_xfer_idle */
+/* 0x0a4f: ctx_xfer_idle */
        0xf104bd00,
        0xf00000e7,
        0xeecf03e3,
        0x00e4f100,
        0xf21bf420,
        0xf40611f4,
-/* 0x0a0e: ctx_xfer_pre */
+/* 0x0a66: ctx_xfer_pre */
        0xf7f01102,
-       0x1421f510,
-       0x7f21f508,
+       0x6c21f510,
+       0xd721f508,
        0x1c11f407,
-/* 0x0a1c: ctx_xfer_pre_load */
+/* 0x0a74: ctx_xfer_pre_load */
        0xf502f7f0,
-       0xf507b521,
-       0xf507c721,
-       0xbd07dc21,
-       0xb521f5f4,
-       0x5a21f507,
-/* 0x0a35: ctx_xfer_exec */
+       0xf5080d21,
+       0xf5081f21,
+       0xbd083421,
+       0x0d21f5f4,
+       0xb221f508,
+/* 0x0a8d: ctx_xfer_exec */
        0x16019808,
        0x07f124bd,
        0x03f00500,
@@ -960,23 +982,65 @@ uint32_t nvc0_grhub_code[] = {
        0x1301f402,
        0xf40ca7f0,
        0xf7f0d021,
-       0x3c21f505,
+       0x9421f505,
        0x3202f408,
-/* 0x0ac4: ctx_xfer_post */
+/* 0x0b1c: ctx_xfer_post */
        0xf502f7f0,
-       0xbd07b521,
-       0x1421f5f4,
+       0xbd080d21,
+       0x6c21f5f4,
        0x7f21f508,
-       0xc721f502,
-       0xf5f4bd07,
-       0xf407b521,
+       0x1f21f502,
+       0xf5f4bd08,
+       0xf4080d21,
        0x01981011,
        0x0511fd40,
        0xf5070bf4,
-/* 0x0aef: ctx_xfer_no_post_mmio */
-       0xf5099321,
-/* 0x0af3: ctx_xfer_done */
-       0xf807a421,
+/* 0x0b47: ctx_xfer_no_post_mmio */
+       0xf509eb21,
+/* 0x0b4b: ctx_xfer_done */
+       0xf807fc21,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
        0x00000000,
        0x00000000,
        0x00000000,
index 624215a..62b0c76 100644 (file)
@@ -528,10 +528,10 @@ uint32_t nvd7_grhub_code[] = {
        0x0001d001,
        0x17f104bd,
        0xf7f00100,
-       0xb521f502,
-       0xc721f507,
-       0x10f7f007,
-       0x081421f5,
+       0x0d21f502,
+       0x1f21f508,
+       0x10f7f008,
+       0x086c21f5,
        0x98000e98,
        0x21f5010f,
        0x14950150,
@@ -574,9 +574,9 @@ uint32_t nvd7_grhub_code[] = {
        0xb6800040,
        0x1bf40132,
        0x00f7f0be,
-       0x081421f5,
+       0x086c21f5,
        0xf500f7f0,
-       0xf107b521,
+       0xf1080d21,
        0xf0010007,
        0x01d00203,
        0xbd04bd00,
@@ -610,8 +610,8 @@ uint32_t nvd7_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x31f40132,
-       0xe821f502,
-       0xf094bd09,
+       0x4021f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -621,7 +621,7 @@ uint32_t nvd7_grhub_code[] = {
        0x0203f00f,
        0xbd0009d0,
        0x0131f404,
-       0x09e821f5,
+       0x0a4021f5,
        0x99f094bd,
        0x0007f106,
        0x0203f017,
@@ -631,7 +631,7 @@ uint32_t nvd7_grhub_code[] = {
        0x12b920f9,
        0x0132f402,
        0xf50232f4,
-       0xfc09e821,
+       0xfc0a4021,
        0x0007f120,
        0x0203f0c0,
        0xbd0002d0,
@@ -640,7 +640,7 @@ uint32_t nvd7_grhub_code[] = {
        0xf41f23c8,
        0x31f40d0b,
        0x0232f401,
-       0x09e821f5,
+       0x0a4021f5,
 /* 0x063c: chsw_done */
        0xf10127f0,
        0xf0c30007,
@@ -654,7 +654,7 @@ uint32_t nvd7_grhub_code[] = {
 /* 0x0660: main_not_ctx_switch */
        0xf401e4b0,
        0xf2b90d1b,
-       0x7821f502,
+       0xd021f502,
        0x460ef409,
 /* 0x0670: main_not_ctx_chan */
        0xf402e4b0,
@@ -664,8 +664,8 @@ uint32_t nvd7_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x32f40132,
-       0xe821f502,
-       0xf094bd09,
+       0x4021f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -710,18 +710,40 @@ uint32_t nvd7_grhub_code[] = {
 /* 0x072b: ih_no_ctxsw */
        0xe40421f4,
        0xf40400ab,
-       0xb7f1140b,
+       0xe7f16c0b,
+       0xe3f00708,
+       0x6821f440,
+       0xf102ffb9,
+       0xf0040007,
+       0x0fd00203,
+       0xf104bd00,
+       0xf00704e7,
+       0x21f440e3,
+       0x02ffb968,
+       0x030007f1,
+       0xd00203f0,
+       0x04bd000f,
+       0x9450fec7,
+       0xf7f102ee,
+       0xf3f00700,
+       0x00efbb40,
+       0xf16821f4,
+       0xf0020007,
+       0x0fd00203,
+       0xf004bd00,
+       0x21f503f7,
+       0xb7f1037e,
        0xbfb90100,
        0x44e7f102,
        0x40e3f001,
-/* 0x0743: ih_no_fwmthd */
+/* 0x079b: ih_no_fwmthd */
        0xf19d21f4,
-       0xbd0104b7,
+       0xbd0504b7,
        0xb4abffb0,
        0xf10f0bf4,
        0xf0070007,
        0x0bd00303,
-/* 0x075b: ih_no_other */
+/* 0x07b3: ih_no_other */
        0xf104bd00,
        0xf0010007,
        0x0ad00003,
@@ -731,36 +753,36 @@ uint32_t nvd7_grhub_code[] = {
        0xfc90fca0,
        0x0088fe80,
        0x32f480fc,
-/* 0x077f: ctx_4160s */
+/* 0x07d7: ctx_4160s */
        0xf001f800,
        0xffb901f7,
        0x60e7f102,
        0x40e3f041,
-/* 0x078f: ctx_4160s_wait */
+/* 0x07e7: ctx_4160s_wait */
        0xf19d21f4,
        0xf04160e7,
        0x21f440e3,
        0x02ffb968,
        0xf404ffc8,
        0x00f8f00b,
-/* 0x07a4: ctx_4160c */
+/* 0x07fc: ctx_4160c */
        0xffb9f4bd,
        0x60e7f102,
        0x40e3f041,
        0xf89d21f4,
-/* 0x07b5: ctx_4170s */
+/* 0x080d: ctx_4170s */
        0x10f5f000,
        0xf102ffb9,
        0xf04170e7,
        0x21f440e3,
-/* 0x07c7: ctx_4170w */
+/* 0x081f: ctx_4170w */
        0xf100f89d,
        0xf04170e7,
        0x21f440e3,
        0x02ffb968,
        0xf410f4f0,
        0x00f8f01b,
-/* 0x07dc: ctx_redswitch */
+/* 0x0834: ctx_redswitch */
        0x0200e7f1,
        0xf040e5f0,
        0xe5f020e5,
@@ -768,7 +790,7 @@ uint32_t nvd7_grhub_code[] = {
        0x0103f085,
        0xbd000ed0,
        0x08f7f004,
-/* 0x07f8: ctx_redswitch_delay */
+/* 0x0850: ctx_redswitch_delay */
        0xf401f2b6,
        0xe5f1fd1b,
        0xe5f10400,
@@ -776,7 +798,7 @@ uint32_t nvd7_grhub_code[] = {
        0x03f08500,
        0x000ed001,
        0x00f804bd,
-/* 0x0814: ctx_86c */
+/* 0x086c: ctx_86c */
        0x1b0007f1,
        0xd00203f0,
        0x04bd000f,
@@ -787,16 +809,16 @@ uint32_t nvd7_grhub_code[] = {
        0xa86ce7f1,
        0xf441e3f0,
        0x00f89d21,
-/* 0x083c: ctx_mem */
+/* 0x0894: ctx_mem */
        0x840007f1,
        0xd00203f0,
        0x04bd000f,
-/* 0x0848: ctx_mem_wait */
+/* 0x08a0: ctx_mem_wait */
        0x8400f7f1,
        0xcf02f3f0,
        0xfffd00ff,
        0xf31bf405,
-/* 0x085a: ctx_load */
+/* 0x08b2: ctx_load */
        0x94bd00f8,
        0xf10599f0,
        0xf00f0007,
@@ -814,7 +836,7 @@ uint32_t nvd7_grhub_code[] = {
        0x02d00203,
        0xf004bd00,
        0x21f507f7,
-       0x07f1083c,
+       0x07f10894,
        0x03f0c000,
        0x0002d002,
        0x0bfe04bd,
@@ -869,31 +891,31 @@ uint32_t nvd7_grhub_code[] = {
        0x03f01700,
        0x0009d002,
        0x00f804bd,
-/* 0x0978: ctx_chan */
-       0x077f21f5,
-       0x085a21f5,
+/* 0x09d0: ctx_chan */
+       0x07d721f5,
+       0x08b221f5,
        0xf40ca7f0,
        0xf7f0d021,
-       0x3c21f505,
-       0xa421f508,
-/* 0x0993: ctx_mmio_exec */
+       0x9421f505,
+       0xfc21f508,
+/* 0x09eb: ctx_mmio_exec */
        0x9800f807,
        0x07f14103,
        0x03f08100,
        0x0003d002,
        0x34bd04bd,
-/* 0x09a4: ctx_mmio_loop */
+/* 0x09fc: ctx_mmio_loop */
        0xf4ff34c4,
        0x57f10f1b,
        0x53f00200,
        0x0535fa06,
-/* 0x09b6: ctx_mmio_pull */
+/* 0x0a0e: ctx_mmio_pull */
        0x4e9803f8,
        0x814f9880,
        0xb69d21f4,
        0x12b60830,
        0xdf1bf401,
-/* 0x09c8: ctx_mmio_done */
+/* 0x0a20: ctx_mmio_done */
        0xf1160398,
        0xf0810007,
        0x03d00203,
@@ -902,30 +924,30 @@ uint32_t nvd7_grhub_code[] = {
        0x13f00100,
        0x0601fa06,
        0x00f803f8,
-/* 0x09e8: ctx_xfer */
+/* 0x0a40: ctx_xfer */
        0xf104e7f0,
        0xf0020007,
        0x0ed00303,
-/* 0x09f7: ctx_xfer_idle */
+/* 0x0a4f: ctx_xfer_idle */
        0xf104bd00,
        0xf00000e7,
        0xeecf03e3,
        0x00e4f100,
        0xf21bf420,
        0xf40611f4,
-/* 0x0a0e: ctx_xfer_pre */
+/* 0x0a66: ctx_xfer_pre */
        0xf7f01102,
-       0x1421f510,
-       0x7f21f508,
+       0x6c21f510,
+       0xd721f508,
        0x1c11f407,
-/* 0x0a1c: ctx_xfer_pre_load */
+/* 0x0a74: ctx_xfer_pre_load */
        0xf502f7f0,
-       0xf507b521,
-       0xf507c721,
-       0xbd07dc21,
-       0xb521f5f4,
-       0x5a21f507,
-/* 0x0a35: ctx_xfer_exec */
+       0xf5080d21,
+       0xf5081f21,
+       0xbd083421,
+       0x0d21f5f4,
+       0xb221f508,
+/* 0x0a8d: ctx_xfer_exec */
        0x16019808,
        0x07f124bd,
        0x03f00500,
@@ -960,23 +982,65 @@ uint32_t nvd7_grhub_code[] = {
        0x1301f402,
        0xf40ca7f0,
        0xf7f0d021,
-       0x3c21f505,
+       0x9421f505,
        0x3202f408,
-/* 0x0ac4: ctx_xfer_post */
+/* 0x0b1c: ctx_xfer_post */
        0xf502f7f0,
-       0xbd07b521,
-       0x1421f5f4,
+       0xbd080d21,
+       0x6c21f5f4,
        0x7f21f508,
-       0xc721f502,
-       0xf5f4bd07,
-       0xf407b521,
+       0x1f21f502,
+       0xf5f4bd08,
+       0xf4080d21,
        0x01981011,
        0x0511fd40,
        0xf5070bf4,
-/* 0x0aef: ctx_xfer_no_post_mmio */
-       0xf5099321,
-/* 0x0af3: ctx_xfer_done */
-       0xf807a421,
+/* 0x0b47: ctx_xfer_no_post_mmio */
+       0xf509eb21,
+/* 0x0b4b: ctx_xfer_done */
+       0xf807fc21,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
        0x00000000,
        0x00000000,
        0x00000000,
index 6547b3d..51c3797 100644 (file)
@@ -528,10 +528,10 @@ uint32_t nve0_grhub_code[] = {
        0x0001d001,
        0x17f104bd,
        0xf7f00100,
-       0x7f21f502,
-       0x9121f507,
+       0xd721f502,
+       0xe921f507,
        0x10f7f007,
-       0x07de21f5,
+       0x083621f5,
        0x98000e98,
        0x21f5010f,
        0x14950150,
@@ -574,9 +574,9 @@ uint32_t nve0_grhub_code[] = {
        0xb6800040,
        0x1bf40132,
        0x00f7f0be,
-       0x07de21f5,
+       0x083621f5,
        0xf500f7f0,
-       0xf1077f21,
+       0xf107d721,
        0xf0010007,
        0x01d00203,
        0xbd04bd00,
@@ -610,8 +610,8 @@ uint32_t nve0_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x31f40132,
-       0xaa21f502,
-       0xf094bd09,
+       0x0221f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -621,7 +621,7 @@ uint32_t nve0_grhub_code[] = {
        0x0203f00f,
        0xbd0009d0,
        0x0131f404,
-       0x09aa21f5,
+       0x0a0221f5,
        0x99f094bd,
        0x0007f106,
        0x0203f017,
@@ -631,7 +631,7 @@ uint32_t nve0_grhub_code[] = {
        0x12b920f9,
        0x0132f402,
        0xf50232f4,
-       0xfc09aa21,
+       0xfc0a0221,
        0x0007f120,
        0x0203f0c0,
        0xbd0002d0,
@@ -640,7 +640,7 @@ uint32_t nve0_grhub_code[] = {
        0xf41f23c8,
        0x31f40d0b,
        0x0232f401,
-       0x09aa21f5,
+       0x0a0221f5,
 /* 0x063c: chsw_done */
        0xf10127f0,
        0xf0c30007,
@@ -654,7 +654,7 @@ uint32_t nve0_grhub_code[] = {
 /* 0x0660: main_not_ctx_switch */
        0xf401e4b0,
        0xf2b90d1b,
-       0x4221f502,
+       0x9a21f502,
        0x460ef409,
 /* 0x0670: main_not_ctx_chan */
        0xf402e4b0,
@@ -664,8 +664,8 @@ uint32_t nve0_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x32f40132,
-       0xaa21f502,
-       0xf094bd09,
+       0x0221f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -710,18 +710,40 @@ uint32_t nve0_grhub_code[] = {
 /* 0x072b: ih_no_ctxsw */
        0xe40421f4,
        0xf40400ab,
-       0xb7f1140b,
+       0xe7f16c0b,
+       0xe3f00708,
+       0x6821f440,
+       0xf102ffb9,
+       0xf0040007,
+       0x0fd00203,
+       0xf104bd00,
+       0xf00704e7,
+       0x21f440e3,
+       0x02ffb968,
+       0x030007f1,
+       0xd00203f0,
+       0x04bd000f,
+       0x9450fec7,
+       0xf7f102ee,
+       0xf3f00700,
+       0x00efbb40,
+       0xf16821f4,
+       0xf0020007,
+       0x0fd00203,
+       0xf004bd00,
+       0x21f503f7,
+       0xb7f1037e,
        0xbfb90100,
        0x44e7f102,
        0x40e3f001,
-/* 0x0743: ih_no_fwmthd */
+/* 0x079b: ih_no_fwmthd */
        0xf19d21f4,
-       0xbd0104b7,
+       0xbd0504b7,
        0xb4abffb0,
        0xf10f0bf4,
        0xf0070007,
        0x0bd00303,
-/* 0x075b: ih_no_other */
+/* 0x07b3: ih_no_other */
        0xf104bd00,
        0xf0010007,
        0x0ad00003,
@@ -731,19 +753,19 @@ uint32_t nve0_grhub_code[] = {
        0xfc90fca0,
        0x0088fe80,
        0x32f480fc,
-/* 0x077f: ctx_4170s */
+/* 0x07d7: ctx_4170s */
        0xf001f800,
        0xffb910f5,
        0x70e7f102,
        0x40e3f041,
        0xf89d21f4,
-/* 0x0791: ctx_4170w */
+/* 0x07e9: ctx_4170w */
        0x70e7f100,
        0x40e3f041,
        0xb96821f4,
        0xf4f002ff,
        0xf01bf410,
-/* 0x07a6: ctx_redswitch */
+/* 0x07fe: ctx_redswitch */
        0xe7f100f8,
        0xe5f00200,
        0x20e5f040,
@@ -751,7 +773,7 @@ uint32_t nve0_grhub_code[] = {
        0xf0850007,
        0x0ed00103,
        0xf004bd00,
-/* 0x07c2: ctx_redswitch_delay */
+/* 0x081a: ctx_redswitch_delay */
        0xf2b608f7,
        0xfd1bf401,
        0x0400e5f1,
@@ -759,7 +781,7 @@ uint32_t nve0_grhub_code[] = {
        0x850007f1,
        0xd00103f0,
        0x04bd000e,
-/* 0x07de: ctx_86c */
+/* 0x0836: ctx_86c */
        0x07f100f8,
        0x03f01b00,
        0x000fd002,
@@ -770,17 +792,17 @@ uint32_t nve0_grhub_code[] = {
        0xe7f102ff,
        0xe3f0a86c,
        0x9d21f441,
-/* 0x0806: ctx_mem */
+/* 0x085e: ctx_mem */
        0x07f100f8,
        0x03f08400,
        0x000fd002,
-/* 0x0812: ctx_mem_wait */
+/* 0x086a: ctx_mem_wait */
        0xf7f104bd,
        0xf3f08400,
        0x00ffcf02,
        0xf405fffd,
        0x00f8f31b,
-/* 0x0824: ctx_load */
+/* 0x087c: ctx_load */
        0x99f094bd,
        0x0007f105,
        0x0203f00f,
@@ -797,7 +819,7 @@ uint32_t nve0_grhub_code[] = {
        0x0203f083,
        0xbd0002d0,
        0x07f7f004,
-       0x080621f5,
+       0x085e21f5,
        0xc00007f1,
        0xd00203f0,
        0x04bd0002,
@@ -852,29 +874,29 @@ uint32_t nve0_grhub_code[] = {
        0x170007f1,
        0xd00203f0,
        0x04bd0009,
-/* 0x0942: ctx_chan */
+/* 0x099a: ctx_chan */
        0x21f500f8,
-       0xa7f00824,
+       0xa7f0087c,
        0xd021f40c,
        0xf505f7f0,
-       0xf8080621,
-/* 0x0955: ctx_mmio_exec */
+       0xf8085e21,
+/* 0x09ad: ctx_mmio_exec */
        0x41039800,
        0x810007f1,
        0xd00203f0,
        0x04bd0003,
-/* 0x0966: ctx_mmio_loop */
+/* 0x09be: ctx_mmio_loop */
        0x34c434bd,
        0x0f1bf4ff,
        0x020057f1,
        0xfa0653f0,
        0x03f80535,
-/* 0x0978: ctx_mmio_pull */
+/* 0x09d0: ctx_mmio_pull */
        0x98804e98,
        0x21f4814f,
        0x0830b69d,
        0xf40112b6,
-/* 0x098a: ctx_mmio_done */
+/* 0x09e2: ctx_mmio_done */
        0x0398df1b,
        0x0007f116,
        0x0203f081,
@@ -883,30 +905,30 @@ uint32_t nve0_grhub_code[] = {
        0x010017f1,
        0xfa0613f0,
        0x03f80601,
-/* 0x09aa: ctx_xfer */
+/* 0x0a02: ctx_xfer */
        0xe7f000f8,
        0x0007f104,
        0x0303f002,
        0xbd000ed0,
-/* 0x09b9: ctx_xfer_idle */
+/* 0x0a11: ctx_xfer_idle */
        0x00e7f104,
        0x03e3f000,
        0xf100eecf,
        0xf42000e4,
        0x11f4f21b,
        0x0d02f406,
-/* 0x09d0: ctx_xfer_pre */
+/* 0x0a28: ctx_xfer_pre */
        0xf510f7f0,
-       0xf407de21,
-/* 0x09da: ctx_xfer_pre_load */
+       0xf4083621,
+/* 0x0a32: ctx_xfer_pre_load */
        0xf7f01c11,
-       0x7f21f502,
-       0x9121f507,
-       0xa621f507,
+       0xd721f502,
+       0xe921f507,
+       0xfe21f507,
        0xf5f4bd07,
-       0xf5077f21,
-/* 0x09f3: ctx_xfer_exec */
-       0x98082421,
+       0xf507d721,
+/* 0x0a4b: ctx_xfer_exec */
+       0x98087c21,
        0x24bd1601,
        0x050007f1,
        0xd00103f0,
@@ -941,21 +963,21 @@ uint32_t nve0_grhub_code[] = {
        0xa7f01301,
        0xd021f40c,
        0xf505f7f0,
-       0xf4080621,
-/* 0x0a82: ctx_xfer_post */
+       0xf4085e21,
+/* 0x0ada: ctx_xfer_post */
        0xf7f02e02,
-       0x7f21f502,
+       0xd721f502,
        0xf5f4bd07,
-       0xf507de21,
+       0xf5083621,
        0xf5027f21,
-       0xbd079121,
-       0x7f21f5f4,
+       0xbd07e921,
+       0xd721f5f4,
        0x1011f407,
        0xfd400198,
        0x0bf40511,
-       0x5521f507,
-/* 0x0aad: ctx_xfer_no_post_mmio */
-/* 0x0aad: ctx_xfer_done */
+       0xad21f507,
+/* 0x0b05: ctx_xfer_no_post_mmio */
+/* 0x0b05: ctx_xfer_done */
        0x0000f809,
        0x00000000,
        0x00000000,
@@ -977,4 +999,46 @@ uint32_t nve0_grhub_code[] = {
        0x00000000,
        0x00000000,
        0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
 };
index a5aee5a..a0af4b7 100644 (file)
@@ -528,10 +528,10 @@ uint32_t nvf0_grhub_code[] = {
        0x0001d001,
        0x17f104bd,
        0xf7f00100,
-       0x7f21f502,
-       0x9121f507,
+       0xd721f502,
+       0xe921f507,
        0x10f7f007,
-       0x07de21f5,
+       0x083621f5,
        0x98000e98,
        0x21f5010f,
        0x14950150,
@@ -574,9 +574,9 @@ uint32_t nvf0_grhub_code[] = {
        0xb6800040,
        0x1bf40132,
        0x00f7f0be,
-       0x07de21f5,
+       0x083621f5,
        0xf500f7f0,
-       0xf1077f21,
+       0xf107d721,
        0xf0010007,
        0x01d00203,
        0xbd04bd00,
@@ -610,8 +610,8 @@ uint32_t nvf0_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x31f40132,
-       0xaa21f502,
-       0xf094bd09,
+       0x0221f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -621,7 +621,7 @@ uint32_t nvf0_grhub_code[] = {
        0x0203f037,
        0xbd0009d0,
        0x0131f404,
-       0x09aa21f5,
+       0x0a0221f5,
        0x99f094bd,
        0x0007f106,
        0x0203f017,
@@ -631,7 +631,7 @@ uint32_t nvf0_grhub_code[] = {
        0x12b920f9,
        0x0132f402,
        0xf50232f4,
-       0xfc09aa21,
+       0xfc0a0221,
        0x0007f120,
        0x0203f0c0,
        0xbd0002d0,
@@ -640,7 +640,7 @@ uint32_t nvf0_grhub_code[] = {
        0xf41f23c8,
        0x31f40d0b,
        0x0232f401,
-       0x09aa21f5,
+       0x0a0221f5,
 /* 0x063c: chsw_done */
        0xf10127f0,
        0xf0c30007,
@@ -654,7 +654,7 @@ uint32_t nvf0_grhub_code[] = {
 /* 0x0660: main_not_ctx_switch */
        0xf401e4b0,
        0xf2b90d1b,
-       0x4221f502,
+       0x9a21f502,
        0x460ef409,
 /* 0x0670: main_not_ctx_chan */
        0xf402e4b0,
@@ -664,8 +664,8 @@ uint32_t nvf0_grhub_code[] = {
        0x09d00203,
        0xf404bd00,
        0x32f40132,
-       0xaa21f502,
-       0xf094bd09,
+       0x0221f502,
+       0xf094bd0a,
        0x07f10799,
        0x03f01700,
        0x0009d002,
@@ -710,18 +710,40 @@ uint32_t nvf0_grhub_code[] = {
 /* 0x072b: ih_no_ctxsw */
        0xe40421f4,
        0xf40400ab,
-       0xb7f1140b,
+       0xe7f16c0b,
+       0xe3f00708,
+       0x6821f440,
+       0xf102ffb9,
+       0xf0040007,
+       0x0fd00203,
+       0xf104bd00,
+       0xf00704e7,
+       0x21f440e3,
+       0x02ffb968,
+       0x030007f1,
+       0xd00203f0,
+       0x04bd000f,
+       0x9450fec7,
+       0xf7f102ee,
+       0xf3f00700,
+       0x00efbb40,
+       0xf16821f4,
+       0xf0020007,
+       0x0fd00203,
+       0xf004bd00,
+       0x21f503f7,
+       0xb7f1037e,
        0xbfb90100,
        0x44e7f102,
        0x40e3f001,
-/* 0x0743: ih_no_fwmthd */
+/* 0x079b: ih_no_fwmthd */
        0xf19d21f4,
-       0xbd0104b7,
+       0xbd0504b7,
        0xb4abffb0,
        0xf10f0bf4,
        0xf0070007,
        0x0bd00303,
-/* 0x075b: ih_no_other */
+/* 0x07b3: ih_no_other */
        0xf104bd00,
        0xf0010007,
        0x0ad00003,
@@ -731,19 +753,19 @@ uint32_t nvf0_grhub_code[] = {
        0xfc90fca0,
        0x0088fe80,
        0x32f480fc,
-/* 0x077f: ctx_4170s */
+/* 0x07d7: ctx_4170s */
        0xf001f800,
        0xffb910f5,
        0x70e7f102,
        0x40e3f041,
        0xf89d21f4,
-/* 0x0791: ctx_4170w */
+/* 0x07e9: ctx_4170w */
        0x70e7f100,
        0x40e3f041,
        0xb96821f4,
        0xf4f002ff,
        0xf01bf410,
-/* 0x07a6: ctx_redswitch */
+/* 0x07fe: ctx_redswitch */
        0xe7f100f8,
        0xe5f00200,
        0x20e5f040,
@@ -751,7 +773,7 @@ uint32_t nvf0_grhub_code[] = {
        0xf0850007,
        0x0ed00103,
        0xf004bd00,
-/* 0x07c2: ctx_redswitch_delay */
+/* 0x081a: ctx_redswitch_delay */
        0xf2b608f7,
        0xfd1bf401,
        0x0400e5f1,
@@ -759,7 +781,7 @@ uint32_t nvf0_grhub_code[] = {
        0x850007f1,
        0xd00103f0,
        0x04bd000e,
-/* 0x07de: ctx_86c */
+/* 0x0836: ctx_86c */
        0x07f100f8,
        0x03f02300,
        0x000fd002,
@@ -770,17 +792,17 @@ uint32_t nvf0_grhub_code[] = {
        0xe7f102ff,
        0xe3f0a88c,
        0x9d21f441,
-/* 0x0806: ctx_mem */
+/* 0x085e: ctx_mem */
        0x07f100f8,
        0x03f08400,
        0x000fd002,
-/* 0x0812: ctx_mem_wait */
+/* 0x086a: ctx_mem_wait */
        0xf7f104bd,
        0xf3f08400,
        0x00ffcf02,
        0xf405fffd,
        0x00f8f31b,
-/* 0x0824: ctx_load */
+/* 0x087c: ctx_load */
        0x99f094bd,
        0x0007f105,
        0x0203f037,
@@ -797,7 +819,7 @@ uint32_t nvf0_grhub_code[] = {
        0x0203f083,
        0xbd0002d0,
        0x07f7f004,
-       0x080621f5,
+       0x085e21f5,
        0xc00007f1,
        0xd00203f0,
        0x04bd0002,
@@ -852,29 +874,29 @@ uint32_t nvf0_grhub_code[] = {
        0x170007f1,
        0xd00203f0,
        0x04bd0009,
-/* 0x0942: ctx_chan */
+/* 0x099a: ctx_chan */
        0x21f500f8,
-       0xa7f00824,
+       0xa7f0087c,
        0xd021f40c,
        0xf505f7f0,
-       0xf8080621,
-/* 0x0955: ctx_mmio_exec */
+       0xf8085e21,
+/* 0x09ad: ctx_mmio_exec */
        0x41039800,
        0x810007f1,
        0xd00203f0,
        0x04bd0003,
-/* 0x0966: ctx_mmio_loop */
+/* 0x09be: ctx_mmio_loop */
        0x34c434bd,
        0x0f1bf4ff,
        0x020057f1,
        0xfa0653f0,
        0x03f80535,
-/* 0x0978: ctx_mmio_pull */
+/* 0x09d0: ctx_mmio_pull */
        0x98804e98,
        0x21f4814f,
        0x0830b69d,
        0xf40112b6,
-/* 0x098a: ctx_mmio_done */
+/* 0x09e2: ctx_mmio_done */
        0x0398df1b,
        0x0007f116,
        0x0203f081,
@@ -883,30 +905,30 @@ uint32_t nvf0_grhub_code[] = {
        0x010017f1,
        0xfa0613f0,
        0x03f80601,
-/* 0x09aa: ctx_xfer */
+/* 0x0a02: ctx_xfer */
        0xe7f000f8,
        0x0007f104,
        0x0303f002,
        0xbd000ed0,
-/* 0x09b9: ctx_xfer_idle */
+/* 0x0a11: ctx_xfer_idle */
        0x00e7f104,
        0x03e3f000,
        0xf100eecf,
        0xf42000e4,
        0x11f4f21b,
        0x0d02f406,
-/* 0x09d0: ctx_xfer_pre */
+/* 0x0a28: ctx_xfer_pre */
        0xf510f7f0,
-       0xf407de21,
-/* 0x09da: ctx_xfer_pre_load */
+       0xf4083621,
+/* 0x0a32: ctx_xfer_pre_load */
        0xf7f01c11,
-       0x7f21f502,
-       0x9121f507,
-       0xa621f507,
+       0xd721f502,
+       0xe921f507,
+       0xfe21f507,
        0xf5f4bd07,
-       0xf5077f21,
-/* 0x09f3: ctx_xfer_exec */
-       0x98082421,
+       0xf507d721,
+/* 0x0a4b: ctx_xfer_exec */
+       0x98087c21,
        0x24bd1601,
        0x050007f1,
        0xd00103f0,
@@ -941,21 +963,21 @@ uint32_t nvf0_grhub_code[] = {
        0xa7f01301,
        0xd021f40c,
        0xf505f7f0,
-       0xf4080621,
-/* 0x0a82: ctx_xfer_post */
+       0xf4085e21,
+/* 0x0ada: ctx_xfer_post */
        0xf7f02e02,
-       0x7f21f502,
+       0xd721f502,
        0xf5f4bd07,
-       0xf507de21,
+       0xf5083621,
        0xf5027f21,
-       0xbd079121,
-       0x7f21f5f4,
+       0xbd07e921,
+       0xd721f5f4,
        0x1011f407,
        0xfd400198,
        0x0bf40511,
-       0x5521f507,
-/* 0x0aad: ctx_xfer_no_post_mmio */
-/* 0x0aad: ctx_xfer_done */
+       0xad21f507,
+/* 0x0b05: ctx_xfer_no_post_mmio */
+/* 0x0b05: ctx_xfer_done */
        0x0000f809,
        0x00000000,
        0x00000000,
@@ -977,4 +999,46 @@ uint32_t nvf0_grhub_code[] = {
        0x00000000,
        0x00000000,
        0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
 };
index a47d49d..2a0b0f8 100644 (file)
 #define GK110 0xf0
 #define GK208 0x108
 
+#define NV_PGRAPH_TRAPPED_ADDR                                         0x400704
+#define NV_PGRAPH_TRAPPED_DATA_LO                                      0x400708
+#define NV_PGRAPH_TRAPPED_DATA_HI                                      0x40070c
+
+#define NV_PGRAPH_FE_OBJECT_TABLE(n)                        ((n) * 4 + 0x400700)
+
 #define NV_PGRAPH_FECS_INTR_ACK                                        0x409004
 #define NV_PGRAPH_FECS_INTR                                            0x409008
 #define NV_PGRAPH_FECS_INTR_FWMTHD                                   0x00000400
index fd1d380..1718ae4 100644 (file)
@@ -3,5 +3,6 @@
 
 #define E_BAD_COMMAND  0x00000001
 #define E_CMD_OVERFLOW 0x00000002
+#define E_BAD_FWMTHD   0x00000003
 
 #endif
index 1a2d564..20665c2 100644 (file)
@@ -976,7 +976,6 @@ nv50_graph_init(struct nouveau_object *object)
                break;
        case 0xa0:
        default:
-               nv_wr32(priv, 0x402cc0, 0x00000000);
                if (nv_device(priv)->chipset == 0xa0 ||
                    nv_device(priv)->chipset == 0xaa ||
                    nv_device(priv)->chipset == 0xac) {
@@ -991,10 +990,10 @@ nv50_graph_init(struct nouveau_object *object)
 
        /* zero out zcull regions */
        for (i = 0; i < 8; i++) {
-               nv_wr32(priv, 0x402c20 + (i * 8), 0x00000000);
-               nv_wr32(priv, 0x402c24 + (i * 8), 0x00000000);
-               nv_wr32(priv, 0x402c28 + (i * 8), 0x00000000);
-               nv_wr32(priv, 0x402c2c + (i * 8), 0x00000000);
+               nv_wr32(priv, 0x402c20 + (i * 0x10), 0x00000000);
+               nv_wr32(priv, 0x402c24 + (i * 0x10), 0x00000000);
+               nv_wr32(priv, 0x402c28 + (i * 0x10), 0x00000000);
+               nv_wr32(priv, 0x402c2c + (i * 0x10), 0x00000000);
        }
        return 0;
 }
index bf7bdb1..aa08389 100644 (file)
@@ -789,17 +789,40 @@ nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *priv)
 static void
 nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
 {
-       u32 ustat = nv_rd32(priv, 0x409c18);
+       u32 stat = nv_rd32(priv, 0x409c18);
 
-       if (ustat & 0x00000001)
-               nv_error(priv, "CTXCTL ucode error\n");
-       if (ustat & 0x00080000)
-               nv_error(priv, "CTXCTL watchdog timeout\n");
-       if (ustat & ~0x00080001)
-               nv_error(priv, "CTXCTL 0x%08x\n", ustat);
+       if (stat & 0x00000001) {
+               u32 code = nv_rd32(priv, 0x409814);
+               if (code == E_BAD_FWMTHD) {
+                       u32 class = nv_rd32(priv, 0x409808);
+                       u32  addr = nv_rd32(priv, 0x40980c);
+                       u32  subc = (addr & 0x00070000) >> 16;
+                       u32  mthd = (addr & 0x00003ffc);
+                       u32  data = nv_rd32(priv, 0x409810);
+
+                       nv_error(priv, "FECS MTHD subc %d class 0x%04x "
+                                      "mthd 0x%04x data 0x%08x\n",
+                                subc, class, mthd, data);
 
-       nvc0_graph_ctxctl_debug(priv);
-       nv_wr32(priv, 0x409c20, ustat);
+                       nv_wr32(priv, 0x409c20, 0x00000001);
+                       stat &= ~0x00000001;
+               } else {
+                       nv_error(priv, "FECS ucode error %d\n", code);
+               }
+       }
+
+       if (stat & 0x00080000) {
+               nv_error(priv, "FECS watchdog timeout\n");
+               nvc0_graph_ctxctl_debug(priv);
+               nv_wr32(priv, 0x409c20, 0x00080000);
+               stat &= ~0x00080000;
+       }
+
+       if (stat) {
+               nv_error(priv, "FECS 0x%08x\n", stat);
+               nvc0_graph_ctxctl_debug(priv);
+               nv_wr32(priv, 0x409c20, stat);
+       }
 }
 
 static void
index 75203a9..ffc2891 100644 (file)
@@ -38,6 +38,8 @@
 #include <engine/fifo.h>
 #include <engine/graph.h>
 
+#include "fuc/os.h"
+
 #define GPC_MAX 32
 #define TPC_MAX (GPC_MAX * 8)
 
index db1b39d..825f7bb 100644 (file)
@@ -84,6 +84,7 @@ extern struct nouveau_oclass *nv4e_i2c_oclass;
 extern struct nouveau_oclass *nv50_i2c_oclass;
 extern struct nouveau_oclass *nv94_i2c_oclass;
 extern struct nouveau_oclass *nvd0_i2c_oclass;
+extern struct nouveau_oclass *gf117_i2c_oclass;
 extern struct nouveau_oclass *nve0_i2c_oclass;
 
 static inline int
index 4ac1aa3..0e62a32 100644 (file)
@@ -307,7 +307,6 @@ calc_clk(struct nve0_clock_priv *priv,
                info->dsrc = src0;
                if (div0) {
                        info->ddiv |= 0x80000000;
-                       info->ddiv |= div0 << 8;
                        info->ddiv |= div0;
                }
                if (div1D) {
@@ -352,7 +351,7 @@ nve0_clock_prog_0(struct nve0_clock_priv *priv, int clk)
 {
        struct nve0_clock_info *info = &priv->eng[clk];
        if (!info->ssel) {
-               nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv);
+               nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x8000003f, info->ddiv);
                nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc);
        }
 }
@@ -389,7 +388,10 @@ static void
 nve0_clock_prog_3(struct nve0_clock_priv *priv, int clk)
 {
        struct nve0_clock_info *info = &priv->eng[clk];
-       nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv);
+       if (info->ssel)
+               nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f00, info->mdiv);
+       else
+               nv_mask(priv, 0x137250 + (clk * 0x04), 0x0000003f, info->mdiv);
 }
 
 static void
index 84c7efb..1ad3ea5 100644 (file)
@@ -262,8 +262,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
        struct nve0_ram *ram = (void *)pfb->ram;
        struct nve0_ramfuc *fuc = &ram->fuc;
        struct nouveau_ram_data *next = ram->base.next;
-       int vc = !(next->bios.ramcfg_11_02_08);
-       int mv = !(next->bios.ramcfg_11_02_04);
+       int vc = !next->bios.ramcfg_11_02_08;
+       int mv = !next->bios.ramcfg_11_02_04;
        u32 mask, data;
 
        ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
@@ -370,8 +370,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
                }
        }
 
-       if ( (next->bios.ramcfg_11_02_40) ||
-            (next->bios.ramcfg_11_07_10)) {
+       if (next->bios.ramcfg_11_02_40 ||
+           next->bios.ramcfg_11_07_10) {
                ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
                ram_nsec(fuc, 20000);
        }
@@ -417,7 +417,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
                ram_mask(fuc, 0x10f694, 0xff00ff00, data);
        }
 
-       if (ram->mode == 2 && (next->bios.ramcfg_11_08_10))
+       if (ram->mode == 2 && next->bios.ramcfg_11_08_10)
                data = 0x00000080;
        else
                data = 0x00000000;
@@ -425,13 +425,13 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
 
        mask = 0x00070000;
        data = 0x00000000;
-       if (!(next->bios.ramcfg_11_02_80))
+       if (!next->bios.ramcfg_11_02_80)
                data |= 0x03000000;
-       if (!(next->bios.ramcfg_11_02_40))
+       if (!next->bios.ramcfg_11_02_40)
                data |= 0x00002000;
-       if (!(next->bios.ramcfg_11_07_10))
+       if (!next->bios.ramcfg_11_07_10)
                data |= 0x00004000;
-       if (!(next->bios.ramcfg_11_07_08))
+       if (!next->bios.ramcfg_11_07_08)
                data |= 0x00000003;
        else
                data |= 0x74000000;
@@ -486,7 +486,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
 
        data = mask = 0x00000000;
        if (NOTE00(ramcfg_02_03 != 0)) {
-               data |= (next->bios.ramcfg_11_02_03) << 8;
+               data |= next->bios.ramcfg_11_02_03 << 8;
                mask |= 0x00000300;
        }
        if (NOTE00(ramcfg_01_10)) {
@@ -498,7 +498,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
 
        data = mask = 0x00000000;
        if (NOTE00(timing_30_07 != 0)) {
-               data |= (next->bios.timing_20_30_07) << 28;
+               data |= next->bios.timing_20_30_07 << 28;
                mask |= 0x70000000;
        }
        if (NOTE00(ramcfg_01_01)) {
@@ -510,7 +510,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
 
        data = mask = 0x00000000;
        if (NOTE00(timing_30_07 != 0)) {
-               data |= (next->bios.timing_20_30_07) << 28;
+               data |= next->bios.timing_20_30_07 << 28;
                mask |= 0x70000000;
        }
        if (NOTE00(ramcfg_01_02)) {
@@ -522,16 +522,16 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
 
        mask = 0x33f00000;
        data = 0x00000000;
-       if (!(next->bios.ramcfg_11_01_04))
+       if (!next->bios.ramcfg_11_01_04)
                data |= 0x20200000;
-       if (!(next->bios.ramcfg_11_07_80))
+       if (!next->bios.ramcfg_11_07_80)
                data |= 0x12800000;
        /*XXX: see note above about there probably being some condition
         *     for the 10f824 stuff that uses ramcfg 3...
         */
-       if ( (next->bios.ramcfg_11_03_f0)) {
+       if (next->bios.ramcfg_11_03_f0) {
                if (next->bios.rammap_11_08_0c) {
-                       if (!(next->bios.ramcfg_11_07_80))
+                       if (!next->bios.ramcfg_11_07_80)
                                mask |= 0x00000020;
                        else
                                data |= 0x00000020;
@@ -563,7 +563,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
                ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000);
        }
 
-       data = (next->bios.timing_20_30_07) << 8;
+       data = next->bios.timing_20_30_07 << 8;
        if (next->bios.ramcfg_11_01_01)
                data |= 0x80000000;
        ram_mask(fuc, 0x100778, 0x00000700, data);
@@ -588,7 +588,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
        ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
        ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
 
-       if ((next->bios.ramcfg_11_08_10) && (ram->mode == 2) /*XXX*/) {
+       if (next->bios.ramcfg_11_08_10 && (ram->mode == 2) /*XXX*/) {
                u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000);
                nve0_ram_train(fuc, 0xbc0e0000, 0xa4010000); /*XXX*/
                ram_nsec(fuc, 1000);
@@ -621,8 +621,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
        data  = ram_rd32(fuc, 0x10f978);
        data &= ~0x00046144;
        data |=  0x0000000b;
-       if (!(next->bios.ramcfg_11_07_08)) {
-               if (!(next->bios.ramcfg_11_07_04))
+       if (!next->bios.ramcfg_11_07_08) {
+               if (!next->bios.ramcfg_11_07_04)
                        data |= 0x0000200c;
                else
                        data |= 0x00000000;
@@ -636,11 +636,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
                ram_wr32(fuc, 0x10f830, data);
        }
 
-       if (!(next->bios.ramcfg_11_07_08)) {
+       if (!next->bios.ramcfg_11_07_08) {
                data = 0x88020000;
-               if ( (next->bios.ramcfg_11_07_04))
+               if ( next->bios.ramcfg_11_07_04)
                        data |= 0x10000000;
-               if (!(next->bios.rammap_11_08_10))
+               if (!next->bios.rammap_11_08_10)
                        data |= 0x00080000;
        } else {
                data = 0xa40e0000;
@@ -689,8 +689,8 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
        const u32 runk0 = ram->fN1 << 16;
        const u32 runk1 = ram->fN1;
        struct nouveau_ram_data *next = ram->base.next;
-       int vc = !(next->bios.ramcfg_11_02_08);
-       int mv = !(next->bios.ramcfg_11_02_04);
+       int vc = !next->bios.ramcfg_11_02_08;
+       int mv = !next->bios.ramcfg_11_02_04;
        u32 mask, data;
 
        ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
@@ -705,7 +705,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
        }
 
        ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
-       if ((next->bios.ramcfg_11_03_f0))
+       if (next->bios.ramcfg_11_03_f0)
                ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
 
        ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
@@ -761,7 +761,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
 
        ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
        data  = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
-       data |= (next->bios.ramcfg_11_03_30) << 12;
+       data |= next->bios.ramcfg_11_03_30 << 16;
        ram_wr32(fuc, 0x1373ec, data);
        ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
        ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
@@ -793,8 +793,8 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
                }
        }
 
-       if ( (next->bios.ramcfg_11_02_40) ||
-            (next->bios.ramcfg_11_07_10)) {
+       if (next->bios.ramcfg_11_02_40 ||
+           next->bios.ramcfg_11_07_10) {
                ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
                ram_nsec(fuc, 20000);
        }
@@ -810,13 +810,13 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
 
        mask = 0x00010000;
        data = 0x00000000;
-       if (!(next->bios.ramcfg_11_02_80))
+       if (!next->bios.ramcfg_11_02_80)
                data |= 0x03000000;
-       if (!(next->bios.ramcfg_11_02_40))
+       if (!next->bios.ramcfg_11_02_40)
                data |= 0x00002000;
-       if (!(next->bios.ramcfg_11_07_10))
+       if (!next->bios.ramcfg_11_07_10)
                data |= 0x00004000;
-       if (!(next->bios.ramcfg_11_07_08))
+       if (!next->bios.ramcfg_11_07_08)
                data |= 0x00000003;
        else
                data |= 0x14000000;
@@ -844,16 +844,16 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
 
        mask = 0x33f00000;
        data = 0x00000000;
-       if (!(next->bios.ramcfg_11_01_04))
+       if (!next->bios.ramcfg_11_01_04)
                data |= 0x20200000;
-       if (!(next->bios.ramcfg_11_07_80))
+       if (!next->bios.ramcfg_11_07_80)
                data |= 0x12800000;
        /*XXX: see note above about there probably being some condition
         *     for the 10f824 stuff that uses ramcfg 3...
         */
-       if ( (next->bios.ramcfg_11_03_f0)) {
+       if (next->bios.ramcfg_11_03_f0) {
                if (next->bios.rammap_11_08_0c) {
-                       if (!(next->bios.ramcfg_11_07_80))
+                       if (!next->bios.ramcfg_11_07_80)
                                mask |= 0x00000020;
                        else
                                data |= 0x00000020;
@@ -876,7 +876,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
                data = next->bios.timing_20_2c_1fc0;
        ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24);
 
-       ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8);
+       ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8 << 16);
 
        ram_wr32(fuc, 0x10f090, 0x4000007f);
        ram_nsec(fuc, 1000);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c
new file mode 100644 (file)
index 0000000..fa891c3
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "nv50.h"
+
+struct nouveau_oclass *
+gf117_i2c_oclass = &(struct nouveau_i2c_impl) {
+       .base.handle = NV_SUBDEV(I2C, 0xd7),
+       .base.ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = _nouveau_i2c_ctor,
+               .dtor = _nouveau_i2c_dtor,
+               .init = _nouveau_i2c_init,
+               .fini = _nouveau_i2c_fini,
+       },
+       .sclass = nvd0_i2c_sclass,
+       .pad_x = &nv04_i2c_pad_oclass,
+       .pad_s = &nv04_i2c_pad_oclass,
+}.base;
index 7120124..ebef970 100644 (file)
@@ -94,6 +94,23 @@ nve0_ibus_intr(struct nouveau_subdev *subdev)
        }
 }
 
+static int
+nve0_ibus_init(struct nouveau_object *object)
+{
+       struct nve0_ibus_priv *priv = (void *)object;
+       int ret = nouveau_ibus_init(&priv->base);
+       if (ret == 0) {
+               nv_mask(priv, 0x122318, 0x0003ffff, 0x00001000);
+               nv_mask(priv, 0x12231c, 0x0003ffff, 0x00000200);
+               nv_mask(priv, 0x122310, 0x0003ffff, 0x00000800);
+               nv_mask(priv, 0x122348, 0x0003ffff, 0x00000100);
+               nv_mask(priv, 0x1223b0, 0x0003ffff, 0x00000fff);
+               nv_mask(priv, 0x122348, 0x0003ffff, 0x00000200);
+               nv_mask(priv, 0x122358, 0x0003ffff, 0x00002880);
+       }
+       return ret;
+}
+
 static int
 nve0_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
               struct nouveau_oclass *oclass, void *data, u32 size,
@@ -117,7 +134,7 @@ nve0_ibus_oclass = {
        .ofuncs = &(struct nouveau_ofuncs) {
                .ctor = nve0_ibus_ctor,
                .dtor = _nouveau_ibus_dtor,
-               .init = _nouveau_ibus_init,
+               .init = nve0_ibus_init,
                .fini = _nouveau_ibus_fini,
        },
 };
index 2284ecb..c2bb616 100644 (file)
@@ -83,7 +83,7 @@ host_send:
                // increment GET
                add b32 $r1 0x1
                and $r14 $r1 #fifo_qmaskf
-               nv_iowr(NV_PPWR_FIFO_GET(0), $r1)
+               nv_iowr(NV_PPWR_FIFO_GET(0), $r14)
                bra #host_send
        host_send_done:
        ret
index 4bd43a9..39a5dc1 100644 (file)
@@ -1018,7 +1018,7 @@ uint32_t nv108_pwr_code[] = {
        0xb600023f,
        0x1ec40110,
        0x04b0400f,
-       0xbd0001f6,
+       0xbd000ef6,
        0xc70ef404,
 /* 0x0328: host_send_done */
 /* 0x032a: host_recv */
index 5a73fa6..254205c 100644 (file)
@@ -1124,7 +1124,7 @@ uint32_t nva3_pwr_code[] = {
        0x0f1ec401,
        0x04b007f1,
        0xd00604b6,
-       0x04bd0001,
+       0x04bd000e,
 /* 0x03cb: host_send_done */
        0xf8ba0ef4,
 /* 0x03cd: host_recv */
index 4dba00d..7ac8740 100644 (file)
@@ -1124,7 +1124,7 @@ uint32_t nvc0_pwr_code[] = {
        0x0f1ec401,
        0x04b007f1,
        0xd00604b6,
-       0x04bd0001,
+       0x04bd000e,
 /* 0x03cb: host_send_done */
        0xf8ba0ef4,
 /* 0x03cd: host_recv */
index 5e24c6b..cd9ff1a 100644 (file)
@@ -1033,7 +1033,7 @@ uint32_t nvd0_pwr_code[] = {
        0xb6026b21,
        0x1ec40110,
        0xb007f10f,
-       0x0001d004,
+       0x000ed004,
        0x0ef404bd,
 /* 0x0365: host_send_done */
 /* 0x0367: host_recv */
index 26b5647..47ad742 100644 (file)
@@ -736,6 +736,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                  fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y,
                  new_bo->bo.offset };
 
+       /* Keep vblanks on during flip, for the target crtc of this flip */
+       drm_vblank_get(dev, nouveau_crtc(crtc)->index);
+
        /* Emit a page flip */
        if (nv_device(drm->device)->card_type >= NV_50) {
                ret = nv50_display_flip_next(crtc, fb, chan, swap_interval);
@@ -779,6 +782,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        return 0;
 
 fail_unreserve:
+       drm_vblank_put(dev, nouveau_crtc(crtc)->index);
        ttm_bo_unreserve(&old_bo->bo);
 fail_unpin:
        mutex_unlock(&chan->cli->mutex);
@@ -817,6 +821,9 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
                drm_send_vblank_event(dev, crtcid, s->event);
        }
 
+       /* Give up ownership of vblank for page-flipped crtc */
+       drm_vblank_put(dev, s->crtc);
+
        list_del(&s->head);
        if (ps)
                *ps = *s;
index 26c12a3..a03c734 100644 (file)
@@ -1052,7 +1052,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
        int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
 
        /* pass the actual clock to atombios_crtc_program_pll for DCE5,6 for HDMI */
-       if (ASIC_IS_DCE5(rdev) && !ASIC_IS_DCE8(rdev) &&
+       if (ASIC_IS_DCE5(rdev) &&
            (encoder_mode == ATOM_ENCODER_MODE_HDMI) &&
            (radeon_crtc->bpc > 8))
                clock = radeon_crtc->adjusted_clock;
@@ -1136,6 +1136,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
        u32 tmp, viewport_w, viewport_h;
        int r;
+       bool bypass_lut = false;
 
        /* no fb bound */
        if (!atomic && !crtc->primary->fb) {
@@ -1174,33 +1175,73 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
        radeon_bo_unreserve(rbo);
 
-       switch (target_fb->bits_per_pixel) {
-       case 8:
+       switch (target_fb->pixel_format) {
+       case DRM_FORMAT_C8:
                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
                break;
-       case 15:
+       case DRM_FORMAT_XRGB4444:
+       case DRM_FORMAT_ARGB4444:
+               fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
+                            EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB4444));
+#ifdef __BIG_ENDIAN
+               fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
+#endif
+               break;
+       case DRM_FORMAT_XRGB1555:
+       case DRM_FORMAT_ARGB1555:
                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
+#ifdef __BIG_ENDIAN
+               fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
+#endif
+               break;
+       case DRM_FORMAT_BGRX5551:
+       case DRM_FORMAT_BGRA5551:
+               fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
+                            EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA5551));
+#ifdef __BIG_ENDIAN
+               fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
+#endif
                break;
-       case 16:
+       case DRM_FORMAT_RGB565:
                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
 #ifdef __BIG_ENDIAN
                fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
 #endif
                break;
-       case 24:
-       case 32:
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
 #ifdef __BIG_ENDIAN
                fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
 #endif
                break;
+       case DRM_FORMAT_XRGB2101010:
+       case DRM_FORMAT_ARGB2101010:
+               fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
+                            EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB2101010));
+#ifdef __BIG_ENDIAN
+               fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
+#endif
+               /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
+               bypass_lut = true;
+               break;
+       case DRM_FORMAT_BGRX1010102:
+       case DRM_FORMAT_BGRA1010102:
+               fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
+                            EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA1010102));
+#ifdef __BIG_ENDIAN
+               fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
+#endif
+               /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
+               bypass_lut = true;
+               break;
        default:
-               DRM_ERROR("Unsupported screen depth %d\n",
-                         target_fb->bits_per_pixel);
+               DRM_ERROR("Unsupported screen format %s\n",
+                         drm_get_format_name(target_fb->pixel_format));
                return -EINVAL;
        }
 
@@ -1329,6 +1370,18 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
        WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
 
+       /*
+        * The LUT only has 256 slots for indexing by a 8 bpc fb. Bypass the LUT
+        * for > 8 bpc scanout to avoid truncation of fb indices to 8 msb's, to
+        * retain the full precision throughout the pipeline.
+        */
+       WREG32_P(EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL + radeon_crtc->crtc_offset,
+                (bypass_lut ? EVERGREEN_LUT_10BIT_BYPASS_EN : 0),
+                ~EVERGREEN_LUT_10BIT_BYPASS_EN);
+
+       if (bypass_lut)
+               DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
+
        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
        WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
@@ -1396,6 +1449,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
        u32 tmp, viewport_w, viewport_h;
        int r;
+       bool bypass_lut = false;
 
        /* no fb bound */
        if (!atomic && !crtc->primary->fb) {
@@ -1433,18 +1487,30 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
        radeon_bo_unreserve(rbo);
 
-       switch (target_fb->bits_per_pixel) {
-       case 8:
+       switch (target_fb->pixel_format) {
+       case DRM_FORMAT_C8:
                fb_format =
                    AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
                    AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
                break;
-       case 15:
+       case DRM_FORMAT_XRGB4444:
+       case DRM_FORMAT_ARGB4444:
+               fb_format =
+                   AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
+                   AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444;
+#ifdef __BIG_ENDIAN
+               fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
+#endif
+               break;
+       case DRM_FORMAT_XRGB1555:
                fb_format =
                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
                    AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
+#ifdef __BIG_ENDIAN
+               fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
+#endif
                break;
-       case 16:
+       case DRM_FORMAT_RGB565:
                fb_format =
                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
                    AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
@@ -1452,8 +1518,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
                fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
 #endif
                break;
-       case 24:
-       case 32:
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
                fb_format =
                    AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
                    AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
@@ -1461,9 +1527,20 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
                fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
 #endif
                break;
+       case DRM_FORMAT_XRGB2101010:
+       case DRM_FORMAT_ARGB2101010:
+               fb_format =
+                   AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
+                   AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010;
+#ifdef __BIG_ENDIAN
+               fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
+#endif
+               /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
+               bypass_lut = true;
+               break;
        default:
-               DRM_ERROR("Unsupported screen depth %d\n",
-                         target_fb->bits_per_pixel);
+               DRM_ERROR("Unsupported screen format %s\n",
+                         drm_get_format_name(target_fb->pixel_format));
                return -EINVAL;
        }
 
@@ -1502,6 +1579,13 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        if (rdev->family >= CHIP_R600)
                WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
 
+       /* LUT only has 256 slots for 8 bpc fb. Bypass for > 8 bpc scanout for precision */
+       WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset,
+                (bypass_lut ? AVIVO_LUT_10BIT_BYPASS_EN : 0), ~AVIVO_LUT_10BIT_BYPASS_EN);
+
+       if (bypass_lut)
+               DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
+
        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
        WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
index a0f63ff..333d143 100644 (file)
 #       define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED      1
 #       define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1      2
 #       define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1      4
+#define EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL         0x6808
+#       define EVERGREEN_LUT_10BIT_BYPASS_EN            (1 << 8)
 #define EVERGREEN_GRPH_SWAP_CONTROL                     0x680c
 #       define EVERGREEN_GRPH_ENDIAN_SWAP(x)            (((x) & 0x3) << 0)
 #       define EVERGREEN_GRPH_ENDIAN_NONE               0
index 1dd0d32..136b7bc 100644 (file)
  * block and vice versa.  This applies to GRPH, CUR, etc.
  */
 #define AVIVO_D1GRPH_LUT_SEL                                    0x6108
+#       define AVIVO_LUT_10BIT_BYPASS_EN                        (1 << 8)
 #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS                    0x6110
 #define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH                0x6914
 #define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH                0x6114
index 933c5c3..1b9177e 100644 (file)
@@ -1288,17 +1288,15 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
                    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
                    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
                        return MODE_OK;
-               else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) {
-                       if (ASIC_IS_DCE6(rdev)) {
-                               /* HDMI 1.3+ supports max clock of 340 Mhz */
-                               if (mode->clock > 340000)
-                                       return MODE_CLOCK_HIGH;
-                               else
-                                       return MODE_OK;
-                       } else
+               else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+                       /* HDMI 1.3+ supports max clock of 340 Mhz */
+                       if (mode->clock > 340000)
                                return MODE_CLOCK_HIGH;
-               } else
+                       else
+                               return MODE_OK;
+               } else {
                        return MODE_CLOCK_HIGH;
+               }
        }
 
        /* check against the max pixel clock */
@@ -1549,6 +1547,8 @@ out:
 static int radeon_dp_mode_valid(struct drm_connector *connector,
                                  struct drm_display_mode *mode)
 {
+       struct drm_device *dev = connector->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
 
@@ -1579,14 +1579,23 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
                                        return MODE_PANEL;
                        }
                }
-               return MODE_OK;
        } else {
                if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
-                   (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+                   (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
                        return radeon_dp_mode_valid_helper(connector, mode);
-               else
-                       return MODE_OK;
+               } else {
+                       if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+                               /* HDMI 1.3+ supports max clock of 340 Mhz */
+                               if (mode->clock > 340000)
+                                       return MODE_CLOCK_HIGH;
+                       } else {
+                               if (mode->clock > 165000)
+                                       return MODE_CLOCK_HIGH;
+                       }
+               }
        }
+
+       return MODE_OK;
 }
 
 static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
index 5ed6170..8fc362a 100644 (file)
@@ -66,7 +66,8 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
                             (radeon_crtc->lut_b[i] << 0));
        }
 
-       WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
+       /* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
+       WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id, ~1);
 }
 
 static void dce4_crtc_load_lut(struct drm_crtc *crtc)
@@ -357,8 +358,9 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 
        spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
 
+       drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
        radeon_fence_unref(&work->fence);
-       radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id);
+       radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
        queue_work(radeon_crtc->flip_queue, &work->unpin_work);
 }
 
@@ -459,6 +461,12 @@ static void radeon_flip_work_func(struct work_struct *__work)
                base &= ~7;
        }
 
+       r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id);
+       if (r) {
+               DRM_ERROR("failed to get vblank before flip\n");
+               goto pflip_cleanup;
+       }
+
        /* We borrow the event spin lock for protecting flip_work */
        spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
@@ -473,6 +481,16 @@ static void radeon_flip_work_func(struct work_struct *__work)
 
        return;
 
+pflip_cleanup:
+       if (unlikely(radeon_bo_reserve(work->new_rbo, false) != 0)) {
+               DRM_ERROR("failed to reserve new rbo in error path\n");
+               goto cleanup;
+       }
+       if (unlikely(radeon_bo_unpin(work->new_rbo) != 0)) {
+               DRM_ERROR("failed to unpin new rbo in error path\n");
+       }
+       radeon_bo_unreserve(work->new_rbo);
+
 cleanup:
        drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
        radeon_fence_unref(&work->fence);
index 08531a1..02d3d85 100644 (file)
@@ -1052,7 +1052,7 @@ config SENSORS_PC87427
          will be called pc87427.
 
 config SENSORS_NTC_THERMISTOR
-       tristate "NTC thermistor support"
+       tristate "NTC thermistor support from Murata"
        depends on !OF || IIO=n || IIO
        help
          This driver supports NTC thermistors sensor reading and its
@@ -1060,7 +1060,8 @@ config SENSORS_NTC_THERMISTOR
          send notifications about the temperature.
 
          Currently, this driver supports
-         NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333.
+         NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333
+         from Murata.
 
          This driver can also be built as a module.  If so, the module
          will be called ntc-thermistor.
@@ -1176,6 +1177,7 @@ config SENSORS_DME1737
 config SENSORS_EMC1403
        tristate "SMSC EMC1403/23 thermal sensor"
        depends on I2C
+       select REGMAP_I2C
        help
          If you say yes here you get support for the SMSC EMC1403/23
          temperature monitoring chip.
index ba35e4d..2566c43 100644 (file)
@@ -538,7 +538,7 @@ static int gpio_fan_probe(struct platform_device *pdev)
 
        /* Make this driver part of hwmon class. */
        fan_data->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev,
-                                               "gpio-fan", fan_data,
+                                               "gpio_fan", fan_data,
                                                gpio_fan_groups);
        if (IS_ERR(fan_data->hwmon_dev))
                return PTR_ERR(fan_data->hwmon_dev);
index e76feb8..bdfbe91 100644 (file)
@@ -163,6 +163,18 @@ static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata)
 }
 
 static const struct of_device_id ntc_match[] = {
+       { .compatible = "murata,ncp15wb473",
+               .data = &ntc_thermistor_id[0] },
+       { .compatible = "murata,ncp18wb473",
+               .data = &ntc_thermistor_id[1] },
+       { .compatible = "murata,ncp21wb473",
+               .data = &ntc_thermistor_id[2] },
+       { .compatible = "murata,ncp03wb473",
+               .data = &ntc_thermistor_id[3] },
+       { .compatible = "murata,ncp15wl333",
+               .data = &ntc_thermistor_id[4] },
+
+       /* Usage of vendor name "ntc" is deprecated */
        { .compatible = "ntc,ncp15wb473",
                .data = &ntc_thermistor_id[0] },
        { .compatible = "ntc,ncp18wb473",
@@ -534,7 +546,7 @@ static struct platform_driver ntc_thermistor_driver = {
 
 module_platform_driver(ntc_thermistor_driver);
 
-MODULE_DESCRIPTION("NTC Thermistor Driver");
+MODULE_DESCRIPTION("NTC Thermistor Driver from Murata");
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:ntc-thermistor");
index 6ed76ce..32487c1 100644 (file)
@@ -249,7 +249,7 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
        int nr = to_sensor_dev_attr(attr)->index; \
        struct w83l786ng_data *data = w83l786ng_update_device(dev); \
        return sprintf(buf, "%d\n", \
-               FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \
+               FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
 }
 
 show_fan_reg(fan);
index 620d100..9f7d585 100644 (file)
@@ -676,6 +676,16 @@ config I2C_RIIC
          This driver can also be built as a module.  If so, the module
          will be called i2c-riic.
 
+config I2C_RK3X
+       tristate "Rockchip RK3xxx I2C adapter"
+       depends on OF
+       help
+         Say Y here to include support for the I2C adapter in Rockchip RK3xxx
+         SoCs.
+
+         This driver can also be built as a module. If so, the module will
+         be called i2c-rk3x.
+
 config HAVE_S3C2410_I2C
        bool
        help
@@ -764,6 +774,19 @@ config I2C_STU300
          This driver can also be built as a module. If so, the module
          will be called i2c-stu300.
 
+config I2C_SUN6I_P2WI
+       tristate "Allwinner sun6i internal P2WI controller"
+       depends on RESET_CONTROLLER
+       depends on MACH_SUN6I || COMPILE_TEST
+       help
+         If you say yes to this option, support will be included for the
+         P2WI (Push/Pull 2 Wire Interface) controller embedded in some sunxi
+         SOCs.
+         The P2WI looks like an SMBus controller (which supports only byte
+         accesses), except that it only supports one slave device.
+         This interface is used to connect to specific PMIC devices (like the
+         AXP221).
+
 config I2C_TEGRA
        tristate "NVIDIA Tegra internal I2C controller"
        depends on ARCH_TEGRA
index 298692c..dd9a7f8 100644 (file)
@@ -66,6 +66,7 @@ obj-$(CONFIG_I2C_PXA)         += i2c-pxa.o
 obj-$(CONFIG_I2C_PXA_PCI)      += i2c-pxa-pci.o
 obj-$(CONFIG_I2C_QUP)          += i2c-qup.o
 obj-$(CONFIG_I2C_RIIC)         += i2c-riic.o
+obj-$(CONFIG_I2C_RK3X)         += i2c-rk3x.o
 obj-$(CONFIG_I2C_S3C2410)      += i2c-s3c2410.o
 obj-$(CONFIG_I2C_S6000)                += i2c-s6000.o
 obj-$(CONFIG_I2C_SH7760)       += i2c-sh7760.o
@@ -74,6 +75,7 @@ obj-$(CONFIG_I2C_SIMTEC)      += i2c-simtec.o
 obj-$(CONFIG_I2C_SIRF)         += i2c-sirf.o
 obj-$(CONFIG_I2C_ST)           += i2c-st.o
 obj-$(CONFIG_I2C_STU300)       += i2c-stu300.o
+obj-$(CONFIG_I2C_SUN6I_P2WI)   += i2c-sun6i-p2wi.o
 obj-$(CONFIG_I2C_TEGRA)                += i2c-tegra.o
 obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
 obj-$(CONFIG_I2C_WMT)          += i2c-wmt.o
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
new file mode 100644 (file)
index 0000000..a979150
--- /dev/null
@@ -0,0 +1,763 @@
+/*
+ * Driver for I2C adapter in Rockchip RK3xxx SoC
+ *
+ * Max Schwarz <max.schwarz@online.de>
+ * based on the patches by Rockchip Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/wait.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+
+/* Register Map */
+#define REG_CON        0x00 /* control register */
+#define REG_CLKDIV     0x04 /* clock divisor register */
+#define REG_MRXADDR    0x08 /* slave address for REGISTER_TX */
+#define REG_MRXRADDR   0x0c /* slave register address for REGISTER_TX */
+#define REG_MTXCNT     0x10 /* number of bytes to be transmitted */
+#define REG_MRXCNT     0x14 /* number of bytes to be received */
+#define REG_IEN        0x18 /* interrupt enable */
+#define REG_IPD        0x1c /* interrupt pending */
+#define REG_FCNT       0x20 /* finished count */
+
+/* Data buffer offsets */
+#define TXBUFFER_BASE 0x100
+#define RXBUFFER_BASE 0x200
+
+/* REG_CON bits */
+#define REG_CON_EN        BIT(0)
+enum {
+       REG_CON_MOD_TX = 0,      /* transmit data */
+       REG_CON_MOD_REGISTER_TX, /* select register and restart */
+       REG_CON_MOD_RX,          /* receive data */
+       REG_CON_MOD_REGISTER_RX, /* broken: transmits read addr AND writes
+                                 * register addr */
+};
+#define REG_CON_MOD(mod)  ((mod) << 1)
+#define REG_CON_MOD_MASK  (BIT(1) | BIT(2))
+#define REG_CON_START     BIT(3)
+#define REG_CON_STOP      BIT(4)
+#define REG_CON_LASTACK   BIT(5) /* 1: send NACK after last received byte */
+#define REG_CON_ACTACK    BIT(6) /* 1: stop if NACK is received */
+
+/* REG_MRXADDR bits */
+#define REG_MRXADDR_VALID(x) BIT(24 + (x)) /* [x*8+7:x*8] of MRX[R]ADDR valid */
+
+/* REG_IEN/REG_IPD bits */
+#define REG_INT_BTF       BIT(0) /* a byte was transmitted */
+#define REG_INT_BRF       BIT(1) /* a byte was received */
+#define REG_INT_MBTF      BIT(2) /* master data transmit finished */
+#define REG_INT_MBRF      BIT(3) /* master data receive finished */
+#define REG_INT_START     BIT(4) /* START condition generated */
+#define REG_INT_STOP      BIT(5) /* STOP condition generated */
+#define REG_INT_NAKRCV    BIT(6) /* NACK received */
+#define REG_INT_ALL       0x7f
+
+/* Constants */
+#define WAIT_TIMEOUT      200 /* ms */
+#define DEFAULT_SCL_RATE  (100 * 1000) /* Hz */
+
+enum rk3x_i2c_state {
+       STATE_IDLE,
+       STATE_START,
+       STATE_READ,
+       STATE_WRITE,
+       STATE_STOP
+};
+
+/**
+ * @grf_offset: offset inside the grf regmap for setting the i2c type
+ */
+struct rk3x_i2c_soc_data {
+       int grf_offset;
+};
+
+struct rk3x_i2c {
+       struct i2c_adapter adap;
+       struct device *dev;
+       struct rk3x_i2c_soc_data *soc_data;
+
+       /* Hardware resources */
+       void __iomem *regs;
+       struct clk *clk;
+
+       /* Settings */
+       unsigned int scl_frequency;
+
+       /* Synchronization & notification */
+       spinlock_t lock;
+       wait_queue_head_t wait;
+       bool busy;
+
+       /* Current message */
+       struct i2c_msg *msg;
+       u8 addr;
+       unsigned int mode;
+       bool is_last_msg;
+
+       /* I2C state machine */
+       enum rk3x_i2c_state state;
+       unsigned int processed; /* sent/received bytes */
+       int error;
+};
+
+static inline void i2c_writel(struct rk3x_i2c *i2c, u32 value,
+                             unsigned int offset)
+{
+       writel(value, i2c->regs + offset);
+}
+
+static inline u32 i2c_readl(struct rk3x_i2c *i2c, unsigned int offset)
+{
+       return readl(i2c->regs + offset);
+}
+
+/* Reset all interrupt pending bits */
+static inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c)
+{
+       i2c_writel(i2c, REG_INT_ALL, REG_IPD);
+}
+
+/**
+ * Generate a START condition, which triggers a REG_INT_START interrupt.
+ */
+static void rk3x_i2c_start(struct rk3x_i2c *i2c)
+{
+       u32 val;
+
+       rk3x_i2c_clean_ipd(i2c);
+       i2c_writel(i2c, REG_INT_START, REG_IEN);
+
+       /* enable adapter with correct mode, send START condition */
+       val = REG_CON_EN | REG_CON_MOD(i2c->mode) | REG_CON_START;
+
+       /* if we want to react to NACK, set ACTACK bit */
+       if (!(i2c->msg->flags & I2C_M_IGNORE_NAK))
+               val |= REG_CON_ACTACK;
+
+       i2c_writel(i2c, val, REG_CON);
+}
+
+/**
+ * Generate a STOP condition, which triggers a REG_INT_STOP interrupt.
+ *
+ * @error: Error code to return in rk3x_i2c_xfer
+ */
+static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error)
+{
+       unsigned int ctrl;
+
+       i2c->processed = 0;
+       i2c->msg = NULL;
+       i2c->error = error;
+
+       if (i2c->is_last_msg) {
+               /* Enable stop interrupt */
+               i2c_writel(i2c, REG_INT_STOP, REG_IEN);
+
+               i2c->state = STATE_STOP;
+
+               ctrl = i2c_readl(i2c, REG_CON);
+               ctrl |= REG_CON_STOP;
+               i2c_writel(i2c, ctrl, REG_CON);
+       } else {
+               /* Signal rk3x_i2c_xfer to start the next message. */
+               i2c->busy = false;
+               i2c->state = STATE_IDLE;
+
+               /*
+                * The HW is actually not capable of REPEATED START. But we can
+                * get the intended effect by resetting its internal state
+                * and issuing an ordinary START.
+                */
+               i2c_writel(i2c, 0, REG_CON);
+
+               /* signal that we are finished with the current msg */
+               wake_up(&i2c->wait);
+       }
+}
+
+/**
+ * Setup a read according to i2c->msg
+ */
+static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
+{
+       unsigned int len = i2c->msg->len - i2c->processed;
+       u32 con;
+
+       con = i2c_readl(i2c, REG_CON);
+
+       /*
+        * The hw can read up to 32 bytes at a time. If we need more than one
+        * chunk, send an ACK after the last byte of the current chunk.
+        */
+       if (unlikely(len > 32)) {
+               len = 32;
+               con &= ~REG_CON_LASTACK;
+       } else {
+               con |= REG_CON_LASTACK;
+       }
+
+       /* make sure we are in plain RX mode if we read a second chunk */
+       if (i2c->processed != 0) {
+               con &= ~REG_CON_MOD_MASK;
+               con |= REG_CON_MOD(REG_CON_MOD_RX);
+       }
+
+       i2c_writel(i2c, con, REG_CON);
+       i2c_writel(i2c, len, REG_MRXCNT);
+}
+
+/**
+ * Fill the transmit buffer with data from i2c->msg
+ */
+static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c)
+{
+       unsigned int i, j;
+       u32 cnt = 0;
+       u32 val;
+       u8 byte;
+
+       for (i = 0; i < 8; ++i) {
+               val = 0;
+               for (j = 0; j < 4; ++j) {
+                       if (i2c->processed == i2c->msg->len)
+                               break;
+
+                       if (i2c->processed == 0 && cnt == 0)
+                               byte = (i2c->addr & 0x7f) << 1;
+                       else
+                               byte = i2c->msg->buf[i2c->processed++];
+
+                       val |= byte << (j * 8);
+                       cnt++;
+               }
+
+               i2c_writel(i2c, val, TXBUFFER_BASE + 4 * i);
+
+               if (i2c->processed == i2c->msg->len)
+                       break;
+       }
+
+       i2c_writel(i2c, cnt, REG_MTXCNT);
+}
+
+
+/* IRQ handlers for individual states */
+
+static void rk3x_i2c_handle_start(struct rk3x_i2c *i2c, unsigned int ipd)
+{
+       if (!(ipd & REG_INT_START)) {
+               rk3x_i2c_stop(i2c, -EIO);
+               dev_warn(i2c->dev, "unexpected irq in START: 0x%x\n", ipd);
+               rk3x_i2c_clean_ipd(i2c);
+               return;
+       }
+
+       /* ack interrupt */
+       i2c_writel(i2c, REG_INT_START, REG_IPD);
+
+       /* disable start bit */
+       i2c_writel(i2c, i2c_readl(i2c, REG_CON) & ~REG_CON_START, REG_CON);
+
+       /* enable appropriate interrupts and transition */
+       if (i2c->mode == REG_CON_MOD_TX) {
+               i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN);
+               i2c->state = STATE_WRITE;
+               rk3x_i2c_fill_transmit_buf(i2c);
+       } else {
+               /* in any other case, we are going to be reading. */
+               i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN);
+               i2c->state = STATE_READ;
+               rk3x_i2c_prepare_read(i2c);
+       }
+}
+
+static void rk3x_i2c_handle_write(struct rk3x_i2c *i2c, unsigned int ipd)
+{
+       if (!(ipd & REG_INT_MBTF)) {
+               rk3x_i2c_stop(i2c, -EIO);
+               dev_err(i2c->dev, "unexpected irq in WRITE: 0x%x\n", ipd);
+               rk3x_i2c_clean_ipd(i2c);
+               return;
+       }
+
+       /* ack interrupt */
+       i2c_writel(i2c, REG_INT_MBTF, REG_IPD);
+
+       /* are we finished? */
+       if (i2c->processed == i2c->msg->len)
+               rk3x_i2c_stop(i2c, i2c->error);
+       else
+               rk3x_i2c_fill_transmit_buf(i2c);
+}
+
+static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
+{
+       unsigned int i;
+       unsigned int len = i2c->msg->len - i2c->processed;
+       u32 uninitialized_var(val);
+       u8 byte;
+
+       /* we only care for MBRF here. */
+       if (!(ipd & REG_INT_MBRF))
+               return;
+
+       /* ack interrupt */
+       i2c_writel(i2c, REG_INT_MBRF, REG_IPD);
+
+       /* read the data from receive buffer */
+       for (i = 0; i < len; ++i) {
+               if (i % 4 == 0)
+                       val = i2c_readl(i2c, RXBUFFER_BASE + (i / 4) * 4);
+
+               byte = (val >> ((i % 4) * 8)) & 0xff;
+               i2c->msg->buf[i2c->processed++] = byte;
+       }
+
+       /* are we finished? */
+       if (i2c->processed == i2c->msg->len)
+               rk3x_i2c_stop(i2c, i2c->error);
+       else
+               rk3x_i2c_prepare_read(i2c);
+}
+
+static void rk3x_i2c_handle_stop(struct rk3x_i2c *i2c, unsigned int ipd)
+{
+       unsigned int con;
+
+       if (!(ipd & REG_INT_STOP)) {
+               rk3x_i2c_stop(i2c, -EIO);
+               dev_err(i2c->dev, "unexpected irq in STOP: 0x%x\n", ipd);
+               rk3x_i2c_clean_ipd(i2c);
+               return;
+       }
+
+       /* ack interrupt */
+       i2c_writel(i2c, REG_INT_STOP, REG_IPD);
+
+       /* disable STOP bit */
+       con = i2c_readl(i2c, REG_CON);
+       con &= ~REG_CON_STOP;
+       i2c_writel(i2c, con, REG_CON);
+
+       i2c->busy = false;
+       i2c->state = STATE_IDLE;
+
+       /* signal rk3x_i2c_xfer that we are finished */
+       wake_up(&i2c->wait);
+}
+
+static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
+{
+       struct rk3x_i2c *i2c = dev_id;
+       unsigned int ipd;
+
+       spin_lock(&i2c->lock);
+
+       ipd = i2c_readl(i2c, REG_IPD);
+       if (i2c->state == STATE_IDLE) {
+               dev_warn(i2c->dev, "irq in STATE_IDLE, ipd = 0x%x\n", ipd);
+               rk3x_i2c_clean_ipd(i2c);
+               goto out;
+       }
+
+       dev_dbg(i2c->dev, "IRQ: state %d, ipd: %x\n", i2c->state, ipd);
+
+       /* Clean interrupt bits we don't care about */
+       ipd &= ~(REG_INT_BRF | REG_INT_BTF);
+
+       if (ipd & REG_INT_NAKRCV) {
+               /*
+                * We got a NACK in the last operation. Depending on whether
+                * IGNORE_NAK is set, we have to stop the operation and report
+                * an error.
+                */
+               i2c_writel(i2c, REG_INT_NAKRCV, REG_IPD);
+
+               ipd &= ~REG_INT_NAKRCV;
+
+               if (!(i2c->msg->flags & I2C_M_IGNORE_NAK))
+                       rk3x_i2c_stop(i2c, -ENXIO);
+       }
+
+       /* is there anything left to handle? */
+       if (unlikely(ipd == 0))
+               goto out;
+
+       switch (i2c->state) {
+       case STATE_START:
+               rk3x_i2c_handle_start(i2c, ipd);
+               break;
+       case STATE_WRITE:
+               rk3x_i2c_handle_write(i2c, ipd);
+               break;
+       case STATE_READ:
+               rk3x_i2c_handle_read(i2c, ipd);
+               break;
+       case STATE_STOP:
+               rk3x_i2c_handle_stop(i2c, ipd);
+               break;
+       case STATE_IDLE:
+               break;
+       }
+
+out:
+       spin_unlock(&i2c->lock);
+       return IRQ_HANDLED;
+}
+
+static void rk3x_i2c_set_scl_rate(struct rk3x_i2c *i2c, unsigned long scl_rate)
+{
+       unsigned long i2c_rate = clk_get_rate(i2c->clk);
+       unsigned int div;
+
+       /* SCL rate = (clk rate) / (8 * DIV) */
+       div = DIV_ROUND_UP(i2c_rate, scl_rate * 8);
+
+       /* The lower and upper half of the CLKDIV reg describe the length of
+        * SCL low & high periods. */
+       div = DIV_ROUND_UP(div, 2);
+
+       i2c_writel(i2c, (div << 16) | (div & 0xffff), REG_CLKDIV);
+}
+
+/**
+ * Setup I2C registers for an I2C operation specified by msgs, num.
+ *
+ * Must be called with i2c->lock held.
+ *
+ * @msgs: I2C msgs to process
+ * @num: Number of msgs
+ *
+ * returns: Number of I2C msgs processed or negative in case of error
+ */
+static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num)
+{
+       u32 addr = (msgs[0].addr & 0x7f) << 1;
+       int ret = 0;
+
+       /*
+        * The I2C adapter can issue a small (len < 4) write packet before
+        * reading. This speeds up SMBus-style register reads.
+        * The MRXADDR/MRXRADDR hold the slave address and the slave register
+        * address in this case.
+        */
+
+       if (num >= 2 && msgs[0].len < 4 &&
+           !(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD)) {
+               u32 reg_addr = 0;
+               int i;
+
+               dev_dbg(i2c->dev, "Combined write/read from addr 0x%x\n",
+                       addr >> 1);
+
+               /* Fill MRXRADDR with the register address(es) */
+               for (i = 0; i < msgs[0].len; ++i) {
+                       reg_addr |= msgs[0].buf[i] << (i * 8);
+                       reg_addr |= REG_MRXADDR_VALID(i);
+               }
+
+               /* msgs[0] is handled by hw. */
+               i2c->msg = &msgs[1];
+
+               i2c->mode = REG_CON_MOD_REGISTER_TX;
+
+               i2c_writel(i2c, addr | REG_MRXADDR_VALID(0), REG_MRXADDR);
+               i2c_writel(i2c, reg_addr, REG_MRXRADDR);
+
+               ret = 2;
+       } else {
+               /*
+                * We'll have to do it the boring way and process the msgs
+                * one-by-one.
+                */
+
+               if (msgs[0].flags & I2C_M_RD) {
+                       addr |= 1; /* set read bit */
+
+                       /*
+                        * We have to transmit the slave addr first. Use
+                        * MOD_REGISTER_TX for that purpose.
+                        */
+                       i2c->mode = REG_CON_MOD_REGISTER_TX;
+                       i2c_writel(i2c, addr | REG_MRXADDR_VALID(0),
+                                  REG_MRXADDR);
+                       i2c_writel(i2c, 0, REG_MRXRADDR);
+               } else {
+                       i2c->mode = REG_CON_MOD_TX;
+               }
+
+               i2c->msg = &msgs[0];
+
+               ret = 1;
+       }
+
+       i2c->addr = msgs[0].addr;
+       i2c->busy = true;
+       i2c->state = STATE_START;
+       i2c->processed = 0;
+       i2c->error = 0;
+
+       rk3x_i2c_clean_ipd(i2c);
+
+       return ret;
+}
+
+static int rk3x_i2c_xfer(struct i2c_adapter *adap,
+                        struct i2c_msg *msgs, int num)
+{
+       struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data;
+       unsigned long timeout, flags;
+       int ret = 0;
+       int i;
+
+       spin_lock_irqsave(&i2c->lock, flags);
+
+       clk_enable(i2c->clk);
+
+       /* The clock rate might have changed, so setup the divider again */
+       rk3x_i2c_set_scl_rate(i2c, i2c->scl_frequency);
+
+       i2c->is_last_msg = false;
+
+       /*
+        * Process msgs. We can handle more than one message at once (see
+        * rk3x_i2c_setup()).
+        */
+       for (i = 0; i < num; i += ret) {
+               ret = rk3x_i2c_setup(i2c, msgs + i, num - i);
+
+               if (ret < 0) {
+                       dev_err(i2c->dev, "rk3x_i2c_setup() failed\n");
+                       break;
+               }
+
+               if (i + ret >= num)
+                       i2c->is_last_msg = true;
+
+               spin_unlock_irqrestore(&i2c->lock, flags);
+
+               rk3x_i2c_start(i2c);
+
+               timeout = wait_event_timeout(i2c->wait, !i2c->busy,
+                                            msecs_to_jiffies(WAIT_TIMEOUT));
+
+               spin_lock_irqsave(&i2c->lock, flags);
+
+               if (timeout == 0) {
+                       dev_err(i2c->dev, "timeout, ipd: 0x%02x, state: %d\n",
+                               i2c_readl(i2c, REG_IPD), i2c->state);
+
+                       /* Force a STOP condition without interrupt */
+                       i2c_writel(i2c, 0, REG_IEN);
+                       i2c_writel(i2c, REG_CON_EN | REG_CON_STOP, REG_CON);
+
+                       i2c->state = STATE_IDLE;
+
+                       ret = -ETIMEDOUT;
+                       break;
+               }
+
+               if (i2c->error) {
+                       ret = i2c->error;
+                       break;
+               }
+       }
+
+       clk_disable(i2c->clk);
+       spin_unlock_irqrestore(&i2c->lock, flags);
+
+       return ret;
+}
+
+static u32 rk3x_i2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
+}
+
+static const struct i2c_algorithm rk3x_i2c_algorithm = {
+       .master_xfer            = rk3x_i2c_xfer,
+       .functionality          = rk3x_i2c_func,
+};
+
+static struct rk3x_i2c_soc_data soc_data[3] = {
+       { .grf_offset = 0x154 }, /* rk3066 */
+       { .grf_offset = 0x0a4 }, /* rk3188 */
+       { .grf_offset = -1 },    /* no I2C switching needed */
+};
+
+static const struct of_device_id rk3x_i2c_match[] = {
+       { .compatible = "rockchip,rk3066-i2c", .data = (void *)&soc_data[0] },
+       { .compatible = "rockchip,rk3188-i2c", .data = (void *)&soc_data[1] },
+       { .compatible = "rockchip,rk3288-i2c", .data = (void *)&soc_data[2] },
+       {},
+};
+
+static int rk3x_i2c_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *match;
+       struct rk3x_i2c *i2c;
+       struct resource *mem;
+       int ret = 0;
+       int bus_nr;
+       u32 value;
+       int irq;
+
+       i2c = devm_kzalloc(&pdev->dev, sizeof(struct rk3x_i2c), GFP_KERNEL);
+       if (!i2c)
+               return -ENOMEM;
+
+       match = of_match_node(rk3x_i2c_match, np);
+       i2c->soc_data = (struct rk3x_i2c_soc_data *)match->data;
+
+       if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+                                &i2c->scl_frequency)) {
+               dev_info(&pdev->dev, "using default SCL frequency: %d\n",
+                        DEFAULT_SCL_RATE);
+               i2c->scl_frequency = DEFAULT_SCL_RATE;
+       }
+
+       if (i2c->scl_frequency == 0 || i2c->scl_frequency > 400 * 1000) {
+               dev_warn(&pdev->dev, "invalid SCL frequency specified.\n");
+               dev_warn(&pdev->dev, "using default SCL frequency: %d\n",
+                        DEFAULT_SCL_RATE);
+               i2c->scl_frequency = DEFAULT_SCL_RATE;
+       }
+
+       strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
+       i2c->adap.owner = THIS_MODULE;
+       i2c->adap.algo = &rk3x_i2c_algorithm;
+       i2c->adap.retries = 3;
+       i2c->adap.dev.of_node = np;
+       i2c->adap.algo_data = i2c;
+       i2c->adap.dev.parent = &pdev->dev;
+
+       i2c->dev = &pdev->dev;
+
+       spin_lock_init(&i2c->lock);
+       init_waitqueue_head(&i2c->wait);
+
+       i2c->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(i2c->clk)) {
+               dev_err(&pdev->dev, "cannot get clock\n");
+               return PTR_ERR(i2c->clk);
+       }
+
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
+       if (IS_ERR(i2c->regs))
+               return PTR_ERR(i2c->regs);
+
+       /* Try to set the I2C adapter number from dt */
+       bus_nr = of_alias_get_id(np, "i2c");
+
+       /*
+        * Switch to new interface if the SoC also offers the old one.
+        * The control bit is located in the GRF register space.
+        */
+       if (i2c->soc_data->grf_offset >= 0) {
+               struct regmap *grf;
+
+               grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+               if (IS_ERR(grf)) {
+                       dev_err(&pdev->dev,
+                               "rk3x-i2c needs 'rockchip,grf' property\n");
+                       return PTR_ERR(grf);
+               }
+
+               if (bus_nr < 0) {
+                       dev_err(&pdev->dev, "rk3x-i2c needs i2cX alias");
+                       return -EINVAL;
+               }
+
+               /* 27+i: write mask, 11+i: value */
+               value = BIT(27 + bus_nr) | BIT(11 + bus_nr);
+
+               ret = regmap_write(grf, i2c->soc_data->grf_offset, value);
+               if (ret != 0) {
+                       dev_err(i2c->dev, "Could not write to GRF: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       /* IRQ setup */
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "cannot find rk3x IRQ\n");
+               return irq;
+       }
+
+       ret = devm_request_irq(&pdev->dev, irq, rk3x_i2c_irq,
+                              0, dev_name(&pdev->dev), i2c);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "cannot request IRQ\n");
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, i2c);
+
+       ret = clk_prepare(i2c->clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Could not prepare clock\n");
+               return ret;
+       }
+
+       ret = i2c_add_adapter(&i2c->adap);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Could not register adapter\n");
+               goto err_clk;
+       }
+
+       dev_info(&pdev->dev, "Initialized RK3xxx I2C bus at %p\n", i2c->regs);
+
+       return 0;
+
+err_clk:
+       clk_unprepare(i2c->clk);
+       return ret;
+}
+
+static int rk3x_i2c_remove(struct platform_device *pdev)
+{
+       struct rk3x_i2c *i2c = platform_get_drvdata(pdev);
+
+       i2c_del_adapter(&i2c->adap);
+       clk_unprepare(i2c->clk);
+
+       return 0;
+}
+
+static struct platform_driver rk3x_i2c_driver = {
+       .probe   = rk3x_i2c_probe,
+       .remove  = rk3x_i2c_remove,
+       .driver  = {
+               .owner = THIS_MODULE,
+               .name  = "rk3x-i2c",
+               .of_match_table = rk3x_i2c_match,
+       },
+};
+
+module_platform_driver(rk3x_i2c_driver);
+
+MODULE_DESCRIPTION("Rockchip RK3xxx I2C Bus driver");
+MODULE_AUTHOR("Max Schwarz <max.schwarz@online.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
new file mode 100644 (file)
index 0000000..09de4fd
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * P2WI (Push-Pull Two Wire Interface) bus driver.
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * The P2WI controller looks like an SMBus controller which only supports byte
+ * data transfers. But, it differs from standard SMBus protocol on several
+ * aspects:
+ * - it supports only one slave device, and thus drop the address field
+ * - it adds a parity bit every 8bits of data
+ * - only one read access is required to read a byte (instead of a write
+ *   followed by a read access in standard SMBus protocol)
+ * - there's no Ack bit after each byte transfer
+ *
+ * This means this bus cannot be used to interface with standard SMBus
+ * devices (the only known device to support this interface is the AXP221
+ * PMIC).
+ *
+ */
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+
+/* P2WI registers */
+#define P2WI_CTRL              0x0
+#define P2WI_CCR               0x4
+#define P2WI_INTE              0x8
+#define P2WI_INTS              0xc
+#define P2WI_DADDR0            0x10
+#define P2WI_DADDR1            0x14
+#define P2WI_DLEN              0x18
+#define P2WI_DATA0             0x1c
+#define P2WI_DATA1             0x20
+#define P2WI_LCR               0x24
+#define P2WI_PMCR              0x28
+
+/* CTRL fields */
+#define P2WI_CTRL_START_TRANS          BIT(7)
+#define P2WI_CTRL_ABORT_TRANS          BIT(6)
+#define P2WI_CTRL_GLOBAL_INT_ENB       BIT(1)
+#define P2WI_CTRL_SOFT_RST             BIT(0)
+
+/* CLK CTRL fields */
+#define P2WI_CCR_SDA_OUT_DELAY(v)      (((v) & 0x7) << 8)
+#define P2WI_CCR_MAX_CLK_DIV           0xff
+#define P2WI_CCR_CLK_DIV(v)            ((v) & P2WI_CCR_MAX_CLK_DIV)
+
+/* STATUS fields */
+#define P2WI_INTS_TRANS_ERR_ID(v)      (((v) >> 8) & 0xff)
+#define P2WI_INTS_LOAD_BSY             BIT(2)
+#define P2WI_INTS_TRANS_ERR            BIT(1)
+#define P2WI_INTS_TRANS_OVER           BIT(0)
+
+/* DATA LENGTH fields*/
+#define P2WI_DLEN_READ                 BIT(4)
+#define P2WI_DLEN_DATA_LENGTH(v)       ((v - 1) & 0x7)
+
+/* LINE CTRL fields*/
+#define P2WI_LCR_SCL_STATE             BIT(5)
+#define P2WI_LCR_SDA_STATE             BIT(4)
+#define P2WI_LCR_SCL_CTL               BIT(3)
+#define P2WI_LCR_SCL_CTL_EN            BIT(2)
+#define P2WI_LCR_SDA_CTL               BIT(1)
+#define P2WI_LCR_SDA_CTL_EN            BIT(0)
+
+/* PMU MODE CTRL fields */
+#define P2WI_PMCR_PMU_INIT_SEND                BIT(31)
+#define P2WI_PMCR_PMU_INIT_DATA(v)     (((v) & 0xff) << 16)
+#define P2WI_PMCR_PMU_MODE_REG(v)      (((v) & 0xff) << 8)
+#define P2WI_PMCR_PMU_DEV_ADDR(v)      ((v) & 0xff)
+
+#define P2WI_MAX_FREQ                  6000000
+
+struct p2wi {
+       struct i2c_adapter adapter;
+       struct completion complete;
+       unsigned int status;
+       void __iomem *regs;
+       struct clk *clk;
+       struct reset_control *rstc;
+       int slave_addr;
+};
+
+static irqreturn_t p2wi_interrupt(int irq, void *dev_id)
+{
+       struct p2wi *p2wi = dev_id;
+       unsigned long status;
+
+       status = readl(p2wi->regs + P2WI_INTS);
+       p2wi->status = status;
+
+       /* Clear interrupts */
+       status &= (P2WI_INTS_LOAD_BSY | P2WI_INTS_TRANS_ERR |
+                  P2WI_INTS_TRANS_OVER);
+       writel(status, p2wi->regs + P2WI_INTS);
+
+       complete(&p2wi->complete);
+
+       return IRQ_HANDLED;
+}
+
+static u32 p2wi_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_SMBUS_BYTE_DATA;
+}
+
+static int p2wi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+                          unsigned short flags, char read_write,
+                          u8 command, int size, union i2c_smbus_data *data)
+{
+       struct p2wi *p2wi = i2c_get_adapdata(adap);
+       unsigned long dlen = P2WI_DLEN_DATA_LENGTH(1);
+
+       if (p2wi->slave_addr >= 0 && addr != p2wi->slave_addr) {
+               dev_err(&adap->dev, "invalid P2WI address\n");
+               return -EINVAL;
+       }
+
+       if (!data)
+               return -EINVAL;
+
+       writel(command, p2wi->regs + P2WI_DADDR0);
+
+       if (read_write == I2C_SMBUS_READ)
+               dlen |= P2WI_DLEN_READ;
+       else
+               writel(data->byte, p2wi->regs + P2WI_DATA0);
+
+       writel(dlen, p2wi->regs + P2WI_DLEN);
+
+       if (readl(p2wi->regs + P2WI_CTRL) & P2WI_CTRL_START_TRANS) {
+               dev_err(&adap->dev, "P2WI bus busy\n");
+               return -EBUSY;
+       }
+
+       reinit_completion(&p2wi->complete);
+
+       writel(P2WI_INTS_LOAD_BSY | P2WI_INTS_TRANS_ERR | P2WI_INTS_TRANS_OVER,
+              p2wi->regs + P2WI_INTE);
+
+       writel(P2WI_CTRL_START_TRANS | P2WI_CTRL_GLOBAL_INT_ENB,
+              p2wi->regs + P2WI_CTRL);
+
+       wait_for_completion(&p2wi->complete);
+
+       if (p2wi->status & P2WI_INTS_LOAD_BSY) {
+               dev_err(&adap->dev, "P2WI bus busy\n");
+               return -EBUSY;
+       }
+
+       if (p2wi->status & P2WI_INTS_TRANS_ERR) {
+               dev_err(&adap->dev, "P2WI bus xfer error\n");
+               return -ENXIO;
+       }
+
+       if (read_write == I2C_SMBUS_READ)
+               data->byte = readl(p2wi->regs + P2WI_DATA0);
+
+       return 0;
+}
+
+static const struct i2c_algorithm p2wi_algo = {
+       .smbus_xfer = p2wi_smbus_xfer,
+       .functionality = p2wi_functionality,
+};
+
+static const struct of_device_id p2wi_of_match_table[] = {
+       { .compatible = "allwinner,sun6i-a31-p2wi" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, p2wi_of_match_table);
+
+static int p2wi_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct device_node *childnp;
+       unsigned long parent_clk_freq;
+       u32 clk_freq = 100000;
+       struct resource *r;
+       struct p2wi *p2wi;
+       u32 slave_addr;
+       int clk_div;
+       int irq;
+       int ret;
+
+       of_property_read_u32(np, "clock-frequency", &clk_freq);
+       if (clk_freq > P2WI_MAX_FREQ) {
+               dev_err(dev,
+                       "required clock-frequency (%u Hz) is too high (max = 6MHz)",
+                       clk_freq);
+               return -EINVAL;
+       }
+
+       if (of_get_child_count(np) > 1) {
+               dev_err(dev, "P2WI only supports one slave device\n");
+               return -EINVAL;
+       }
+
+       p2wi = devm_kzalloc(dev, sizeof(struct p2wi), GFP_KERNEL);
+       if (!p2wi)
+               return -ENOMEM;
+
+       p2wi->slave_addr = -1;
+
+       /*
+        * Authorize a p2wi node without any children to be able to use an
+        * i2c-dev from userpace.
+        * In this case the slave_addr is set to -1 and won't be checked when
+        * launching a P2WI transfer.
+        */
+       childnp = of_get_next_available_child(np, NULL);
+       if (childnp) {
+               ret = of_property_read_u32(childnp, "reg", &slave_addr);
+               if (ret) {
+                       dev_err(dev, "invalid slave address on node %s\n",
+                               childnp->full_name);
+                       return -EINVAL;
+               }
+
+               p2wi->slave_addr = slave_addr;
+       }
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       p2wi->regs = devm_ioremap_resource(dev, r);
+       if (IS_ERR(p2wi->regs))
+               return PTR_ERR(p2wi->regs);
+
+       strlcpy(p2wi->adapter.name, pdev->name, sizeof(p2wi->adapter.name));
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(dev, "failed to retrieve irq: %d\n", irq);
+               return irq;
+       }
+
+       p2wi->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(p2wi->clk)) {
+               ret = PTR_ERR(p2wi->clk);
+               dev_err(dev, "failed to retrieve clk: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(p2wi->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable clk: %d\n", ret);
+               return ret;
+       }
+
+       parent_clk_freq = clk_get_rate(p2wi->clk);
+
+       p2wi->rstc = devm_reset_control_get(dev, NULL);
+       if (IS_ERR(p2wi->rstc)) {
+               ret = PTR_ERR(p2wi->rstc);
+               dev_err(dev, "failed to retrieve reset controller: %d\n", ret);
+               goto err_clk_disable;
+       }
+
+       ret = reset_control_deassert(p2wi->rstc);
+       if (ret) {
+               dev_err(dev, "failed to deassert reset line: %d\n", ret);
+               goto err_clk_disable;
+       }
+
+       init_completion(&p2wi->complete);
+       p2wi->adapter.dev.parent = dev;
+       p2wi->adapter.algo = &p2wi_algo;
+       p2wi->adapter.owner = THIS_MODULE;
+       p2wi->adapter.dev.of_node = pdev->dev.of_node;
+       platform_set_drvdata(pdev, p2wi);
+       i2c_set_adapdata(&p2wi->adapter, p2wi);
+
+       ret = devm_request_irq(dev, irq, p2wi_interrupt, 0, pdev->name, p2wi);
+       if (ret) {
+               dev_err(dev, "can't register interrupt handler irq%d: %d\n",
+                       irq, ret);
+               goto err_reset_assert;
+       }
+
+       writel(P2WI_CTRL_SOFT_RST, p2wi->regs + P2WI_CTRL);
+
+       clk_div = parent_clk_freq / clk_freq;
+       if (!clk_div) {
+               dev_warn(dev,
+                        "clock-frequency is too high, setting it to %lu Hz\n",
+                        parent_clk_freq);
+               clk_div = 1;
+       } else if (clk_div > P2WI_CCR_MAX_CLK_DIV) {
+               dev_warn(dev,
+                        "clock-frequency is too low, setting it to %lu Hz\n",
+                        parent_clk_freq / P2WI_CCR_MAX_CLK_DIV);
+               clk_div = P2WI_CCR_MAX_CLK_DIV;
+       }
+
+       writel(P2WI_CCR_SDA_OUT_DELAY(1) | P2WI_CCR_CLK_DIV(clk_div),
+              p2wi->regs + P2WI_CCR);
+
+       ret = i2c_add_adapter(&p2wi->adapter);
+       if (!ret)
+               return 0;
+
+err_reset_assert:
+       reset_control_assert(p2wi->rstc);
+
+err_clk_disable:
+       clk_disable_unprepare(p2wi->clk);
+
+       return ret;
+}
+
+static int p2wi_remove(struct platform_device *dev)
+{
+       struct p2wi *p2wi = platform_get_drvdata(dev);
+
+       reset_control_assert(p2wi->rstc);
+       clk_disable_unprepare(p2wi->clk);
+       i2c_del_adapter(&p2wi->adapter);
+
+       return 0;
+}
+
+static struct platform_driver p2wi_driver = {
+       .probe  = p2wi_probe,
+       .remove = p2wi_remove,
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "i2c-sunxi-p2wi",
+               .of_match_table = p2wi_of_match_table,
+       },
+};
+module_platform_driver(p2wi_driver);
+
+MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>");
+MODULE_DESCRIPTION("Allwinner P2WI driver");
+MODULE_LICENSE("GPL v2");
index 3b5bacd..2b6a9ce 100644 (file)
@@ -510,12 +510,11 @@ static int at91_adc_channel_init(struct iio_dev *idev)
        return idev->num_channels;
 }
 
-static u8 at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
+static int at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
                                             struct at91_adc_trigger *triggers,
                                             const char *trigger_name)
 {
        struct at91_adc_state *st = iio_priv(idev);
-       u8 value = 0;
        int i;
 
        for (i = 0; i < st->trigger_number; i++) {
@@ -528,15 +527,16 @@ static u8 at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
                        return -ENOMEM;
 
                if (strcmp(trigger_name, name) == 0) {
-                       value = triggers[i].value;
                        kfree(name);
-                       break;
+                       if (triggers[i].value == 0)
+                               return -EINVAL;
+                       return triggers[i].value;
                }
 
                kfree(name);
        }
 
-       return value;
+       return -EINVAL;
 }
 
 static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
@@ -546,14 +546,14 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
        struct iio_buffer *buffer = idev->buffer;
        struct at91_adc_reg_desc *reg = st->registers;
        u32 status = at91_adc_readl(st, reg->trigger_register);
-       u8 value;
+       int value;
        u8 bit;
 
        value = at91_adc_get_trigger_value_by_name(idev,
                                                   st->trigger_list,
                                                   idev->trig->name);
-       if (value == 0)
-               return -EINVAL;
+       if (value < 0)
+               return value;
 
        if (state) {
                st->buffer = kmalloc(idev->scan_bytes, GFP_KERNEL);
index 6989c16..b58d630 100644 (file)
@@ -121,8 +121,8 @@ static int men_z188_probe(struct mcb_device *dev,
        indio_dev->num_channels = ARRAY_SIZE(z188_adc_iio_channels);
 
        mem = mcb_request_mem(dev, "z188-adc");
-       if (!mem)
-               return -ENOMEM;
+       if (IS_ERR(mem))
+               return PTR_ERR(mem);
 
        adc->base = ioremap(mem->start, resource_size(mem));
        if (adc->base == NULL)
index 7de1c4c..eb86786 100644 (file)
@@ -645,6 +645,7 @@ int twl4030_get_madc_conversion(int channel_no)
        req.channels = (1 << channel_no);
        req.method = TWL4030_MADC_SW2;
        req.active = 0;
+       req.raw = 0;
        req.func_cb = NULL;
        ret = twl4030_madc_conversion(&req);
        if (ret < 0)
index 73282ce..a3109a6 100644 (file)
@@ -75,6 +75,9 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
                                        (s32)report_val);
        }
 
+       sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
+                                       st->power_state.index,
+                                       &state_val);
        return 0;
 }
 EXPORT_SYMBOL(hid_sensor_power_state);
index 09ea5c4..ea08313 100644 (file)
@@ -373,8 +373,6 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
 {
        struct ak8975_data *data = iio_priv(indio_dev);
        struct i2c_client *client = data->client;
-       u16 meas_reg;
-       s16 raw;
        int ret;
 
        mutex_lock(&data->lock);
@@ -422,16 +420,11 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
                dev_err(&client->dev, "Read axis data fails\n");
                goto exit;
        }
-       meas_reg = ret;
 
        mutex_unlock(&data->lock);
 
-       /* Endian conversion of the measured values. */
-       raw = (s16) (le16_to_cpu(meas_reg));
-
        /* Clamp to valid range. */
-       raw = clamp_t(s16, raw, -4096, 4095);
-       *val = raw;
+       *val = clamp_t(s16, ret, -4096, 4095);
        return IIO_VAL_INT;
 
 exit:
index ba6d0c5..01b2e0b 100644 (file)
@@ -98,7 +98,7 @@ static int mpl3115_read_raw(struct iio_dev *indio_dev,
                        mutex_unlock(&data->lock);
                        if (ret < 0)
                                return ret;
-                       *val = sign_extend32(be32_to_cpu(tmp) >> 12, 23);
+                       *val = be32_to_cpu(tmp) >> 12;
                        return IIO_VAL_INT;
                case IIO_TEMP: /* in 0.0625 celsius / LSB */
                        mutex_lock(&data->lock);
@@ -112,7 +112,7 @@ static int mpl3115_read_raw(struct iio_dev *indio_dev,
                        mutex_unlock(&data->lock);
                        if (ret < 0)
                                return ret;
-                       *val = sign_extend32(be32_to_cpu(tmp) >> 20, 15);
+                       *val = sign_extend32(be32_to_cpu(tmp) >> 20, 11);
                        return IIO_VAL_INT;
                default:
                        return -EINVAL;
@@ -185,7 +185,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
                        BIT(IIO_CHAN_INFO_SCALE),
                .scan_index = 0,
                .scan_type = {
-                       .sign = 's',
+                       .sign = 'u',
                        .realbits = 20,
                        .storagebits = 32,
                        .shift = 12,
index d4daa05..499b436 100644 (file)
@@ -45,7 +45,7 @@ struct pri_queue {
 struct pasid_state {
        struct list_head list;                  /* For global state-list */
        atomic_t count;                         /* Reference count */
-       atomic_t mmu_notifier_count;            /* Counting nested mmu_notifier
+       unsigned mmu_notifier_count;            /* Counting nested mmu_notifier
                                                   calls */
        struct task_struct *task;               /* Task bound to this PASID */
        struct mm_struct *mm;                   /* mm_struct for the faults */
@@ -53,7 +53,8 @@ struct pasid_state {
        struct pri_queue pri[PRI_QUEUE_SIZE];   /* PRI tag states */
        struct device_state *device_state;      /* Link to our device_state */
        int pasid;                              /* PASID index */
-       spinlock_t lock;                        /* Protect pri_queues */
+       spinlock_t lock;                        /* Protect pri_queues and
+                                                  mmu_notifer_count */
        wait_queue_head_t wq;                   /* To wait for count == 0 */
 };
 
@@ -431,15 +432,19 @@ static void mn_invalidate_range_start(struct mmu_notifier *mn,
 {
        struct pasid_state *pasid_state;
        struct device_state *dev_state;
+       unsigned long flags;
 
        pasid_state = mn_to_state(mn);
        dev_state   = pasid_state->device_state;
 
-       if (atomic_add_return(1, &pasid_state->mmu_notifier_count) == 1) {
+       spin_lock_irqsave(&pasid_state->lock, flags);
+       if (pasid_state->mmu_notifier_count == 0) {
                amd_iommu_domain_set_gcr3(dev_state->domain,
                                          pasid_state->pasid,
                                          __pa(empty_page_table));
        }
+       pasid_state->mmu_notifier_count += 1;
+       spin_unlock_irqrestore(&pasid_state->lock, flags);
 }
 
 static void mn_invalidate_range_end(struct mmu_notifier *mn,
@@ -448,15 +453,19 @@ static void mn_invalidate_range_end(struct mmu_notifier *mn,
 {
        struct pasid_state *pasid_state;
        struct device_state *dev_state;
+       unsigned long flags;
 
        pasid_state = mn_to_state(mn);
        dev_state   = pasid_state->device_state;
 
-       if (atomic_dec_and_test(&pasid_state->mmu_notifier_count)) {
+       spin_lock_irqsave(&pasid_state->lock, flags);
+       pasid_state->mmu_notifier_count -= 1;
+       if (pasid_state->mmu_notifier_count == 0) {
                amd_iommu_domain_set_gcr3(dev_state->domain,
                                          pasid_state->pasid,
                                          __pa(pasid_state->mm->pgd));
        }
+       spin_unlock_irqrestore(&pasid_state->lock, flags);
 }
 
 static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm)
@@ -650,7 +659,6 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid,
                goto out;
 
        atomic_set(&pasid_state->count, 1);
-       atomic_set(&pasid_state->mmu_notifier_count, 0);
        init_waitqueue_head(&pasid_state->wq);
        spin_lock_init(&pasid_state->lock);
 
index 6bb3277..51b6b77 100644 (file)
@@ -3816,14 +3816,11 @@ int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
                                ((void *)rmrr) + rmrr->header.length,
                                rmrr->segment, rmrru->devices,
                                rmrru->devices_cnt);
-                       if (ret > 0)
-                               break;
-                       else if(ret < 0)
+                       if(ret < 0)
                                return ret;
                } else if (info->event == BUS_NOTIFY_DEL_DEVICE) {
-                       if (dmar_remove_dev_scope(info, rmrr->segment,
-                               rmrru->devices, rmrru->devices_cnt))
-                               break;
+                       dmar_remove_dev_scope(info, rmrr->segment,
+                               rmrru->devices, rmrru->devices_cnt);
                }
        }
 
index d9edcc9..97465ac 100644 (file)
@@ -16,7 +16,7 @@ config ISDN_DRV_HISAX
          also to the configuration option of the driver for your particular
          card, below.
 
-if ISDN_DRV_HISAX!=n
+if ISDN_DRV_HISAX
 
 comment "D-channel protocol features"
 
@@ -348,10 +348,6 @@ config HISAX_ENTERNOW_PCI
          This enables HiSax support for the Formula-n enter:now PCI
          ISDN card.
 
-endif
-
-if ISDN_DRV_HISAX
-
 config HISAX_DEBUG
        bool "HiSax debugging"
        help
@@ -420,11 +416,6 @@ config HISAX_FRITZ_PCIPNP
          (the latter also needs you to select "ISA Plug and Play support"
          from the menu "Plug and Play configuration")
 
-config HISAX_AVM_A1_PCMCIA
-       bool
-       depends on HISAX_AVM_A1_CS
-       default y
-
 endif
 
 endmenu
index a1b044e..8736f69 100644 (file)
@@ -32,14 +32,6 @@ config LEDS_88PM860X
          This option enables support for on-chip LED drivers found on Marvell
          Semiconductor 88PM8606 PMIC.
 
-config LEDS_ATMEL_PWM
-       tristate "LED Support using Atmel PWM outputs"
-       depends on LEDS_CLASS
-       depends on ATMEL_PWM
-       help
-         This option enables support for LEDs driven using outputs
-         of the dedicated PWM controller found on newer Atmel SOCs.
-
 config LEDS_LM3530
        tristate "LCD Backlight driver for LM3530"
        depends on LEDS_CLASS
index 79c5155..3c03666 100644 (file)
@@ -6,7 +6,6 @@ obj-$(CONFIG_LEDS_TRIGGERS)             += led-triggers.o
 
 # LED Platform Drivers
 obj-$(CONFIG_LEDS_88PM860X)            += leds-88pm860x.o
-obj-$(CONFIG_LEDS_ATMEL_PWM)           += leds-atmel-pwm.o
 obj-$(CONFIG_LEDS_BD2802)              += leds-bd2802.o
 obj-$(CONFIG_LEDS_LOCOMO)              += leds-locomo.o
 obj-$(CONFIG_LEDS_LM3530)              += leds-lm3530.o
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
deleted file mode 100644 (file)
index 56cec8d..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/io.h>
-#include <linux/atmel_pwm.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-
-struct pwmled {
-       struct led_classdev     cdev;
-       struct pwm_channel      pwmc;
-       struct gpio_led         *desc;
-       u32                     mult;
-       u8                      active_low;
-};
-
-
-/*
- * For simplicity, we use "brightness" as if it were a linear function
- * of PWM duty cycle.  However, a logarithmic function of duty cycle is
- * probably a better match for perceived brightness: two is half as bright
- * as four, four is half as bright as eight, etc
- */
-static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
-{
-       struct pwmled            *led;
-
-       /* update the duty cycle for the *next* period */
-       led = container_of(cdev, struct pwmled, cdev);
-       pwm_channel_writel(&led->pwmc, PWM_CUPD, led->mult * (unsigned) b);
-}
-
-/*
- * NOTE:  we reuse the platform_data structure of GPIO leds,
- * but repurpose its "gpio" number as a PWM channel number.
- */
-static int pwmled_probe(struct platform_device *pdev)
-{
-       const struct gpio_led_platform_data     *pdata;
-       struct pwmled                           *leds;
-       int                                     i;
-       int                                     status;
-
-       pdata = dev_get_platdata(&pdev->dev);
-       if (!pdata || pdata->num_leds < 1)
-               return -ENODEV;
-
-       leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds),
-                       GFP_KERNEL);
-       if (!leds)
-               return -ENOMEM;
-
-       for (i = 0; i < pdata->num_leds; i++) {
-               struct pwmled           *led = leds + i;
-               const struct gpio_led   *dat = pdata->leds + i;
-               u32                     tmp;
-
-               led->cdev.name = dat->name;
-               led->cdev.brightness = LED_OFF;
-               led->cdev.brightness_set = pwmled_brightness;
-               led->cdev.default_trigger = dat->default_trigger;
-
-               led->active_low = dat->active_low;
-
-               status = pwm_channel_alloc(dat->gpio, &led->pwmc);
-               if (status < 0)
-                       goto err;
-
-               /*
-                * Prescale clock by 2^x, so PWM counts in low MHz.
-                * Start each cycle with the LED active, so increasing
-                * the duty cycle gives us more time on (== brighter).
-                */
-               tmp = 5;
-               if (!led->active_low)
-                       tmp |= PWM_CPR_CPOL;
-               pwm_channel_writel(&led->pwmc, PWM_CMR, tmp);
-
-               /*
-                * Pick a period so PWM cycles at 100+ Hz; and a multiplier
-                * for scaling duty cycle:  brightness * mult.
-                */
-               tmp = (led->pwmc.mck / (1 << 5)) / 100;
-               tmp /= 255;
-               led->mult = tmp;
-               pwm_channel_writel(&led->pwmc, PWM_CDTY,
-                               led->cdev.brightness * 255);
-               pwm_channel_writel(&led->pwmc, PWM_CPRD,
-                               LED_FULL * tmp);
-
-               pwm_channel_enable(&led->pwmc);
-
-               /* Hand it over to the LED framework */
-               status = led_classdev_register(&pdev->dev, &led->cdev);
-               if (status < 0) {
-                       pwm_channel_free(&led->pwmc);
-                       goto err;
-               }
-       }
-
-       platform_set_drvdata(pdev, leds);
-       return 0;
-
-err:
-       if (i > 0) {
-               for (i = i - 1; i >= 0; i--) {
-                       led_classdev_unregister(&leds[i].cdev);
-                       pwm_channel_free(&leds[i].pwmc);
-               }
-       }
-
-       return status;
-}
-
-static int pwmled_remove(struct platform_device *pdev)
-{
-       const struct gpio_led_platform_data     *pdata;
-       struct pwmled                           *leds;
-       unsigned                                i;
-
-       pdata = dev_get_platdata(&pdev->dev);
-       leds = platform_get_drvdata(pdev);
-
-       for (i = 0; i < pdata->num_leds; i++) {
-               struct pwmled           *led = leds + i;
-
-               led_classdev_unregister(&led->cdev);
-               pwm_channel_free(&led->pwmc);
-       }
-
-       return 0;
-}
-
-static struct platform_driver pwmled_driver = {
-       .driver = {
-               .name =         "leds-atmel-pwm",
-               .owner =        THIS_MODULE,
-       },
-       /* REVISIT add suspend() and resume() methods */
-       .probe =        pwmled_probe,
-       .remove =       pwmled_remove,
-};
-
-module_platform_driver(pwmled_driver);
-
-MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:leds-atmel-pwm");
index 23b4a3b..4eab93a 100644 (file)
@@ -1257,7 +1257,8 @@ static unsigned int smu_fpoll(struct file *file, poll_table *wait)
                if (pp->busy && pp->cmd.status != 1)
                        mask |= POLLIN;
                spin_unlock_irqrestore(&pp->lock, flags);
-       } if (pp->mode == smu_file_events) {
+       }
+       if (pp->mode == smu_file_events) {
                /* Not yet implemented */
        }
        return mask;
index 2a635b6..c880ba6 100644 (file)
@@ -601,6 +601,7 @@ static int rtsx_pci_ms_drv_remove(struct platform_device *pdev)
        pcr->slots[RTSX_MS_CARD].card_event = NULL;
        msh = host->msh;
        host->eject = true;
+       cancel_work_sync(&host->handle_req);
 
        mutex_lock(&host->host_mutex);
        if (host->req) {
index ee8204c..6cc4b6a 100644 (file)
@@ -760,6 +760,7 @@ config MFD_SYSCON
 config MFD_DAVINCI_VOICECODEC
        tristate
        select MFD_CORE
+       select REGMAP_MMIO
 
 config MFD_TI_AM335X_TSCADC
        tristate "TI ADC / Touch Screen chip support"
@@ -1225,7 +1226,7 @@ config MFD_WM8994
          functionaltiy of the device other drivers must be enabled.
 
 config MFD_STW481X
-       bool "Support for ST Microelectronics STw481x"
+       tristate "Support for ST Microelectronics STw481x"
        depends on I2C && ARCH_NOMADIK
        select REGMAP_I2C
        select MFD_CORE
@@ -1248,7 +1249,7 @@ config MCP_SA11X0
 
 # Chip drivers
 config MCP_UCB1200
-       bool "Support for UCB1200 / UCB1300"
+       tristate "Support for UCB1200 / UCB1300"
        depends on MCP_SA11X0
        select MCP
 
index a8ee4a3..cf2e6a1 100644 (file)
@@ -591,7 +591,7 @@ static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np)
                num_irqs = AB8500_NR_IRQS;
 
        /* If ->irq_base is zero this will give a linear mapping */
-       ab8500->domain = irq_domain_add_simple(NULL,
+       ab8500->domain = irq_domain_add_simple(ab8500->dev->of_node,
                        num_irqs, 0,
                        &ab8500_irq_ops, ab8500);
 
index a43d0c4..b841180 100644 (file)
@@ -51,16 +51,6 @@ config AD525X_DPOT_SPI
          To compile this driver as a module, choose M here: the
          module will be called ad525x_dpot-spi.
 
-config ATMEL_PWM
-       tristate "Atmel AT32/AT91 PWM support"
-       depends on HAVE_CLK
-       depends on AVR32 || AT91SAM9263 || AT91SAM9RL || AT91SAM9G45
-       help
-         This option enables device driver support for the PWM channels
-         on certain Atmel processors.  Pulse Width Modulation is used for
-         purposes including software controlled power-efficient backlights
-         on LCD displays, motor control, and waveform generation.
-
 config ATMEL_TCLIB
        bool "Atmel AT32/AT91 Timer/Counter Library"
        depends on (AVR32 || ARCH_AT91)
index d59ce12..5497d02 100644 (file)
@@ -7,7 +7,6 @@ obj-$(CONFIG_AD525X_DPOT)       += ad525x_dpot.o
 obj-$(CONFIG_AD525X_DPOT_I2C)  += ad525x_dpot-i2c.o
 obj-$(CONFIG_AD525X_DPOT_SPI)  += ad525x_dpot-spi.o
 obj-$(CONFIG_INTEL_MID_PTI)    += pti.o
-obj-$(CONFIG_ATMEL_PWM)                += atmel_pwm.o
 obj-$(CONFIG_ATMEL_SSC)                += atmel-ssc.o
 obj-$(CONFIG_ATMEL_TCLIB)      += atmel_tclib.o
 obj-$(CONFIG_BMP085)           += bmp085.o
diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c
deleted file mode 100644 (file)
index a6dc56e..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/atmel_pwm.h>
-
-
-/*
- * This is a simple driver for the PWM controller found in various newer
- * Atmel SOCs, including the AVR32 series and the AT91sam9263.
- *
- * Chips with current Linux ports have only 4 PWM channels, out of max 32.
- * AT32UC3A and AT32UC3B chips have 7 channels (but currently no Linux).
- * Docs are inconsistent about the width of the channel counter registers;
- * it's at least 16 bits, but several places say 20 bits.
- */
-#define        PWM_NCHAN       4               /* max 32 */
-
-struct pwm {
-       spinlock_t              lock;
-       struct platform_device  *pdev;
-       u32                     mask;
-       int                     irq;
-       void __iomem            *base;
-       struct clk              *clk;
-       struct pwm_channel      *channel[PWM_NCHAN];
-       void                    (*handler[PWM_NCHAN])(struct pwm_channel *);
-};
-
-
-/* global PWM controller registers */
-#define PWM_MR         0x00
-#define PWM_ENA                0x04
-#define PWM_DIS                0x08
-#define PWM_SR         0x0c
-#define PWM_IER                0x10
-#define PWM_IDR                0x14
-#define PWM_IMR                0x18
-#define PWM_ISR                0x1c
-
-static inline void pwm_writel(const struct pwm *p, unsigned offset, u32 val)
-{
-       __raw_writel(val, p->base + offset);
-}
-
-static inline u32 pwm_readl(const struct pwm *p, unsigned offset)
-{
-       return __raw_readl(p->base + offset);
-}
-
-static inline void __iomem *pwmc_regs(const struct pwm *p, int index)
-{
-       return p->base + 0x200 + index * 0x20;
-}
-
-static struct pwm *pwm;
-
-static void pwm_dumpregs(struct pwm_channel *ch, char *tag)
-{
-       struct device   *dev = &pwm->pdev->dev;
-
-       dev_dbg(dev, "%s: mr %08x, sr %08x, imr %08x\n",
-               tag,
-               pwm_readl(pwm, PWM_MR),
-               pwm_readl(pwm, PWM_SR),
-               pwm_readl(pwm, PWM_IMR));
-       dev_dbg(dev,
-               "pwm ch%d - mr %08x, dty %u, prd %u, cnt %u\n",
-               ch->index,
-               pwm_channel_readl(ch, PWM_CMR),
-               pwm_channel_readl(ch, PWM_CDTY),
-               pwm_channel_readl(ch, PWM_CPRD),
-               pwm_channel_readl(ch, PWM_CCNT));
-}
-
-
-/**
- * pwm_channel_alloc - allocate an unused PWM channel
- * @index: identifies the channel
- * @ch: structure to be initialized
- *
- * Drivers allocate PWM channels according to the board's wiring, and
- * matching board-specific setup code.  Returns zero or negative errno.
- */
-int pwm_channel_alloc(int index, struct pwm_channel *ch)
-{
-       unsigned long   flags;
-       int             status = 0;
-
-       if (!pwm)
-               return -EPROBE_DEFER;
-
-       if (!(pwm->mask & 1 << index))
-               return -ENODEV;
-
-       if (index < 0 || index >= PWM_NCHAN || !ch)
-               return -EINVAL;
-       memset(ch, 0, sizeof *ch);
-
-       spin_lock_irqsave(&pwm->lock, flags);
-       if (pwm->channel[index])
-               status = -EBUSY;
-       else {
-               clk_enable(pwm->clk);
-
-               ch->regs = pwmc_regs(pwm, index);
-               ch->index = index;
-
-               /* REVISIT: ap7000 seems to go 2x as fast as we expect!! */
-               ch->mck = clk_get_rate(pwm->clk);
-
-               pwm->channel[index] = ch;
-               pwm->handler[index] = NULL;
-
-               /* channel and irq are always disabled when we return */
-               pwm_writel(pwm, PWM_DIS, 1 << index);
-               pwm_writel(pwm, PWM_IDR, 1 << index);
-       }
-       spin_unlock_irqrestore(&pwm->lock, flags);
-       return status;
-}
-EXPORT_SYMBOL(pwm_channel_alloc);
-
-static int pwmcheck(struct pwm_channel *ch)
-{
-       int             index;
-
-       if (!pwm)
-               return -ENODEV;
-       if (!ch)
-               return -EINVAL;
-       index = ch->index;
-       if (index < 0 || index >= PWM_NCHAN || pwm->channel[index] != ch)
-               return -EINVAL;
-
-       return index;
-}
-
-/**
- * pwm_channel_free - release a previously allocated channel
- * @ch: the channel being released
- *
- * The channel is completely shut down (counter and IRQ disabled),
- * and made available for re-use.  Returns zero, or negative errno.
- */
-int pwm_channel_free(struct pwm_channel *ch)
-{
-       unsigned long   flags;
-       int             t;
-
-       spin_lock_irqsave(&pwm->lock, flags);
-       t = pwmcheck(ch);
-       if (t >= 0) {
-               pwm->channel[t] = NULL;
-               pwm->handler[t] = NULL;
-
-               /* channel and irq are always disabled when we return */
-               pwm_writel(pwm, PWM_DIS, 1 << t);
-               pwm_writel(pwm, PWM_IDR, 1 << t);
-
-               clk_disable(pwm->clk);
-               t = 0;
-       }
-       spin_unlock_irqrestore(&pwm->lock, flags);
-       return t;
-}
-EXPORT_SYMBOL(pwm_channel_free);
-
-int __pwm_channel_onoff(struct pwm_channel *ch, int enabled)
-{
-       unsigned long   flags;
-       int             t;
-
-       /* OMITTED FUNCTIONALITY:  starting several channels in synch */
-
-       spin_lock_irqsave(&pwm->lock, flags);
-       t = pwmcheck(ch);
-       if (t >= 0) {
-               pwm_writel(pwm, enabled ? PWM_ENA : PWM_DIS, 1 << t);
-               t = 0;
-               pwm_dumpregs(ch, enabled ? "enable" : "disable");
-       }
-       spin_unlock_irqrestore(&pwm->lock, flags);
-
-       return t;
-}
-EXPORT_SYMBOL(__pwm_channel_onoff);
-
-/**
- * pwm_clk_alloc - allocate and configure CLKA or CLKB
- * @prescale: from 0..10, the power of two used to divide MCK
- * @div: from 1..255, the linear divisor to use
- *
- * Returns PWM_CPR_CLKA, PWM_CPR_CLKB, or negative errno.  The allocated
- * clock will run with a period of (2^prescale * div) / MCK, or twice as
- * long if center aligned PWM output is used.  The clock must later be
- * deconfigured using pwm_clk_free().
- */
-int pwm_clk_alloc(unsigned prescale, unsigned div)
-{
-       unsigned long   flags;
-       u32             mr;
-       u32             val = (prescale << 8) | div;
-       int             ret = -EBUSY;
-
-       if (prescale >= 10 || div == 0 || div > 255)
-               return -EINVAL;
-
-       spin_lock_irqsave(&pwm->lock, flags);
-       mr = pwm_readl(pwm, PWM_MR);
-       if ((mr & 0xffff) == 0) {
-               mr |= val;
-               ret = PWM_CPR_CLKA;
-       } else if ((mr & (0xffff << 16)) == 0) {
-               mr |= val << 16;
-               ret = PWM_CPR_CLKB;
-       }
-       if (ret > 0)
-               pwm_writel(pwm, PWM_MR, mr);
-       spin_unlock_irqrestore(&pwm->lock, flags);
-       return ret;
-}
-EXPORT_SYMBOL(pwm_clk_alloc);
-
-/**
- * pwm_clk_free - deconfigure and release CLKA or CLKB
- *
- * Reverses the effect of pwm_clk_alloc().
- */
-void pwm_clk_free(unsigned clk)
-{
-       unsigned long   flags;
-       u32             mr;
-
-       spin_lock_irqsave(&pwm->lock, flags);
-       mr = pwm_readl(pwm, PWM_MR);
-       if (clk == PWM_CPR_CLKA)
-               pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 0));
-       if (clk == PWM_CPR_CLKB)
-               pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 16));
-       spin_unlock_irqrestore(&pwm->lock, flags);
-}
-EXPORT_SYMBOL(pwm_clk_free);
-
-/**
- * pwm_channel_handler - manage channel's IRQ handler
- * @ch: the channel
- * @handler: the handler to use, possibly NULL
- *
- * If the handler is non-null, the handler will be called after every
- * period of this PWM channel.  If the handler is null, this channel
- * won't generate an IRQ.
- */
-int pwm_channel_handler(struct pwm_channel *ch,
-               void (*handler)(struct pwm_channel *ch))
-{
-       unsigned long   flags;
-       int             t;
-
-       spin_lock_irqsave(&pwm->lock, flags);
-       t = pwmcheck(ch);
-       if (t >= 0) {
-               pwm->handler[t] = handler;
-               pwm_writel(pwm, handler ? PWM_IER : PWM_IDR, 1 << t);
-               t = 0;
-       }
-       spin_unlock_irqrestore(&pwm->lock, flags);
-
-       return t;
-}
-EXPORT_SYMBOL(pwm_channel_handler);
-
-static irqreturn_t pwm_irq(int id, void *_pwm)
-{
-       struct pwm      *p = _pwm;
-       irqreturn_t     handled = IRQ_NONE;
-       u32             irqstat;
-       int             index;
-
-       spin_lock(&p->lock);
-
-       /* ack irqs, then handle them */
-       irqstat = pwm_readl(pwm, PWM_ISR);
-
-       while (irqstat) {
-               struct pwm_channel *ch;
-               void (*handler)(struct pwm_channel *ch);
-
-               index = ffs(irqstat) - 1;
-               irqstat &= ~(1 << index);
-               ch = pwm->channel[index];
-               handler = pwm->handler[index];
-               if (handler && ch) {
-                       spin_unlock(&p->lock);
-                       handler(ch);
-                       spin_lock(&p->lock);
-                       handled = IRQ_HANDLED;
-               }
-       }
-
-       spin_unlock(&p->lock);
-       return handled;
-}
-
-static int __init pwm_probe(struct platform_device *pdev)
-{
-       struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       int irq = platform_get_irq(pdev, 0);
-       u32 *mp = pdev->dev.platform_data;
-       struct pwm *p;
-       int status = -EIO;
-
-       if (pwm)
-               return -EBUSY;
-       if (!r || irq < 0 || !mp || !*mp)
-               return -ENODEV;
-       if (*mp & ~((1<<PWM_NCHAN)-1)) {
-               dev_warn(&pdev->dev, "mask 0x%x ... more than %d channels\n",
-                       *mp, PWM_NCHAN);
-               return -EINVAL;
-       }
-
-       p = kzalloc(sizeof(*p), GFP_KERNEL);
-       if (!p)
-               return -ENOMEM;
-
-       spin_lock_init(&p->lock);
-       p->pdev = pdev;
-       p->mask = *mp;
-       p->irq = irq;
-       p->base = ioremap(r->start, resource_size(r));
-       if (!p->base)
-               goto fail;
-       p->clk = clk_get(&pdev->dev, "pwm_clk");
-       if (IS_ERR(p->clk)) {
-               status = PTR_ERR(p->clk);
-               p->clk = NULL;
-               goto fail;
-       }
-
-       status = request_irq(irq, pwm_irq, 0, pdev->name, p);
-       if (status < 0)
-               goto fail;
-
-       pwm = p;
-       platform_set_drvdata(pdev, p);
-
-       return 0;
-
-fail:
-       if (p->clk)
-               clk_put(p->clk);
-       if (p->base)
-               iounmap(p->base);
-
-       kfree(p);
-       return status;
-}
-
-static int __exit pwm_remove(struct platform_device *pdev)
-{
-       struct pwm *p = platform_get_drvdata(pdev);
-
-       if (p != pwm)
-               return -EINVAL;
-
-       clk_enable(pwm->clk);
-       pwm_writel(pwm, PWM_DIS, (1 << PWM_NCHAN) - 1);
-       pwm_writel(pwm, PWM_IDR, (1 << PWM_NCHAN) - 1);
-       clk_disable(pwm->clk);
-
-       pwm = NULL;
-
-       free_irq(p->irq, p);
-       clk_put(p->clk);
-       iounmap(p->base);
-       kfree(p);
-
-       return 0;
-}
-
-static struct platform_driver atmel_pwm_driver = {
-       .driver = {
-               .name = "atmel_pwm",
-               .owner = THIS_MODULE,
-       },
-       .remove = __exit_p(pwm_remove),
-
-       /* NOTE: PWM can keep running in AVR32 "idle" and "frozen" states;
-        * and all AT91sam9263 states, albeit at reduced clock rate if
-        * MCK becomes the slow clock (i.e. what Linux labels STR).
-        */
-};
-
-module_platform_driver_probe(atmel_pwm_driver, pwm_probe);
-
-MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:atmel_pwm");
index 73068e5..3250fc1 100644 (file)
@@ -199,7 +199,7 @@ static struct regmap *vexpress_syscfg_regmap_init(struct device *dev,
        func = kzalloc(sizeof(*func) + sizeof(*func->template) * num,
                        GFP_KERNEL);
        if (!func)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        func->syscfg = syscfg;
        func->num_templates = num;
@@ -231,10 +231,14 @@ static struct regmap *vexpress_syscfg_regmap_init(struct device *dev,
        func->regmap = regmap_init(dev, NULL, func,
                        &vexpress_syscfg_regmap_config);
 
-       if (IS_ERR(func->regmap))
+       if (IS_ERR(func->regmap)) {
+               void *err = func->regmap;
+
                kfree(func);
-       else
-               list_add(&func->list, &syscfg->funcs);
+               return err;
+       }
+
+       list_add(&func->list, &syscfg->funcs);
 
        return func->regmap;
 }
index 2421835..1916174 100644 (file)
@@ -17,7 +17,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Maintained by: Dmitry Torokhov <dtor@vmware.com>
+ * Maintained by:      Xavier Deguillard <xdeguillard@vmware.com>
+ *                     Philip Moltmann <moltmann@vmware.com>
  */
 
 /*
index 04f35f9..3a451b6 100644 (file)
@@ -1025,10 +1025,14 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
                                 NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
                                 NETIF_F_HIGHDMA | NETIF_F_LRO)
 
+#define BOND_ENC_FEATURES      (NETIF_F_ALL_CSUM | NETIF_F_SG | NETIF_F_RXCSUM |\
+                                NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL)
+
 static void bond_compute_features(struct bonding *bond)
 {
        unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
        netdev_features_t vlan_features = BOND_VLAN_FEATURES;
+       netdev_features_t enc_features  = BOND_ENC_FEATURES;
        struct net_device *bond_dev = bond->dev;
        struct list_head *iter;
        struct slave *slave;
@@ -1044,6 +1048,9 @@ static void bond_compute_features(struct bonding *bond)
                vlan_features = netdev_increment_features(vlan_features,
                        slave->dev->vlan_features, BOND_VLAN_FEATURES);
 
+               enc_features = netdev_increment_features(enc_features,
+                                                        slave->dev->hw_enc_features,
+                                                        BOND_ENC_FEATURES);
                dst_release_flag &= slave->dev->priv_flags;
                if (slave->dev->hard_header_len > max_hard_header_len)
                        max_hard_header_len = slave->dev->hard_header_len;
@@ -1054,6 +1061,7 @@ static void bond_compute_features(struct bonding *bond)
 
 done:
        bond_dev->vlan_features = vlan_features;
+       bond_dev->hw_enc_features = enc_features;
        bond_dev->hard_header_len = max_hard_header_len;
        bond_dev->gso_max_segs = gso_max_segs;
        netif_set_gso_max_size(bond_dev, gso_max_size);
@@ -3975,6 +3983,7 @@ void bond_setup(struct net_device *bond_dev)
                                NETIF_F_HW_VLAN_CTAG_FILTER;
 
        bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
+       bond_dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
        bond_dev->features |= bond_dev->hw_features;
 }
 
index dcf9196..ea4d4f1 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/workqueue.h>
 #include <linux/can.h>
 #include <linux/can/skb.h>
 
@@ -85,6 +86,7 @@ struct slcan {
        struct tty_struct       *tty;           /* ptr to TTY structure      */
        struct net_device       *dev;           /* easy for intr handling    */
        spinlock_t              lock;
+       struct work_struct      tx_work;        /* Flushes transmit buffer   */
 
        /* These are pointers to the malloc()ed frame buffers. */
        unsigned char           rbuff[SLC_MTU]; /* receiver buffer           */
@@ -309,36 +311,46 @@ static void slc_encaps(struct slcan *sl, struct can_frame *cf)
        sl->dev->stats.tx_bytes += cf->can_dlc;
 }
 
-/*
- * Called by the driver when there's room for more data.  If we have
- * more packets to send, we send them here.
- */
-static void slcan_write_wakeup(struct tty_struct *tty)
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void slcan_transmit(struct work_struct *work)
 {
+       struct slcan *sl = container_of(work, struct slcan, tx_work);
        int actual;
-       struct slcan *sl = (struct slcan *) tty->disc_data;
 
+       spin_lock_bh(&sl->lock);
        /* First make sure we're connected. */
-       if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
+       if (!sl->tty || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) {
+               spin_unlock_bh(&sl->lock);
                return;
+       }
 
-       spin_lock_bh(&sl->lock);
        if (sl->xleft <= 0)  {
                /* Now serial buffer is almost free & we can start
                 * transmission of another packet */
                sl->dev->stats.tx_packets++;
-               clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+               clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
                spin_unlock_bh(&sl->lock);
                netif_wake_queue(sl->dev);
                return;
        }
 
-       actual = tty->ops->write(tty, sl->xhead, sl->xleft);
+       actual = sl->tty->ops->write(sl->tty, sl->xhead, sl->xleft);
        sl->xleft -= actual;
        sl->xhead += actual;
        spin_unlock_bh(&sl->lock);
 }
 
+/*
+ * Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void slcan_write_wakeup(struct tty_struct *tty)
+{
+       struct slcan *sl = tty->disc_data;
+
+       schedule_work(&sl->tx_work);
+}
+
 /* Send a can_frame to a TTY queue. */
 static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -528,6 +540,7 @@ static struct slcan *slc_alloc(dev_t line)
        sl->magic = SLCAN_MAGIC;
        sl->dev = dev;
        spin_lock_init(&sl->lock);
+       INIT_WORK(&sl->tx_work, slcan_transmit);
        slcan_devs[i] = dev;
 
        return sl;
@@ -626,8 +639,12 @@ static void slcan_close(struct tty_struct *tty)
        if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
                return;
 
+       spin_lock_bh(&sl->lock);
        tty->disc_data = NULL;
        sl->tty = NULL;
+       spin_unlock_bh(&sl->lock);
+
+       flush_work(&sl->tx_work);
 
        /* Flush network side */
        unregister_netdev(sl->dev);
index 2846067..d81e716 100644 (file)
@@ -736,6 +736,7 @@ static int emac_open(struct net_device *dev)
 
        ret = emac_mdio_probe(dev);
        if (ret < 0) {
+               free_irq(dev->irq, dev);
                netdev_err(dev, "cannot probe MDIO bus\n");
                return ret;
        }
index df2792d..8afa579 100644 (file)
@@ -3224,7 +3224,7 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
        return 0;
 }
 
-#define NVRAM_CMD_TIMEOUT 100
+#define NVRAM_CMD_TIMEOUT 5000
 
 static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
 {
@@ -3232,7 +3232,7 @@ static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
 
        tw32(NVRAM_CMD, nvram_cmd);
        for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
-               udelay(10);
+               usleep_range(10, 40);
                if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
                        udelay(10);
                        break;
@@ -7854,8 +7854,8 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
                netif_wake_queue(tp->dev);
        }
 
-       segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO);
-       if (IS_ERR(segs))
+       segs = skb_gso_segment(skb, tp->dev->features & ~(NETIF_F_TSO | NETIF_F_TSO6));
+       if (IS_ERR(segs) || !segs)
                goto tg3_tso_bug_end;
 
        do {
index 2f8d6b9..a83271c 100644 (file)
@@ -4057,22 +4057,19 @@ int cxgb4_unregister_uld(enum cxgb4_uld type)
 EXPORT_SYMBOL(cxgb4_unregister_uld);
 
 /* Check if netdev on which event is occured belongs to us or not. Return
- * suceess (1) if it belongs otherwise failure (0).
+ * success (true) if it belongs otherwise failure (false).
+ * Called with rcu_read_lock() held.
  */
-static int cxgb4_netdev(struct net_device *netdev)
+static bool cxgb4_netdev(const struct net_device *netdev)
 {
        struct adapter *adap;
        int i;
 
-       spin_lock(&adap_rcu_lock);
        list_for_each_entry_rcu(adap, &adap_rcu_list, rcu_node)
                for (i = 0; i < MAX_NPORTS; i++)
-                       if (adap->port[i] == netdev) {
-                               spin_unlock(&adap_rcu_lock);
-                               return 1;
-                       }
-       spin_unlock(&adap_rcu_lock);
-       return 0;
+                       if (adap->port[i] == netdev)
+                               return true;
+       return false;
 }
 
 static int clip_add(struct net_device *event_dev, struct inet6_ifaddr *ifa,
@@ -6396,6 +6393,7 @@ static void remove_one(struct pci_dev *pdev)
                        adapter->flags &= ~DEV_ENABLED;
                }
                pci_release_regions(pdev);
+               synchronize_rcu();
                kfree(adapter);
        } else
                pci_release_regions(pdev);
index bba6768..931478e 100644 (file)
@@ -3962,6 +3962,7 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
                p->lport = j;
                p->rss_size = rss_size;
                memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
+               adap->port[i]->dev_port = j;
 
                ret = ntohl(c.u.info.lstatus_to_modtype);
                p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ?
index 768379b..523d9dd 100644 (file)
@@ -158,7 +158,7 @@ void comet_timer(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
        struct tulip_private *tp = netdev_priv(dev);
-       int next_tick = 60*HZ;
+       int next_tick = 2*HZ;
 
        if (tulip_debug > 1)
                netdev_dbg(dev, "Comet link status %04x partner capability %04x\n",
index 2e7c555..c2f5d2d 100644 (file)
@@ -557,9 +557,7 @@ static inline u16 be_max_qs(struct be_adapter *adapter)
 #define be_pvid_tagging_enabled(adapter)       (adapter->pvid)
 
 /* Is BE in QNQ multi-channel mode */
-#define be_is_qnq_mode(adapter)                (adapter->mc_type == FLEX10 ||  \
-                                        adapter->mc_type == vNIC1 ||   \
-                                        adapter->mc_type == UFP)
+#define be_is_qnq_mode(adapter)                (adapter->function_mode & QNQ_MODE)
 
 #define lancer_chip(adapter)   (adapter->pdev->device == OC_DEVICE_ID3 || \
                                 adapter->pdev->device == OC_DEVICE_ID4)
index 3e0a6b2..59b3c05 100644 (file)
@@ -1091,7 +1091,7 @@ struct be_cmd_resp_modify_eq_delay {
  * based on the skew/IPL.
  */
 #define RDMA_ENABLED                           0x4
-#define FLEX10_MODE                            0x400
+#define QNQ_MODE                               0x400
 #define VNIC_MODE                              0x20000
 #define UMC_ENABLED                            0x1000000
 struct be_cmd_req_query_fw_cfg {
index 6822b3d..34a26e4 100644 (file)
@@ -3254,9 +3254,9 @@ err:
 
 static u8 be_convert_mc_type(u32 function_mode)
 {
-       if (function_mode & VNIC_MODE && function_mode & FLEX10_MODE)
+       if (function_mode & VNIC_MODE && function_mode & QNQ_MODE)
                return vNIC1;
-       else if (function_mode & FLEX10_MODE)
+       else if (function_mode & QNQ_MODE)
                return FLEX10;
        else if (function_mode & VNIC_MODE)
                return vNIC2;
index 38d9d27..77037fd 100644 (file)
@@ -320,6 +320,11 @@ static void *swap_buffer(void *bufaddr, int len)
        return bufaddr;
 }
 
+static inline bool is_ipv4_pkt(struct sk_buff *skb)
+{
+       return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
+}
+
 static int
 fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
 {
@@ -330,7 +335,8 @@ fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
        if (unlikely(skb_cow_head(skb, 0)))
                return -1;
 
-       ip_hdr(skb)->check = 0;
+       if (is_ipv4_pkt(skb))
+               ip_hdr(skb)->check = 0;
        *(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) = 0;
 
        return 0;
index 7f81ae6..e912b68 100644 (file)
@@ -4199,6 +4199,13 @@ static struct dmi_system_id skge_32bit_dma_boards[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "P5NSLI")
                },
        },
+       {
+               .ident = "FUJITSU SIEMENS A8NE-FM",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "A8NE-FM")
+               },
+       },
        {}
 };
 
index 5f42f6d..82ab427 100644 (file)
@@ -2439,7 +2439,8 @@ slave_start:
                            (num_vfs_argc > 1 || probe_vfs_argc > 1)) {
                                mlx4_err(dev,
                                         "Invalid syntax of num_vfs/probe_vfs with IB port - single port VFs syntax is only supported when all ports are configured as ethernet\n");
-                               goto err_close;
+                               err = -EINVAL;
+                               goto err_master_mfunc;
                        }
                        for (i = 0; i < sizeof(nvfs)/sizeof(nvfs[0]); i++) {
                                unsigned j;
index ff380da..b988d16 100644 (file)
@@ -1212,7 +1212,12 @@ static int cpsw_ndo_open(struct net_device *ndev)
        for_each_slave(priv, cpsw_slave_open, priv);
 
        /* Add default VLAN */
-       cpsw_add_default_vlan(priv);
+       if (!priv->data.dual_emac)
+               cpsw_add_default_vlan(priv);
+       else
+               cpsw_ale_add_vlan(priv->ale, priv->data.default_vlan,
+                                 ALE_ALL_PORTS << priv->host_port,
+                                 ALE_ALL_PORTS << priv->host_port, 0, 0);
 
        if (!cpsw_common_res_usage_state(priv)) {
                /* setup tx dma to fixed prio and zero offset */
index 14389f8..4c70360 100644 (file)
@@ -2191,7 +2191,6 @@ static void tile_net_setup(struct net_device *dev)
 static void tile_net_dev_init(const char *name, const uint8_t *mac)
 {
        int ret;
-       int i;
        struct net_device *dev;
        struct tile_net_priv *priv;
 
index c041f63..4ed38ea 100644 (file)
@@ -189,7 +189,7 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device)
                                   "unable to teardown send buffer's gpadl\n");
                        return ret;
                }
-               net_device->recv_buf_gpadl_handle = 0;
+               net_device->send_buf_gpadl_handle = 0;
        }
        if (net_device->send_buf) {
                /* Free up the receive buffer */
index 4517b14..5089941 100644 (file)
@@ -1137,6 +1137,8 @@ static int at86rf230_probe(struct spi_device *spi)
        dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
 
        irq_type = irq_get_trigger_type(spi->irq);
+       if (!irq_type)
+               irq_type = IRQF_TRIGGER_RISING;
        if (irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
                irq_worker = at86rf230_irqwork;
                irq_handler = at86rf230_isr;
@@ -1168,7 +1170,8 @@ static int at86rf230_probe(struct spi_device *spi)
        if (rc)
                goto err_hw_init;
 
-       rc = devm_request_irq(&spi->dev, spi->irq, irq_handler, IRQF_SHARED,
+       rc = devm_request_irq(&spi->dev, spi->irq, irq_handler,
+                             IRQF_SHARED | irq_type,
                              dev_name(&spi->dev), lp);
        if (rc)
                goto err_hw_init;
index 6c622ae..fdc1b41 100644 (file)
 #include <linux/string.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
 
 #define AT803X_INTR_ENABLE                     0x12
 #define AT803X_INTR_STATUS                     0x13
+#define AT803X_SMART_SPEED                     0x14
+#define AT803X_LED_CONTROL                     0x18
 #define AT803X_WOL_ENABLE                      0x01
 #define AT803X_DEVICE_ADDR                     0x03
 #define AT803X_LOC_MAC_ADDR_0_15_OFFSET                0x804C
 #define AT803X_DEBUG_SYSTEM_MODE_CTRL          0x05
 #define AT803X_DEBUG_RGMII_TX_CLK_DLY          BIT(8)
 
+#define ATH8030_PHY_ID 0x004dd076
+#define ATH8031_PHY_ID 0x004dd074
+#define ATH8035_PHY_ID 0x004dd072
+
 MODULE_DESCRIPTION("Atheros 803x PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
 
+struct at803x_priv {
+       bool phy_reset:1;
+       struct gpio_desc *gpiod_reset;
+};
+
+struct at803x_context {
+       u16 bmcr;
+       u16 advertise;
+       u16 control1000;
+       u16 int_enable;
+       u16 smart_speed;
+       u16 led_control;
+};
+
+/* save relevant PHY registers to private copy */
+static void at803x_context_save(struct phy_device *phydev,
+                               struct at803x_context *context)
+{
+       context->bmcr = phy_read(phydev, MII_BMCR);
+       context->advertise = phy_read(phydev, MII_ADVERTISE);
+       context->control1000 = phy_read(phydev, MII_CTRL1000);
+       context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE);
+       context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED);
+       context->led_control = phy_read(phydev, AT803X_LED_CONTROL);
+}
+
+/* restore relevant PHY registers from private copy */
+static void at803x_context_restore(struct phy_device *phydev,
+                                  const struct at803x_context *context)
+{
+       phy_write(phydev, MII_BMCR, context->bmcr);
+       phy_write(phydev, MII_ADVERTISE, context->advertise);
+       phy_write(phydev, MII_CTRL1000, context->control1000);
+       phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable);
+       phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed);
+       phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
+}
+
 static int at803x_set_wol(struct phy_device *phydev,
                          struct ethtool_wolinfo *wol)
 {
@@ -142,6 +188,26 @@ static int at803x_resume(struct phy_device *phydev)
        return 0;
 }
 
+static int at803x_probe(struct phy_device *phydev)
+{
+       struct device *dev = &phydev->dev;
+       struct at803x_priv *priv;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->gpiod_reset = devm_gpiod_get(dev, "reset");
+       if (IS_ERR(priv->gpiod_reset))
+               priv->gpiod_reset = NULL;
+       else
+               gpiod_direction_output(priv->gpiod_reset, 1);
+
+       phydev->priv = priv;
+
+       return 0;
+}
+
 static int at803x_config_init(struct phy_device *phydev)
 {
        int ret;
@@ -189,58 +255,99 @@ static int at803x_config_intr(struct phy_device *phydev)
        return err;
 }
 
+static void at803x_link_change_notify(struct phy_device *phydev)
+{
+       struct at803x_priv *priv = phydev->priv;
+
+       /*
+        * Conduct a hardware reset for AT8030 every time a link loss is
+        * signalled. This is necessary to circumvent a hardware bug that
+        * occurs when the cable is unplugged while TX packets are pending
+        * in the FIFO. In such cases, the FIFO enters an error mode it
+        * cannot recover from by software.
+        */
+       if (phydev->drv->phy_id == ATH8030_PHY_ID) {
+               if (phydev->state == PHY_NOLINK) {
+                       if (priv->gpiod_reset && !priv->phy_reset) {
+                               struct at803x_context context;
+
+                               at803x_context_save(phydev, &context);
+
+                               gpiod_set_value(priv->gpiod_reset, 0);
+                               msleep(1);
+                               gpiod_set_value(priv->gpiod_reset, 1);
+                               msleep(1);
+
+                               at803x_context_restore(phydev, &context);
+
+                               dev_dbg(&phydev->dev, "%s(): phy was reset\n",
+                                       __func__);
+                               priv->phy_reset = true;
+                       }
+               } else {
+                       priv->phy_reset = false;
+               }
+       }
+}
+
 static struct phy_driver at803x_driver[] = {
 {
        /* ATHEROS 8035 */
-       .phy_id         = 0x004dd072,
-       .name           = "Atheros 8035 ethernet",
-       .phy_id_mask    = 0xffffffef,
-       .config_init    = at803x_config_init,
-       .set_wol        = at803x_set_wol,
-       .get_wol        = at803x_get_wol,
-       .suspend        = at803x_suspend,
-       .resume         = at803x_resume,
-       .features       = PHY_GBIT_FEATURES,
-       .flags          = PHY_HAS_INTERRUPT,
-       .config_aneg    = genphy_config_aneg,
-       .read_status    = genphy_read_status,
-       .driver         = {
+       .phy_id                 = ATH8035_PHY_ID,
+       .name                   = "Atheros 8035 ethernet",
+       .phy_id_mask            = 0xffffffef,
+       .probe                  = at803x_probe,
+       .config_init            = at803x_config_init,
+       .link_change_notify     = at803x_link_change_notify,
+       .set_wol                = at803x_set_wol,
+       .get_wol                = at803x_get_wol,
+       .suspend                = at803x_suspend,
+       .resume                 = at803x_resume,
+       .features               = PHY_GBIT_FEATURES,
+       .flags                  = PHY_HAS_INTERRUPT,
+       .config_aneg            = genphy_config_aneg,
+       .read_status            = genphy_read_status,
+       .driver                 = {
                .owner = THIS_MODULE,
        },
 }, {
        /* ATHEROS 8030 */
-       .phy_id         = 0x004dd076,
-       .name           = "Atheros 8030 ethernet",
-       .phy_id_mask    = 0xffffffef,
-       .config_init    = at803x_config_init,
-       .set_wol        = at803x_set_wol,
-       .get_wol        = at803x_get_wol,
-       .suspend        = at803x_suspend,
-       .resume         = at803x_resume,
-       .features       = PHY_GBIT_FEATURES,
-       .flags          = PHY_HAS_INTERRUPT,
-       .config_aneg    = genphy_config_aneg,
-       .read_status    = genphy_read_status,
-       .driver         = {
+       .phy_id                 = ATH8030_PHY_ID,
+       .name                   = "Atheros 8030 ethernet",
+       .phy_id_mask            = 0xffffffef,
+       .probe                  = at803x_probe,
+       .config_init            = at803x_config_init,
+       .link_change_notify     = at803x_link_change_notify,
+       .set_wol                = at803x_set_wol,
+       .get_wol                = at803x_get_wol,
+       .suspend                = at803x_suspend,
+       .resume                 = at803x_resume,
+       .features               = PHY_GBIT_FEATURES,
+       .flags                  = PHY_HAS_INTERRUPT,
+       .config_aneg            = genphy_config_aneg,
+       .read_status            = genphy_read_status,
+       .driver                 = {
                .owner = THIS_MODULE,
        },
 }, {
        /* ATHEROS 8031 */
-       .phy_id         = 0x004dd074,
-       .name           = "Atheros 8031 ethernet",
-       .phy_id_mask    = 0xffffffef,
-       .config_init    = at803x_config_init,
-       .set_wol        = at803x_set_wol,
-       .get_wol        = at803x_get_wol,
-       .suspend        = at803x_suspend,
-       .resume         = at803x_resume,
-       .features       = PHY_GBIT_FEATURES,
-       .flags          = PHY_HAS_INTERRUPT,
-       .config_aneg    = genphy_config_aneg,
-       .read_status    = genphy_read_status,
-       .ack_interrupt  = &at803x_ack_interrupt,
-       .config_intr    = &at803x_config_intr,
-       .driver         = {
+       .phy_id                 = ATH8031_PHY_ID,
+       .name                   = "Atheros 8031 ethernet",
+       .phy_id_mask            = 0xffffffef,
+       .probe                  = at803x_probe,
+       .config_init            = at803x_config_init,
+       .link_change_notify     = at803x_link_change_notify,
+       .set_wol                = at803x_set_wol,
+       .get_wol                = at803x_get_wol,
+       .suspend                = at803x_suspend,
+       .resume                 = at803x_resume,
+       .features               = PHY_GBIT_FEATURES,
+       .flags                  = PHY_HAS_INTERRUPT,
+       .config_aneg            = genphy_config_aneg,
+       .read_status            = genphy_read_status,
+       .ack_interrupt          = &at803x_ack_interrupt,
+       .config_intr            = &at803x_config_intr,
+       .driver                 = {
                .owner = THIS_MODULE,
        },
 } };
@@ -260,9 +367,9 @@ module_init(atheros_init);
 module_exit(atheros_exit);
 
 static struct mdio_device_id __maybe_unused atheros_tbl[] = {
-       { 0x004dd076, 0xffffffef },
-       { 0x004dd074, 0xffffffef },
-       { 0x004dd072, 0xffffffef },
+       { ATH8030_PHY_ID, 0xffffffef },
+       { ATH8031_PHY_ID, 0xffffffef },
+       { ATH8035_PHY_ID, 0xffffffef },
        { }
 };
 
index 3bc079a..f7c6181 100644 (file)
@@ -720,6 +720,9 @@ void phy_state_machine(struct work_struct *work)
 
        mutex_lock(&phydev->lock);
 
+       if (phydev->drv->link_change_notify)
+               phydev->drv->link_change_notify(phydev);
+
        switch (phydev->state) {
        case PHY_DOWN:
        case PHY_STARTING:
index ad4a94e..8752644 100644 (file)
@@ -83,6 +83,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 #include "slip.h"
 #ifdef CONFIG_INET
 #include <linux/ip.h>
@@ -416,36 +417,46 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
 #endif
 }
 
-/*
- * Called by the driver when there's room for more data.  If we have
- * more packets to send, we send them here.
- */
-static void slip_write_wakeup(struct tty_struct *tty)
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void slip_transmit(struct work_struct *work)
 {
+       struct slip *sl = container_of(work, struct slip, tx_work);
        int actual;
-       struct slip *sl = tty->disc_data;
 
+       spin_lock_bh(&sl->lock);
        /* First make sure we're connected. */
-       if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
+       if (!sl->tty || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) {
+               spin_unlock_bh(&sl->lock);
                return;
+       }
 
-       spin_lock_bh(&sl->lock);
        if (sl->xleft <= 0)  {
                /* Now serial buffer is almost free & we can start
                 * transmission of another packet */
                sl->dev->stats.tx_packets++;
-               clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+               clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
                spin_unlock_bh(&sl->lock);
                sl_unlock(sl);
                return;
        }
 
-       actual = tty->ops->write(tty, sl->xhead, sl->xleft);
+       actual = sl->tty->ops->write(sl->tty, sl->xhead, sl->xleft);
        sl->xleft -= actual;
        sl->xhead += actual;
        spin_unlock_bh(&sl->lock);
 }
 
+/*
+ * Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void slip_write_wakeup(struct tty_struct *tty)
+{
+       struct slip *sl = tty->disc_data;
+
+       schedule_work(&sl->tx_work);
+}
+
 static void sl_tx_timeout(struct net_device *dev)
 {
        struct slip *sl = netdev_priv(dev);
@@ -749,6 +760,7 @@ static struct slip *sl_alloc(dev_t line)
        sl->magic       = SLIP_MAGIC;
        sl->dev         = dev;
        spin_lock_init(&sl->lock);
+       INIT_WORK(&sl->tx_work, slip_transmit);
        sl->mode        = SL_MODE_DEFAULT;
 #ifdef CONFIG_SLIP_SMART
        /* initialize timer_list struct */
@@ -872,8 +884,12 @@ static void slip_close(struct tty_struct *tty)
        if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty)
                return;
 
+       spin_lock_bh(&sl->lock);
        tty->disc_data = NULL;
        sl->tty = NULL;
+       spin_unlock_bh(&sl->lock);
+
+       flush_work(&sl->tx_work);
 
        /* VSV = very important to remove timers */
 #ifdef CONFIG_SLIP_SMART
index 67673cf..cf32aad 100644 (file)
@@ -53,6 +53,7 @@ struct slip {
   struct tty_struct    *tty;           /* ptr to TTY structure         */
   struct net_device    *dev;           /* easy for intr handling       */
   spinlock_t           lock;
+  struct work_struct   tx_work;        /* Flushes transmit buffer      */
 
 #ifdef SL_INCLUDE_CSLIP
   struct slcompress    *slcomp;        /* for header compression       */
index f9822bc..5d95a13 100644 (file)
@@ -84,12 +84,13 @@ static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev,
        ctx = drvstate->ctx;
 
        if (usbnet_dev->status)
-               /* CDC-WMC r1.1 requires wMaxCommand to be "at least 256
-                * decimal (0x100)"
+               /* The wMaxCommand buffer must be big enough to hold
+                * any message from the modem. Experience has shown
+                * that some replies are more than 256 bytes long
                 */
                subdriver = usb_cdc_wdm_register(ctx->control,
                                                 &usbnet_dev->status->desc,
-                                                256, /* wMaxCommand */
+                                                1024, /* wMaxCommand */
                                                 huawei_cdc_ncm_wdm_manage_power);
        if (IS_ERR(subdriver)) {
                ret = PTR_ERR(subdriver);
index 9739434..b76f7dc 100644 (file)
@@ -2589,8 +2589,8 @@ vmxnet3_open(struct net_device *netdev)
        for (i = 0; i < adapter->num_tx_queues; i++)
                spin_lock_init(&adapter->tx_queue[i].tx_lock);
 
-       err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE,
-                                   VMXNET3_DEF_RX_RING_SIZE,
+       err = vmxnet3_create_queues(adapter, adapter->tx_ring_size,
+                                   adapter->rx_ring_size,
                                    VMXNET3_DEF_RX_RING_SIZE);
        if (err)
                goto queue_err;
@@ -2968,6 +2968,9 @@ vmxnet3_probe_device(struct pci_dev *pdev,
        adapter->netdev = netdev;
        adapter->pdev = pdev;
 
+       adapter->tx_ring_size = VMXNET3_DEF_TX_RING_SIZE;
+       adapter->rx_ring_size = VMXNET3_DEF_RX_RING_SIZE;
+
        spin_lock_init(&adapter->cmd_lock);
        adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
                                             sizeof(struct vmxnet3_adapter),
index 40c1c7b..b725fd9 100644 (file)
@@ -449,8 +449,8 @@ vmxnet3_get_ringparam(struct net_device *netdev,
        param->rx_mini_max_pending = 0;
        param->rx_jumbo_max_pending = 0;
 
-       param->rx_pending = adapter->rx_queue[0].rx_ring[0].size;
-       param->tx_pending = adapter->tx_queue[0].tx_ring.size;
+       param->rx_pending = adapter->rx_ring_size;
+       param->tx_pending = adapter->tx_ring_size;
        param->rx_mini_pending = 0;
        param->rx_jumbo_pending = 0;
 }
@@ -529,9 +529,11 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                         * size */
                        netdev_err(netdev, "failed to apply new sizes, "
                                   "try the default ones\n");
+                       new_rx_ring_size = VMXNET3_DEF_RX_RING_SIZE;
+                       new_tx_ring_size = VMXNET3_DEF_TX_RING_SIZE;
                        err = vmxnet3_create_queues(adapter,
-                                                   VMXNET3_DEF_TX_RING_SIZE,
-                                                   VMXNET3_DEF_RX_RING_SIZE,
+                                                   new_tx_ring_size,
+                                                   new_rx_ring_size,
                                                    VMXNET3_DEF_RX_RING_SIZE);
                        if (err) {
                                netdev_err(netdev, "failed to create queues "
@@ -545,6 +547,8 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                        netdev_err(netdev, "failed to re-activate, error %d."
                                   " Closing it\n", err);
        }
+       adapter->tx_ring_size = new_tx_ring_size;
+       adapter->rx_ring_size = new_rx_ring_size;
 
 out:
        clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
index 190569d..29ee77f 100644 (file)
@@ -349,6 +349,11 @@ struct vmxnet3_adapter {
        u32     link_speed; /* in mbps */
 
        u64     tx_timeout_count;
+
+       /* Ring sizes */
+       u32 tx_ring_size;
+       u32 rx_ring_size;
+
        struct work_struct work;
 
        unsigned long  state;    /* VMXNET3_STATE_BIT_xxx */
index e3f67b8..40fd9b7 100644 (file)
@@ -36,7 +36,7 @@ config B43_SSB
 choice
        prompt "Supported bus types"
        depends on B43
-       default B43_BCMA_AND_SSB
+       default B43_BUSES_BCMA_AND_SSB
 
 config B43_BUSES_BCMA_AND_SSB
        bool "BCMA and SSB"
index 32538ac..0d6a0bb 100644 (file)
@@ -5221,6 +5221,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
        /* We don't support 5 GHz on some PHYs yet */
        switch (dev->phy.type) {
        case B43_PHYTYPE_A:
+       case B43_PHYTYPE_G:
        case B43_PHYTYPE_N:
        case B43_PHYTYPE_LP:
        case B43_PHYTYPE_HT:
index 4f38f19..6e6ef3f 100644 (file)
@@ -811,9 +811,13 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
                break;
        case B43_PHYTYPE_G:
                status.band = IEEE80211_BAND_2GHZ;
-               /* chanid is the radio channel cookie value as used
-                * to tune the radio. */
-               status.freq = chanid + 2400;
+               /* Somewhere between 478.104 and 508.1084 firmware for G-PHY
+                * has been modified to be compatible with N-PHY and others.
+                */
+               if (dev->fw.rev >= 508)
+                       status.freq = ieee80211_channel_to_frequency(chanid, status.band);
+               else
+                       status.freq = chanid + 2400;
                break;
        case B43_PHYTYPE_N:
        case B43_PHYTYPE_LP:
index 574d4b5..2cc9b6f 100644 (file)
@@ -50,7 +50,7 @@ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
                return -1;
        }
        mapping.len = size;
-       memcpy(skb->cb, &mapping, sizeof(mapping));
+       mwifiex_store_mapping(skb, &mapping);
        return 0;
 }
 
@@ -60,7 +60,7 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
        struct pcie_service_card *card = adapter->card;
        struct mwifiex_dma_mapping mapping;
 
-       MWIFIEX_SKB_PACB(skb, &mapping);
+       mwifiex_get_mapping(skb, &mapping);
        pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
 }
 
index ddae570..caadb37 100644 (file)
 #ifndef _MWIFIEX_UTIL_H_
 #define _MWIFIEX_UTIL_H_
 
+struct mwifiex_dma_mapping {
+       dma_addr_t addr;
+       size_t len;
+};
+
+struct mwifiex_cb {
+       struct mwifiex_dma_mapping dma_mapping;
+       union {
+               struct mwifiex_rxinfo rx_info;
+               struct mwifiex_txinfo tx_info;
+       };
+};
+
 static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
 {
-       return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t));
+       struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
+
+       BUILD_BUG_ON(sizeof(struct mwifiex_cb) > sizeof(skb->cb));
+       return &cb->rx_info;
 }
 
 static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
 {
-       return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t));
+       struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
+
+       return &cb->tx_info;
 }
 
-struct mwifiex_dma_mapping {
-       dma_addr_t addr;
-       size_t len;
-};
+static inline void mwifiex_store_mapping(struct sk_buff *skb,
+                                        struct mwifiex_dma_mapping *mapping)
+{
+       struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
+
+       memcpy(&cb->dma_mapping, mapping, sizeof(*mapping));
+}
 
-static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb,
-                                       struct mwifiex_dma_mapping *mapping)
+static inline void mwifiex_get_mapping(struct sk_buff *skb,
+                                      struct mwifiex_dma_mapping *mapping)
 {
-       memcpy(mapping, skb->cb, sizeof(*mapping));
+       struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
+
+       memcpy(mapping, &cb->dma_mapping, sizeof(*mapping));
 }
 
 static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
 {
        struct mwifiex_dma_mapping mapping;
 
-       MWIFIEX_SKB_PACB(skb, &mapping);
+       mwifiex_get_mapping(skb, &mapping);
 
        return mapping.addr;
 }
index 2f1cd92..a511ccc 100644 (file)
@@ -1681,8 +1681,13 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Detect if this device has an hardware controlled radio.
         */
-       if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+       if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) {
                __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
+               /*
+                * On this device RFKILL initialized during probe does not work.
+                */
+               __set_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags);
+       }
 
        /*
         * Check if the BBP tuning should be enabled.
index a49c3d7..e11dab2 100644 (file)
@@ -229,6 +229,27 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
 /*
  * Firmware functions
  */
+static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
+{
+       __le32 reg;
+       u32 fw_mode;
+
+       /* cannot use rt2x00usb_register_read here as it uses different
+        * mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
+        * magic value USB_MODE_AUTORUN (0x11) to the device, thus the
+        * returned value would be invalid.
+        */
+       rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
+                                USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN,
+                                &reg, sizeof(reg), REGISTER_TIMEOUT_FIRMWARE);
+       fw_mode = le32_to_cpu(reg);
+
+       if ((fw_mode & 0x00000003) == 2)
+               return 1;
+
+       return 0;
+}
+
 static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
 {
        return FIRMWARE_RT2870;
@@ -257,8 +278,13 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
        /*
         * Write firmware to device.
         */
-       rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
-                                     data + offset, length);
+       if (rt2800usb_autorun_detect(rt2x00dev)) {
+               rt2x00_info(rt2x00dev,
+                           "Firmware loading not required - NIC in AutoRun mode\n");
+       } else {
+               rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+                                             data + offset, length);
+       }
 
        rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
        rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
@@ -735,11 +761,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 /*
  * Device probe functions.
  */
+static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev)
+{
+       if (rt2800usb_autorun_detect(rt2x00dev))
+               return 1;
+       return rt2800_efuse_detect(rt2x00dev);
+}
+
 static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
 
-       if (rt2800_efuse_detect(rt2x00dev))
+       if (rt2800usb_efuse_detect(rt2x00dev))
                retval = rt2800_read_eeprom_efuse(rt2x00dev);
        else
                retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
index 010b765..d13f25c 100644 (file)
@@ -693,6 +693,7 @@ enum rt2x00_capability_flags {
        REQUIRE_SW_SEQNO,
        REQUIRE_HT_TX_DESC,
        REQUIRE_PS_AUTOWAKE,
+       REQUIRE_DELAYED_RFKILL,
 
        /*
         * Capabilities
index 2bde672..4fa43a2 100644 (file)
@@ -1126,9 +1126,10 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
                return;
 
        /*
-        * Unregister extra components.
+        * Stop rfkill polling.
         */
-       rt2x00rfkill_unregister(rt2x00dev);
+       if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+               rt2x00rfkill_unregister(rt2x00dev);
 
        /*
         * Allow the HW to uninitialize.
@@ -1166,6 +1167,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
 
        set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
 
+       /*
+        * Start rfkill polling.
+        */
+       if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+               rt2x00rfkill_register(rt2x00dev);
+
        return 0;
 }
 
@@ -1375,7 +1382,12 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
        rt2x00link_register(rt2x00dev);
        rt2x00leds_register(rt2x00dev);
        rt2x00debug_register(rt2x00dev);
-       rt2x00rfkill_register(rt2x00dev);
+
+       /*
+        * Start rfkill polling.
+        */
+       if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+               rt2x00rfkill_register(rt2x00dev);
 
        return 0;
 
@@ -1390,6 +1402,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 {
        clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 
+       /*
+        * Stop rfkill polling.
+        */
+       if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+               rt2x00rfkill_unregister(rt2x00dev);
+
        /*
         * Disable radio.
         */
index 212ac48..004dff9 100644 (file)
@@ -487,6 +487,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        crypto.cipher = rt2x00crypto_key_to_cipher(key);
        if (crypto.cipher == CIPHER_NONE)
                return -EOPNOTSUPP;
+       if (crypto.cipher == CIPHER_TKIP && rt2x00_is_usb(rt2x00dev))
+               return -EOPNOTSUPP;
 
        crypto.cmd = cmd;
 
index e7bcf62..831b65f 100644 (file)
@@ -93,6 +93,7 @@ enum rt2x00usb_mode_offset {
        USB_MODE_SLEEP = 7,     /* RT73USB */
        USB_MODE_FIRMWARE = 8,  /* RT73USB */
        USB_MODE_WAKEUP = 9,    /* RT73USB */
+       USB_MODE_AUTORUN = 17, /* RT2800USB */
 };
 
 /**
index 4dd7c4a..2532ce8 100644 (file)
@@ -222,6 +222,7 @@ struct xenvif {
 
        /* Queues */
        struct xenvif_queue *queues;
+       unsigned int num_queues; /* active queues, resource allocated */
 
        /* Miscellaneous private stuff. */
        struct net_device *dev;
index 852da34..9e97c7c 100644 (file)
@@ -137,32 +137,11 @@ static void xenvif_wake_queue_callback(unsigned long data)
        }
 }
 
-static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb,
-                              void *accel_priv, select_queue_fallback_t fallback)
-{
-       unsigned int num_queues = dev->real_num_tx_queues;
-       u32 hash;
-       u16 queue_index;
-
-       /* First, check if there is only one queue to optimise the
-        * single-queue or old frontend scenario.
-        */
-       if (num_queues == 1) {
-               queue_index = 0;
-       } else {
-               /* Use skb_get_hash to obtain an L4 hash if available */
-               hash = skb_get_hash(skb);
-               queue_index = hash % num_queues;
-       }
-
-       return queue_index;
-}
-
 static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct xenvif *vif = netdev_priv(dev);
        struct xenvif_queue *queue = NULL;
-       unsigned int num_queues = dev->real_num_tx_queues;
+       unsigned int num_queues = vif->num_queues;
        u16 index;
        int min_slots_needed;
 
@@ -225,7 +204,7 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev)
 {
        struct xenvif *vif = netdev_priv(dev);
        struct xenvif_queue *queue = NULL;
-       unsigned int num_queues = dev->real_num_tx_queues;
+       unsigned int num_queues = vif->num_queues;
        unsigned long rx_bytes = 0;
        unsigned long rx_packets = 0;
        unsigned long tx_bytes = 0;
@@ -256,7 +235,7 @@ out:
 static void xenvif_up(struct xenvif *vif)
 {
        struct xenvif_queue *queue = NULL;
-       unsigned int num_queues = vif->dev->real_num_tx_queues;
+       unsigned int num_queues = vif->num_queues;
        unsigned int queue_index;
 
        for (queue_index = 0; queue_index < num_queues; ++queue_index) {
@@ -272,7 +251,7 @@ static void xenvif_up(struct xenvif *vif)
 static void xenvif_down(struct xenvif *vif)
 {
        struct xenvif_queue *queue = NULL;
-       unsigned int num_queues = vif->dev->real_num_tx_queues;
+       unsigned int num_queues = vif->num_queues;
        unsigned int queue_index;
 
        for (queue_index = 0; queue_index < num_queues; ++queue_index) {
@@ -379,7 +358,7 @@ static void xenvif_get_ethtool_stats(struct net_device *dev,
                                     struct ethtool_stats *stats, u64 * data)
 {
        struct xenvif *vif = netdev_priv(dev);
-       unsigned int num_queues = dev->real_num_tx_queues;
+       unsigned int num_queues = vif->num_queues;
        int i;
        unsigned int queue_index;
        struct xenvif_stats *vif_stats;
@@ -424,7 +403,6 @@ static const struct net_device_ops xenvif_netdev_ops = {
        .ndo_fix_features = xenvif_fix_features,
        .ndo_set_mac_address = eth_mac_addr,
        .ndo_validate_addr   = eth_validate_addr,
-       .ndo_select_queue = xenvif_select_queue,
 };
 
 struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
@@ -438,7 +416,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
        snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
        /* Allocate a netdev with the max. supported number of queues.
         * When the guest selects the desired number, it will be updated
-        * via netif_set_real_num_tx_queues().
+        * via netif_set_real_num_*_queues().
         */
        dev = alloc_netdev_mq(sizeof(struct xenvif), name, ether_setup,
                              xenvif_max_queues);
@@ -458,11 +436,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
        vif->dev = dev;
        vif->disabled = false;
 
-       /* Start out with no queues. The call below does not require
-        * rtnl_lock() as it happens before register_netdev().
-        */
+       /* Start out with no queues. */
        vif->queues = NULL;
-       netif_set_real_num_tx_queues(dev, 0);
+       vif->num_queues = 0;
 
        dev->netdev_ops = &xenvif_netdev_ops;
        dev->hw_features = NETIF_F_SG |
@@ -677,7 +653,7 @@ static void xenvif_wait_unmap_timeout(struct xenvif_queue *queue,
 void xenvif_disconnect(struct xenvif *vif)
 {
        struct xenvif_queue *queue = NULL;
-       unsigned int num_queues = vif->dev->real_num_tx_queues;
+       unsigned int num_queues = vif->num_queues;
        unsigned int queue_index;
 
        if (netif_carrier_ok(vif->dev))
@@ -724,7 +700,7 @@ void xenvif_deinit_queue(struct xenvif_queue *queue)
 void xenvif_free(struct xenvif *vif)
 {
        struct xenvif_queue *queue = NULL;
-       unsigned int num_queues = vif->dev->real_num_tx_queues;
+       unsigned int num_queues = vif->num_queues;
        unsigned int queue_index;
        /* Here we want to avoid timeout messages if an skb can be legitimately
         * stuck somewhere else. Realistically this could be an another vif's
@@ -748,12 +724,9 @@ void xenvif_free(struct xenvif *vif)
                xenvif_deinit_queue(queue);
        }
 
-       /* Free the array of queues. The call below does not require
-        * rtnl_lock() because it happens after unregister_netdev().
-        */
-       netif_set_real_num_tx_queues(vif->dev, 0);
        vfree(vif->queues);
        vif->queues = NULL;
+       vif->num_queues = 0;
 
        free_netdev(vif->dev);
 
index 96c63dc..3d85acd 100644 (file)
@@ -527,9 +527,7 @@ static void connect(struct backend_info *be)
        /* Use the number of queues requested by the frontend */
        be->vif->queues = vzalloc(requested_num_queues *
                                  sizeof(struct xenvif_queue));
-       rtnl_lock();
-       netif_set_real_num_tx_queues(be->vif->dev, requested_num_queues);
-       rtnl_unlock();
+       be->vif->num_queues = requested_num_queues;
 
        for (queue_index = 0; queue_index < requested_num_queues; ++queue_index) {
                queue = &be->vif->queues[queue_index];
@@ -546,9 +544,7 @@ static void connect(struct backend_info *be)
                         * earlier queues can be destroyed using the regular
                         * disconnect logic.
                         */
-                       rtnl_lock();
-                       netif_set_real_num_tx_queues(be->vif->dev, queue_index);
-                       rtnl_unlock();
+                       be->vif->num_queues = queue_index;
                        goto err;
                }
 
@@ -561,13 +557,19 @@ static void connect(struct backend_info *be)
                         * and also clean up any previously initialised queues.
                         */
                        xenvif_deinit_queue(queue);
-                       rtnl_lock();
-                       netif_set_real_num_tx_queues(be->vif->dev, queue_index);
-                       rtnl_unlock();
+                       be->vif->num_queues = queue_index;
                        goto err;
                }
        }
 
+       /* Initialisation completed, tell core driver the number of
+        * active queues.
+        */
+       rtnl_lock();
+       netif_set_real_num_tx_queues(be->vif->dev, requested_num_queues);
+       netif_set_real_num_rx_queues(be->vif->dev, requested_num_queues);
+       rtnl_unlock();
+
        xenvif_carrier_on(be->vif);
 
        unregister_hotplug_status_watch(be);
@@ -582,13 +584,11 @@ static void connect(struct backend_info *be)
        return;
 
 err:
-       if (be->vif->dev->real_num_tx_queues > 0)
+       if (be->vif->num_queues > 0)
                xenvif_disconnect(be->vif); /* Clean up existing queues */
        vfree(be->vif->queues);
        be->vif->queues = NULL;
-       rtnl_lock();
-       netif_set_real_num_tx_queues(be->vif->dev, 0);
-       rtnl_unlock();
+       be->vif->num_queues = 0;
        return;
 }
 
@@ -596,7 +596,7 @@ err:
 static int connect_rings(struct backend_info *be, struct xenvif_queue *queue)
 {
        struct xenbus_device *dev = be->dev;
-       unsigned int num_queues = queue->vif->dev->real_num_tx_queues;
+       unsigned int num_queues = queue->vif->num_queues;
        unsigned long tx_ring_ref, rx_ring_ref;
        unsigned int tx_evtchn, rx_evtchn;
        int err;
index 5a7872a..2ccb4a0 100644 (file)
@@ -1287,7 +1287,7 @@ static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id)
 
        if (likely(netif_carrier_ok(dev) &&
                   RING_HAS_UNCONSUMED_RESPONSES(&queue->rx)))
-                       napi_schedule(&queue->napi);
+               napi_schedule(&queue->napi);
 
        return IRQ_HANDLED;
 }
@@ -1437,10 +1437,11 @@ static void xennet_end_access(int ref, void *page)
 static void xennet_disconnect_backend(struct netfront_info *info)
 {
        unsigned int i = 0;
-       struct netfront_queue *queue = NULL;
        unsigned int num_queues = info->netdev->real_num_tx_queues;
 
        for (i = 0; i < num_queues; ++i) {
+               struct netfront_queue *queue = &info->queues[i];
+
                /* Stop old i/f to prevent errors whilst we rebuild the state. */
                spin_lock_bh(&queue->rx_lock);
                spin_lock_irq(&queue->tx_lock);
@@ -1698,8 +1699,6 @@ static int xennet_init_queue(struct netfront_queue *queue)
                goto exit_free_tx;
        }
 
-       netif_napi_add(queue->info->netdev, &queue->napi, xennet_poll, 64);
-
        return 0;
 
  exit_free_tx:
@@ -1790,6 +1789,70 @@ error:
        return err;
 }
 
+static void xennet_destroy_queues(struct netfront_info *info)
+{
+       unsigned int i;
+
+       rtnl_lock();
+
+       for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
+               struct netfront_queue *queue = &info->queues[i];
+
+               if (netif_running(info->netdev))
+                       napi_disable(&queue->napi);
+               netif_napi_del(&queue->napi);
+       }
+
+       rtnl_unlock();
+
+       kfree(info->queues);
+       info->queues = NULL;
+}
+
+static int xennet_create_queues(struct netfront_info *info,
+                               unsigned int num_queues)
+{
+       unsigned int i;
+       int ret;
+
+       info->queues = kcalloc(num_queues, sizeof(struct netfront_queue),
+                              GFP_KERNEL);
+       if (!info->queues)
+               return -ENOMEM;
+
+       rtnl_lock();
+
+       for (i = 0; i < num_queues; i++) {
+               struct netfront_queue *queue = &info->queues[i];
+
+               queue->id = i;
+               queue->info = info;
+
+               ret = xennet_init_queue(queue);
+               if (ret < 0) {
+                       dev_warn(&info->netdev->dev, "only created %d queues\n",
+                                num_queues);
+                       num_queues = i;
+                       break;
+               }
+
+               netif_napi_add(queue->info->netdev, &queue->napi,
+                              xennet_poll, 64);
+               if (netif_running(info->netdev))
+                       napi_enable(&queue->napi);
+       }
+
+       netif_set_real_num_tx_queues(info->netdev, num_queues);
+
+       rtnl_unlock();
+
+       if (num_queues == 0) {
+               dev_err(&info->netdev->dev, "no queues\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
 /* Common code used when first setting up, and when resuming. */
 static int talk_to_netback(struct xenbus_device *dev,
                           struct netfront_info *info)
@@ -1826,42 +1889,20 @@ static int talk_to_netback(struct xenbus_device *dev,
                goto out;
        }
 
-       /* Allocate array of queues */
-       info->queues = kcalloc(num_queues, sizeof(struct netfront_queue), GFP_KERNEL);
-       if (!info->queues) {
-               err = -ENOMEM;
-               goto out;
-       }
-       rtnl_lock();
-       netif_set_real_num_tx_queues(info->netdev, num_queues);
-       rtnl_unlock();
+       if (info->queues)
+               xennet_destroy_queues(info);
+
+       err = xennet_create_queues(info, num_queues);
+       if (err < 0)
+               goto destroy_ring;
 
        /* Create shared ring, alloc event channel -- for each queue */
        for (i = 0; i < num_queues; ++i) {
                queue = &info->queues[i];
-               queue->id = i;
-               queue->info = info;
-               err = xennet_init_queue(queue);
-               if (err) {
-                       /* xennet_init_queue() cleans up after itself on failure,
-                        * but we still have to clean up any previously initialised
-                        * queues. If i > 0, set num_queues to i, then goto
-                        * destroy_ring, which calls xennet_disconnect_backend()
-                        * to tidy up.
-                        */
-                       if (i > 0) {
-                               rtnl_lock();
-                               netif_set_real_num_tx_queues(info->netdev, i);
-                               rtnl_unlock();
-                               goto destroy_ring;
-                       } else {
-                               goto out;
-                       }
-               }
                err = setup_netfront(dev, queue, feature_split_evtchn);
                if (err) {
-                       /* As for xennet_init_queue(), setup_netfront() will tidy
-                        * up the current queue on error, but we need to clean up
+                       /* setup_netfront() will tidy up the current
+                        * queue on error, but we need to clean up
                         * those already allocated.
                         */
                        if (i > 0) {
index 8368d96..b986480 100644 (file)
@@ -227,7 +227,8 @@ static int __of_node_add(struct device_node *np)
        np->kobj.kset = of_kset;
        if (!np->parent) {
                /* Nodes without parents are new top level trees */
-               rc = kobject_add(&np->kobj, NULL, safe_name(&of_kset->kobj, "base"));
+               rc = kobject_add(&np->kobj, NULL, "%s",
+                                safe_name(&of_kset->kobj, "base"));
        } else {
                name = safe_name(&np->parent->kobj, kbasename(np->full_name));
                if (!name || !name[0])
@@ -1960,9 +1961,9 @@ int of_attach_node(struct device_node *np)
 
        raw_spin_lock_irqsave(&devtree_lock, flags);
        np->sibling = np->parent->child;
-       np->allnext = of_allnodes;
+       np->allnext = np->parent->allnext;
+       np->parent->allnext = np;
        np->parent->child = np;
-       of_allnodes = np;
        of_node_clear_flag(np, OF_DETACHED);
        raw_spin_unlock_irqrestore(&devtree_lock, flags);
 
index fb4a598..a3bf212 100644 (file)
@@ -323,11 +323,13 @@ int of_phy_register_fixed_link(struct device_node *np)
        fixed_link_node = of_get_child_by_name(np, "fixed-link");
        if (fixed_link_node) {
                status.link = 1;
-               status.duplex = of_property_read_bool(np, "full-duplex");
+               status.duplex = of_property_read_bool(fixed_link_node,
+                                                     "full-duplex");
                if (of_property_read_u32(fixed_link_node, "speed", &status.speed))
                        return -EINVAL;
-               status.pause = of_property_read_bool(np, "pause");
-               status.asym_pause = of_property_read_bool(np, "asym-pause");
+               status.pause = of_property_read_bool(fixed_link_node, "pause");
+               status.asym_pause = of_property_read_bool(fixed_link_node,
+                                                         "asym-pause");
                of_node_put(fixed_link_node);
                return fixed_phy_register(PHY_POLL, &status, np);
        }
index 6c48d73..500436f 100644 (file)
@@ -166,10 +166,6 @@ static void of_dma_configure(struct platform_device *pdev)
        int ret;
        struct device *dev = &pdev->dev;
 
-#if defined(CONFIG_MICROBLAZE)
-       pdev->archdata.dma_mask = 0xffffffffUL;
-#endif
-
        /*
         * Set default dma-mask to 32 bit. Drivers are expected to setup
         * the correct supported dma_mask.
index 21df477..2d8a4d0 100644 (file)
@@ -46,4 +46,12 @@ config PCI_HOST_GENERIC
          Say Y here if you want to support a simple generic PCI host
          controller, such as the one emulated by kvmtool.
 
+config PCIE_SPEAR13XX
+       tristate "STMicroelectronics SPEAr PCIe controller"
+       depends on ARCH_SPEAR13XX
+       select PCIEPORTBUS
+       select PCIE_DW
+       help
+         Say Y here if you want PCIe support on SPEAr13XX SoCs.
+
 endmenu
index 611ba4b..0daec79 100644 (file)
@@ -6,3 +6,4 @@ obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
 obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o
 obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
+obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
new file mode 100644 (file)
index 0000000..99738e4
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * PCIe host controller driver for ST Microelectronics SPEAr13xx SoCs
+ *
+ * SPEAr13xx PCIe Glue Layer Source Code
+ *
+ * Copyright (C) 2010-2014 ST Microelectronics
+ * Pratyush Anand <pratyush.anand@st.com>
+ * Mohit Kumar <mohit.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+
+#include "pcie-designware.h"
+
+struct spear13xx_pcie {
+       void __iomem            *app_base;
+       struct phy              *phy;
+       struct clk              *clk;
+       struct pcie_port        pp;
+       bool                    is_gen1;
+};
+
+struct pcie_app_reg {
+       u32     app_ctrl_0;             /* cr0 */
+       u32     app_ctrl_1;             /* cr1 */
+       u32     app_status_0;           /* cr2 */
+       u32     app_status_1;           /* cr3 */
+       u32     msg_status;             /* cr4 */
+       u32     msg_payload;            /* cr5 */
+       u32     int_sts;                /* cr6 */
+       u32     int_clr;                /* cr7 */
+       u32     int_mask;               /* cr8 */
+       u32     mst_bmisc;              /* cr9 */
+       u32     phy_ctrl;               /* cr10 */
+       u32     phy_status;             /* cr11 */
+       u32     cxpl_debug_info_0;      /* cr12 */
+       u32     cxpl_debug_info_1;      /* cr13 */
+       u32     ven_msg_ctrl_0;         /* cr14 */
+       u32     ven_msg_ctrl_1;         /* cr15 */
+       u32     ven_msg_data_0;         /* cr16 */
+       u32     ven_msg_data_1;         /* cr17 */
+       u32     ven_msi_0;              /* cr18 */
+       u32     ven_msi_1;              /* cr19 */
+       u32     mst_rmisc;              /* cr20 */
+};
+
+/* CR0 ID */
+#define RX_LANE_FLIP_EN_ID                     0
+#define TX_LANE_FLIP_EN_ID                     1
+#define SYS_AUX_PWR_DET_ID                     2
+#define APP_LTSSM_ENABLE_ID                    3
+#define SYS_ATTEN_BUTTON_PRESSED_ID            4
+#define SYS_MRL_SENSOR_STATE_ID                        5
+#define SYS_PWR_FAULT_DET_ID                   6
+#define SYS_MRL_SENSOR_CHGED_ID                        7
+#define SYS_PRE_DET_CHGED_ID                   8
+#define SYS_CMD_CPLED_INT_ID                   9
+#define APP_INIT_RST_0_ID                      11
+#define APP_REQ_ENTR_L1_ID                     12
+#define APP_READY_ENTR_L23_ID                  13
+#define APP_REQ_EXIT_L1_ID                     14
+#define DEVICE_TYPE_EP                         (0 << 25)
+#define DEVICE_TYPE_LEP                                (1 << 25)
+#define DEVICE_TYPE_RC                         (4 << 25)
+#define SYS_INT_ID                             29
+#define MISCTRL_EN_ID                          30
+#define REG_TRANSLATION_ENABLE                 31
+
+/* CR1 ID */
+#define APPS_PM_XMT_TURNOFF_ID                 2
+#define APPS_PM_XMT_PME_ID                     5
+
+/* CR3 ID */
+#define XMLH_LTSSM_STATE_DETECT_QUIET          0x00
+#define XMLH_LTSSM_STATE_DETECT_ACT            0x01
+#define XMLH_LTSSM_STATE_POLL_ACTIVE           0x02
+#define XMLH_LTSSM_STATE_POLL_COMPLIANCE       0x03
+#define XMLH_LTSSM_STATE_POLL_CONFIG           0x04
+#define XMLH_LTSSM_STATE_PRE_DETECT_QUIET      0x05
+#define XMLH_LTSSM_STATE_DETECT_WAIT           0x06
+#define XMLH_LTSSM_STATE_CFG_LINKWD_START      0x07
+#define XMLH_LTSSM_STATE_CFG_LINKWD_ACEPT      0x08
+#define XMLH_LTSSM_STATE_CFG_LANENUM_WAIT      0x09
+#define XMLH_LTSSM_STATE_CFG_LANENUM_ACEPT     0x0A
+#define XMLH_LTSSM_STATE_CFG_COMPLETE          0x0B
+#define XMLH_LTSSM_STATE_CFG_IDLE              0x0C
+#define XMLH_LTSSM_STATE_RCVRY_LOCK            0x0D
+#define XMLH_LTSSM_STATE_RCVRY_SPEED           0x0E
+#define XMLH_LTSSM_STATE_RCVRY_RCVRCFG         0x0F
+#define XMLH_LTSSM_STATE_RCVRY_IDLE            0x10
+#define XMLH_LTSSM_STATE_L0                    0x11
+#define XMLH_LTSSM_STATE_L0S                   0x12
+#define XMLH_LTSSM_STATE_L123_SEND_EIDLE       0x13
+#define XMLH_LTSSM_STATE_L1_IDLE               0x14
+#define XMLH_LTSSM_STATE_L2_IDLE               0x15
+#define XMLH_LTSSM_STATE_L2_WAKE               0x16
+#define XMLH_LTSSM_STATE_DISABLED_ENTRY                0x17
+#define XMLH_LTSSM_STATE_DISABLED_IDLE         0x18
+#define XMLH_LTSSM_STATE_DISABLED              0x19
+#define XMLH_LTSSM_STATE_LPBK_ENTRY            0x1A
+#define XMLH_LTSSM_STATE_LPBK_ACTIVE           0x1B
+#define XMLH_LTSSM_STATE_LPBK_EXIT             0x1C
+#define XMLH_LTSSM_STATE_LPBK_EXIT_TIMEOUT     0x1D
+#define XMLH_LTSSM_STATE_HOT_RESET_ENTRY       0x1E
+#define XMLH_LTSSM_STATE_HOT_RESET             0x1F
+#define XMLH_LTSSM_STATE_MASK                  0x3F
+#define XMLH_LINK_UP                           (1 << 6)
+
+/* CR4 ID */
+#define CFG_MSI_EN_ID                          18
+
+/* CR6 */
+#define INTA_CTRL_INT                          (1 << 7)
+#define INTB_CTRL_INT                          (1 << 8)
+#define INTC_CTRL_INT                          (1 << 9)
+#define INTD_CTRL_INT                          (1 << 10)
+#define MSI_CTRL_INT                           (1 << 26)
+
+/* CR19 ID */
+#define VEN_MSI_REQ_ID                         11
+#define VEN_MSI_FUN_NUM_ID                     8
+#define VEN_MSI_TC_ID                          5
+#define VEN_MSI_VECTOR_ID                      0
+#define VEN_MSI_REQ_EN         ((u32)0x1 << VEN_MSI_REQ_ID)
+#define VEN_MSI_FUN_NUM_MASK   ((u32)0x7 << VEN_MSI_FUN_NUM_ID)
+#define VEN_MSI_TC_MASK                ((u32)0x7 << VEN_MSI_TC_ID)
+#define VEN_MSI_VECTOR_MASK    ((u32)0x1F << VEN_MSI_VECTOR_ID)
+
+#define EXP_CAP_ID_OFFSET                      0x70
+
+#define to_spear13xx_pcie(x)   container_of(x, struct spear13xx_pcie, pp)
+
+static int spear13xx_pcie_establish_link(struct pcie_port *pp)
+{
+       u32 val;
+       int count = 0;
+       struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
+       struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
+       u32 exp_cap_off = EXP_CAP_ID_OFFSET;
+
+       if (dw_pcie_link_up(pp)) {
+               dev_err(pp->dev, "link already up\n");
+               return 0;
+       }
+
+       dw_pcie_setup_rc(pp);
+
+       /*
+        * this controller support only 128 bytes read size, however its
+        * default value in capability register is 512 bytes. So force
+        * it to 128 here.
+        */
+       dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, &val);
+       val &= ~PCI_EXP_DEVCTL_READRQ;
+       dw_pcie_cfg_write(pp->dbi_base, exp_cap_off + PCI_EXP_DEVCTL, 4, val);
+
+       dw_pcie_cfg_write(pp->dbi_base, PCI_VENDOR_ID, 2, 0x104A);
+       dw_pcie_cfg_write(pp->dbi_base, PCI_DEVICE_ID, 2, 0xCD80);
+
+       /*
+        * if is_gen1 is set then handle it, so that some buggy card
+        * also works
+        */
+       if (spear13xx_pcie->is_gen1) {
+               dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCAP, 4,
+                                &val);
+               if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
+                       val &= ~((u32)PCI_EXP_LNKCAP_SLS);
+                       val |= PCI_EXP_LNKCAP_SLS_2_5GB;
+                       dw_pcie_cfg_write(pp->dbi_base, exp_cap_off +
+                                         PCI_EXP_LNKCAP, 4, val);
+               }
+
+               dw_pcie_cfg_read(pp->dbi_base, exp_cap_off + PCI_EXP_LNKCTL2, 4,
+                                &val);
+               if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
+                       val &= ~((u32)PCI_EXP_LNKCAP_SLS);
+                       val |= PCI_EXP_LNKCAP_SLS_2_5GB;
+                       dw_pcie_cfg_write(pp->dbi_base, exp_cap_off +
+                                         PCI_EXP_LNKCTL2, 4, val);
+               }
+       }
+
+       /* enable ltssm */
+       writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID)
+                       | (1 << APP_LTSSM_ENABLE_ID)
+                       | ((u32)1 << REG_TRANSLATION_ENABLE),
+                       &app_reg->app_ctrl_0);
+
+       /* check if the link is up or not */
+       while (!dw_pcie_link_up(pp)) {
+               mdelay(100);
+               count++;
+               if (count == 10) {
+                       dev_err(pp->dev, "link Fail\n");
+                       return -EINVAL;
+               }
+       }
+       dev_info(pp->dev, "link up\n");
+
+       return 0;
+}
+
+static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)
+{
+       struct pcie_port *pp = arg;
+       struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
+       struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
+       unsigned int status;
+
+       status = readl(&app_reg->int_sts);
+
+       if (status & MSI_CTRL_INT) {
+               if (!IS_ENABLED(CONFIG_PCI_MSI))
+                       BUG();
+               dw_handle_msi_irq(pp);
+       }
+
+       writel(status, &app_reg->int_clr);
+
+       return IRQ_HANDLED;
+}
+
+static void spear13xx_pcie_enable_interrupts(struct pcie_port *pp)
+{
+       struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
+       struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
+
+       /* Enable MSI interrupt */
+       if (IS_ENABLED(CONFIG_PCI_MSI)) {
+               dw_pcie_msi_init(pp);
+               writel(readl(&app_reg->int_mask) |
+                               MSI_CTRL_INT, &app_reg->int_mask);
+       }
+}
+
+static int spear13xx_pcie_link_up(struct pcie_port *pp)
+{
+       struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
+       struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
+
+       if (readl(&app_reg->app_status_1) & XMLH_LINK_UP)
+               return 1;
+
+       return 0;
+}
+
+static void spear13xx_pcie_host_init(struct pcie_port *pp)
+{
+       spear13xx_pcie_establish_link(pp);
+       spear13xx_pcie_enable_interrupts(pp);
+}
+
+static struct pcie_host_ops spear13xx_pcie_host_ops = {
+       .link_up = spear13xx_pcie_link_up,
+       .host_init = spear13xx_pcie_host_init,
+};
+
+static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       int ret;
+
+       pp->irq = platform_get_irq(pdev, 0);
+       if (!pp->irq) {
+               dev_err(dev, "failed to get irq\n");
+               return -ENODEV;
+       }
+       ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler,
+                              IRQF_SHARED, "spear1340-pcie", pp);
+       if (ret) {
+               dev_err(dev, "failed to request irq %d\n", pp->irq);
+               return ret;
+       }
+
+       pp->root_bus_nr = -1;
+       pp->ops = &spear13xx_pcie_host_ops;
+
+       ret = dw_pcie_host_init(pp);
+       if (ret) {
+               dev_err(dev, "failed to initialize host\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int __init spear13xx_pcie_probe(struct platform_device *pdev)
+{
+       struct spear13xx_pcie *spear13xx_pcie;
+       struct pcie_port *pp;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = pdev->dev.of_node;
+       struct resource *dbi_base;
+       int ret;
+
+       spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL);
+       if (!spear13xx_pcie) {
+               dev_err(dev, "no memory for SPEAr13xx pcie\n");
+               return -ENOMEM;
+       }
+
+       spear13xx_pcie->phy = devm_phy_get(dev, "pcie-phy");
+       if (IS_ERR(spear13xx_pcie->phy)) {
+               ret = PTR_ERR(spear13xx_pcie->phy);
+               if (ret == -EPROBE_DEFER)
+                       dev_info(dev, "probe deferred\n");
+               else
+                       dev_err(dev, "couldn't get pcie-phy\n");
+               return ret;
+       }
+
+       phy_init(spear13xx_pcie->phy);
+
+       spear13xx_pcie->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(spear13xx_pcie->clk)) {
+               dev_err(dev, "couldn't get clk for pcie\n");
+               return PTR_ERR(spear13xx_pcie->clk);
+       }
+       ret = clk_prepare_enable(spear13xx_pcie->clk);
+       if (ret) {
+               dev_err(dev, "couldn't enable clk for pcie\n");
+               return ret;
+       }
+
+       pp = &spear13xx_pcie->pp;
+
+       pp->dev = dev;
+
+       dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       pp->dbi_base = devm_ioremap_resource(dev, dbi_base);
+       if (IS_ERR(pp->dbi_base)) {
+               dev_err(dev, "couldn't remap dbi base %p\n", dbi_base);
+               ret = PTR_ERR(pp->dbi_base);
+               goto fail_clk;
+       }
+       spear13xx_pcie->app_base = pp->dbi_base + 0x2000;
+
+       if (of_property_read_bool(np, "st,pcie-is-gen1"))
+               spear13xx_pcie->is_gen1 = true;
+
+       ret = add_pcie_port(pp, pdev);
+       if (ret < 0)
+               goto fail_clk;
+
+       platform_set_drvdata(pdev, spear13xx_pcie);
+       return 0;
+
+fail_clk:
+       clk_disable_unprepare(spear13xx_pcie->clk);
+
+       return ret;
+}
+
+static int __exit spear13xx_pcie_remove(struct platform_device *pdev)
+{
+       struct spear13xx_pcie *spear13xx_pcie = platform_get_drvdata(pdev);
+
+       clk_disable_unprepare(spear13xx_pcie->clk);
+
+       phy_exit(spear13xx_pcie->phy);
+
+       return 0;
+}
+
+static const struct of_device_id spear13xx_pcie_of_match[] = {
+       { .compatible = "st,spear1340-pcie", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, spear13xx_pcie_of_match);
+
+static struct platform_driver spear13xx_pcie_driver = {
+       .probe          = spear13xx_pcie_probe,
+       .remove         = spear13xx_pcie_remove,
+       .driver = {
+               .name   = "spear-pcie",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(spear13xx_pcie_of_match),
+       },
+};
+
+/* SPEAr13xx PCIe driver does not allow module unload */
+
+static int __init pcie_init(void)
+{
+       return platform_driver_register(&spear13xx_pcie_driver);
+}
+module_init(pcie_init);
+
+MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver");
+MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
+MODULE_LICENSE("GPL v2");
index 16a2f06..e8f8a2d 100644 (file)
@@ -178,4 +178,16 @@ config PHY_XGENE
        help
          This option enables support for APM X-Gene SoC multi-purpose PHY.
 
+config PHY_ST_SPEAR1310_MIPHY
+       tristate "ST SPEAR1310-MIPHY driver"
+       select GENERIC_PHY
+       help
+         Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA.
+
+config PHY_ST_SPEAR1340_MIPHY
+       tristate "ST SPEAR1340-MIPHY driver"
+       select GENERIC_PHY
+       help
+         Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA.
+
 endmenu
index b4f1d57..d39609b 100644 (file)
@@ -20,3 +20,5 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
 phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2)  += phy-exynos5250-usb2.o
 obj-$(CONFIG_PHY_EXYNOS5_USBDRD)       += phy-exynos5-usbdrd.o
 obj-$(CONFIG_PHY_XGENE)                        += phy-xgene.o
+obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)   += phy-spear1310-miphy.o
+obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)   += phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c
new file mode 100644 (file)
index 0000000..c58c869
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * ST SPEAr1310-miphy driver
+ *
+ * Copyright (C) 2014 ST Microelectronics
+ * Pratyush Anand <pratyush.anand@st.com>
+ * Mohit Kumar <mohit.kumar@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+
+/* SPEAr1310 Registers */
+#define SPEAR1310_PCIE_SATA_CFG                        0x3A4
+       #define SPEAR1310_PCIE_SATA2_SEL_PCIE           (0 << 31)
+       #define SPEAR1310_PCIE_SATA1_SEL_PCIE           (0 << 30)
+       #define SPEAR1310_PCIE_SATA0_SEL_PCIE           (0 << 29)
+       #define SPEAR1310_PCIE_SATA2_SEL_SATA           BIT(31)
+       #define SPEAR1310_PCIE_SATA1_SEL_SATA           BIT(30)
+       #define SPEAR1310_PCIE_SATA0_SEL_SATA           BIT(29)
+       #define SPEAR1310_SATA2_CFG_TX_CLK_EN           BIT(27)
+       #define SPEAR1310_SATA2_CFG_RX_CLK_EN           BIT(26)
+       #define SPEAR1310_SATA2_CFG_POWERUP_RESET       BIT(25)
+       #define SPEAR1310_SATA2_CFG_PM_CLK_EN           BIT(24)
+       #define SPEAR1310_SATA1_CFG_TX_CLK_EN           BIT(23)
+       #define SPEAR1310_SATA1_CFG_RX_CLK_EN           BIT(22)
+       #define SPEAR1310_SATA1_CFG_POWERUP_RESET       BIT(21)
+       #define SPEAR1310_SATA1_CFG_PM_CLK_EN           BIT(20)
+       #define SPEAR1310_SATA0_CFG_TX_CLK_EN           BIT(19)
+       #define SPEAR1310_SATA0_CFG_RX_CLK_EN           BIT(18)
+       #define SPEAR1310_SATA0_CFG_POWERUP_RESET       BIT(17)
+       #define SPEAR1310_SATA0_CFG_PM_CLK_EN           BIT(16)
+       #define SPEAR1310_PCIE2_CFG_DEVICE_PRESENT      BIT(11)
+       #define SPEAR1310_PCIE2_CFG_POWERUP_RESET       BIT(10)
+       #define SPEAR1310_PCIE2_CFG_CORE_CLK_EN         BIT(9)
+       #define SPEAR1310_PCIE2_CFG_AUX_CLK_EN          BIT(8)
+       #define SPEAR1310_PCIE1_CFG_DEVICE_PRESENT      BIT(7)
+       #define SPEAR1310_PCIE1_CFG_POWERUP_RESET       BIT(6)
+       #define SPEAR1310_PCIE1_CFG_CORE_CLK_EN         BIT(5)
+       #define SPEAR1310_PCIE1_CFG_AUX_CLK_EN          BIT(4)
+       #define SPEAR1310_PCIE0_CFG_DEVICE_PRESENT      BIT(3)
+       #define SPEAR1310_PCIE0_CFG_POWERUP_RESET       BIT(2)
+       #define SPEAR1310_PCIE0_CFG_CORE_CLK_EN         BIT(1)
+       #define SPEAR1310_PCIE0_CFG_AUX_CLK_EN          BIT(0)
+
+       #define SPEAR1310_PCIE_CFG_MASK(x) ((0xF << (x * 4)) | BIT((x + 29)))
+       #define SPEAR1310_SATA_CFG_MASK(x) ((0xF << (x * 4 + 16)) | \
+                       BIT((x + 29)))
+       #define SPEAR1310_PCIE_CFG_VAL(x) \
+                       (SPEAR1310_PCIE_SATA##x##_SEL_PCIE | \
+                       SPEAR1310_PCIE##x##_CFG_AUX_CLK_EN | \
+                       SPEAR1310_PCIE##x##_CFG_CORE_CLK_EN | \
+                       SPEAR1310_PCIE##x##_CFG_POWERUP_RESET | \
+                       SPEAR1310_PCIE##x##_CFG_DEVICE_PRESENT)
+       #define SPEAR1310_SATA_CFG_VAL(x) \
+                       (SPEAR1310_PCIE_SATA##x##_SEL_SATA | \
+                       SPEAR1310_SATA##x##_CFG_PM_CLK_EN | \
+                       SPEAR1310_SATA##x##_CFG_POWERUP_RESET | \
+                       SPEAR1310_SATA##x##_CFG_RX_CLK_EN | \
+                       SPEAR1310_SATA##x##_CFG_TX_CLK_EN)
+
+#define SPEAR1310_PCIE_MIPHY_CFG_1             0x3A8
+       #define SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT     BIT(31)
+       #define SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2       BIT(28)
+       #define SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(x)   (x << 16)
+       #define SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT   BIT(15)
+       #define SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2     BIT(12)
+       #define SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(x) (x << 0)
+       #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_MASK (0xFFFF)
+       #define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK (0xFFFF << 16)
+       #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA \
+                       (SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
+                       SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 | \
+                       SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(60) | \
+                       SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
+                       SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 | \
+                       SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(60))
+       #define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+                       (SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(120))
+       #define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE \
+                       (SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
+                       SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(25) | \
+                       SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
+                       SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(25))
+
+#define SPEAR1310_PCIE_MIPHY_CFG_2             0x3AC
+
+enum spear1310_miphy_mode {
+       SATA,
+       PCIE,
+};
+
+struct spear1310_miphy_priv {
+       /* instance id of this phy */
+       u32                             id;
+       /* phy mode: 0 for SATA 1 for PCIe */
+       enum spear1310_miphy_mode       mode;
+       /* regmap for any soc specific misc registers */
+       struct regmap                   *misc;
+       /* phy struct pointer */
+       struct phy                      *phy;
+};
+
+static int spear1310_miphy_pcie_init(struct spear1310_miphy_priv *priv)
+{
+       u32 val;
+
+       regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
+                          SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK,
+                          SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE);
+
+       switch (priv->id) {
+       case 0:
+               val = SPEAR1310_PCIE_CFG_VAL(0);
+               break;
+       case 1:
+               val = SPEAR1310_PCIE_CFG_VAL(1);
+               break;
+       case 2:
+               val = SPEAR1310_PCIE_CFG_VAL(2);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
+                          SPEAR1310_PCIE_CFG_MASK(priv->id), val);
+
+       return 0;
+}
+
+static int spear1310_miphy_pcie_exit(struct spear1310_miphy_priv *priv)
+{
+       regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
+                          SPEAR1310_PCIE_CFG_MASK(priv->id), 0);
+
+       regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
+                          SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK, 0);
+
+       return 0;
+}
+
+static int spear1310_miphy_init(struct phy *phy)
+{
+       struct spear1310_miphy_priv *priv = phy_get_drvdata(phy);
+       int ret = 0;
+
+       if (priv->mode == PCIE)
+               ret = spear1310_miphy_pcie_init(priv);
+
+       return ret;
+}
+
+static int spear1310_miphy_exit(struct phy *phy)
+{
+       struct spear1310_miphy_priv *priv = phy_get_drvdata(phy);
+       int ret = 0;
+
+       if (priv->mode == PCIE)
+               ret = spear1310_miphy_pcie_exit(priv);
+
+       return ret;
+}
+
+static const struct of_device_id spear1310_miphy_of_match[] = {
+       { .compatible = "st,spear1310-miphy" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, spear1310_miphy_of_match);
+
+static struct phy_ops spear1310_miphy_ops = {
+       .init = spear1310_miphy_init,
+       .exit = spear1310_miphy_exit,
+       .owner = THIS_MODULE,
+};
+
+static struct phy *spear1310_miphy_xlate(struct device *dev,
+                                        struct of_phandle_args *args)
+{
+       struct spear1310_miphy_priv *priv = dev_get_drvdata(dev);
+
+       if (args->args_count < 1) {
+               dev_err(dev, "DT did not pass correct no of args\n");
+               return NULL;
+       }
+
+       priv->mode = args->args[0];
+
+       if (priv->mode != SATA && priv->mode != PCIE) {
+               dev_err(dev, "DT did not pass correct phy mode\n");
+               return NULL;
+       }
+
+       return priv->phy;
+}
+
+static int spear1310_miphy_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct spear1310_miphy_priv *priv;
+       struct phy_provider *phy_provider;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(dev, "can't alloc spear1310_miphy private date memory\n");
+               return -ENOMEM;
+       }
+
+       priv->misc =
+               syscon_regmap_lookup_by_phandle(dev->of_node, "misc");
+       if (IS_ERR(priv->misc)) {
+               dev_err(dev, "failed to find misc regmap\n");
+               return PTR_ERR(priv->misc);
+       }
+
+       if (of_property_read_u32(dev->of_node, "phy-id", &priv->id)) {
+               dev_err(dev, "failed to find phy id\n");
+               return -EINVAL;
+       }
+
+       priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL);
+       if (IS_ERR(priv->phy)) {
+               dev_err(dev, "failed to create SATA PCIe PHY\n");
+               return PTR_ERR(priv->phy);
+       }
+
+       dev_set_drvdata(dev, priv);
+       phy_set_drvdata(priv->phy, priv);
+
+       phy_provider =
+               devm_of_phy_provider_register(dev, spear1310_miphy_xlate);
+       if (IS_ERR(phy_provider)) {
+               dev_err(dev, "failed to register phy provider\n");
+               return PTR_ERR(phy_provider);
+       }
+
+       return 0;
+}
+
+static struct platform_driver spear1310_miphy_driver = {
+       .probe          = spear1310_miphy_probe,
+       .driver = {
+               .name = "spear1310-miphy",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(spear1310_miphy_of_match),
+       },
+};
+
+static int __init spear1310_miphy_phy_init(void)
+{
+       return platform_driver_register(&spear1310_miphy_driver);
+}
+module_init(spear1310_miphy_phy_init);
+
+static void __exit spear1310_miphy_phy_exit(void)
+{
+       platform_driver_unregister(&spear1310_miphy_driver);
+}
+module_exit(spear1310_miphy_phy_exit);
+
+MODULE_DESCRIPTION("ST SPEAR1310-MIPHY driver");
+MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c
new file mode 100644 (file)
index 0000000..8de98ad
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * ST spear1340-miphy driver
+ *
+ * Copyright (C) 2014 ST Microelectronics
+ * Pratyush Anand <pratyush.anand@st.com>
+ * Mohit Kumar <mohit.kumar@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+
+/* SPEAr1340 Registers */
+/* Power Management Registers */
+#define SPEAR1340_PCM_CFG                      0x100
+       #define SPEAR1340_PCM_CFG_SATA_POWER_EN         BIT(11)
+#define SPEAR1340_PCM_WKUP_CFG                 0x104
+#define SPEAR1340_SWITCH_CTR                   0x108
+
+#define SPEAR1340_PERIP1_SW_RST                        0x318
+       #define SPEAR1340_PERIP1_SW_RSATA               BIT(12)
+#define SPEAR1340_PERIP2_SW_RST                        0x31C
+#define SPEAR1340_PERIP3_SW_RST                        0x320
+
+/* PCIE - SATA configuration registers */
+#define SPEAR1340_PCIE_SATA_CFG                        0x424
+       /* PCIE CFG MASks */
+       #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT       BIT(11)
+       #define SPEAR1340_PCIE_CFG_POWERUP_RESET        BIT(10)
+       #define SPEAR1340_PCIE_CFG_CORE_CLK_EN          BIT(9)
+       #define SPEAR1340_PCIE_CFG_AUX_CLK_EN           BIT(8)
+       #define SPEAR1340_SATA_CFG_TX_CLK_EN            BIT(4)
+       #define SPEAR1340_SATA_CFG_RX_CLK_EN            BIT(3)
+       #define SPEAR1340_SATA_CFG_POWERUP_RESET        BIT(2)
+       #define SPEAR1340_SATA_CFG_PM_CLK_EN            BIT(1)
+       #define SPEAR1340_PCIE_SATA_SEL_PCIE            (0)
+       #define SPEAR1340_PCIE_SATA_SEL_SATA            (1)
+       #define SPEAR1340_PCIE_SATA_CFG_MASK            0xF1F
+       #define SPEAR1340_PCIE_CFG_VAL  (SPEAR1340_PCIE_SATA_SEL_PCIE | \
+                       SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
+                       SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
+                       SPEAR1340_PCIE_CFG_POWERUP_RESET | \
+                       SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
+       #define SPEAR1340_SATA_CFG_VAL  (SPEAR1340_PCIE_SATA_SEL_SATA | \
+                       SPEAR1340_SATA_CFG_PM_CLK_EN | \
+                       SPEAR1340_SATA_CFG_POWERUP_RESET | \
+                       SPEAR1340_SATA_CFG_RX_CLK_EN | \
+                       SPEAR1340_SATA_CFG_TX_CLK_EN)
+
+#define SPEAR1340_PCIE_MIPHY_CFG               0x428
+       #define SPEAR1340_MIPHY_OSC_BYPASS_EXT          BIT(31)
+       #define SPEAR1340_MIPHY_CLK_REF_DIV2            BIT(27)
+       #define SPEAR1340_MIPHY_CLK_REF_DIV4            (2 << 27)
+       #define SPEAR1340_MIPHY_CLK_REF_DIV8            (3 << 27)
+       #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)        (x << 0)
+       #define SPEAR1340_PCIE_MIPHY_CFG_MASK           0xF80000FF
+       #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
+                       (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+                       SPEAR1340_MIPHY_CLK_REF_DIV2 | \
+                       SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
+       #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+                       (SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
+       #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
+                       (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+                       SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
+
+enum spear1340_miphy_mode {
+       SATA,
+       PCIE,
+};
+
+struct spear1340_miphy_priv {
+       /* phy mode: 0 for SATA 1 for PCIe */
+       enum spear1340_miphy_mode       mode;
+       /* regmap for any soc specific misc registers */
+       struct regmap                   *misc;
+       /* phy struct pointer */
+       struct phy                      *phy;
+};
+
+static int spear1340_miphy_sata_init(struct spear1340_miphy_priv *priv)
+{
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+                          SPEAR1340_PCIE_SATA_CFG_MASK,
+                          SPEAR1340_SATA_CFG_VAL);
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+                          SPEAR1340_PCIE_MIPHY_CFG_MASK,
+                          SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK);
+       /* Switch on sata power domain */
+       regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
+                          SPEAR1340_PCM_CFG_SATA_POWER_EN,
+                          SPEAR1340_PCM_CFG_SATA_POWER_EN);
+       /* Wait for SATA power domain on */
+       msleep(20);
+
+       /* Disable PCIE SATA Controller reset */
+       regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
+                          SPEAR1340_PERIP1_SW_RSATA, 0);
+       /* Wait for SATA reset de-assert completion */
+       msleep(20);
+
+       return 0;
+}
+
+static int spear1340_miphy_sata_exit(struct spear1340_miphy_priv *priv)
+{
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+                          SPEAR1340_PCIE_SATA_CFG_MASK, 0);
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+                          SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
+
+       /* Enable PCIE SATA Controller reset */
+       regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
+                          SPEAR1340_PERIP1_SW_RSATA,
+                          SPEAR1340_PERIP1_SW_RSATA);
+       /* Wait for SATA power domain off */
+       msleep(20);
+       /* Switch off sata power domain */
+       regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
+                          SPEAR1340_PCM_CFG_SATA_POWER_EN, 0);
+       /* Wait for SATA reset assert completion */
+       msleep(20);
+
+       return 0;
+}
+
+static int spear1340_miphy_pcie_init(struct spear1340_miphy_priv *priv)
+{
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+                          SPEAR1340_PCIE_MIPHY_CFG_MASK,
+                          SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE);
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+                          SPEAR1340_PCIE_SATA_CFG_MASK,
+                          SPEAR1340_PCIE_CFG_VAL);
+
+       return 0;
+}
+
+static int spear1340_miphy_pcie_exit(struct spear1340_miphy_priv *priv)
+{
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+                          SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
+       regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+                          SPEAR1340_PCIE_SATA_CFG_MASK, 0);
+
+       return 0;
+}
+
+static int spear1340_miphy_init(struct phy *phy)
+{
+       struct spear1340_miphy_priv *priv = phy_get_drvdata(phy);
+       int ret = 0;
+
+       if (priv->mode == SATA)
+               ret = spear1340_miphy_sata_init(priv);
+       else if (priv->mode == PCIE)
+               ret = spear1340_miphy_pcie_init(priv);
+
+       return ret;
+}
+
+static int spear1340_miphy_exit(struct phy *phy)
+{
+       struct spear1340_miphy_priv *priv = phy_get_drvdata(phy);
+       int ret = 0;
+
+       if (priv->mode == SATA)
+               ret = spear1340_miphy_sata_exit(priv);
+       else if (priv->mode == PCIE)
+               ret = spear1340_miphy_pcie_exit(priv);
+
+       return ret;
+}
+
+static const struct of_device_id spear1340_miphy_of_match[] = {
+       { .compatible = "st,spear1340-miphy" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, spear1340_miphy_of_match);
+
+static struct phy_ops spear1340_miphy_ops = {
+       .init = spear1340_miphy_init,
+       .exit = spear1340_miphy_exit,
+       .owner = THIS_MODULE,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int spear1340_miphy_suspend(struct device *dev)
+{
+       struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
+       int ret = 0;
+
+       if (priv->mode == SATA)
+               ret = spear1340_miphy_sata_exit(priv);
+
+       return ret;
+}
+
+static int spear1340_miphy_resume(struct device *dev)
+{
+       struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
+       int ret = 0;
+
+       if (priv->mode == SATA)
+               ret = spear1340_miphy_sata_init(priv);
+
+       return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(spear1340_miphy_pm_ops, spear1340_miphy_suspend,
+                        spear1340_miphy_resume);
+
+static struct phy *spear1340_miphy_xlate(struct device *dev,
+                                        struct of_phandle_args *args)
+{
+       struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
+
+       if (args->args_count < 1) {
+               dev_err(dev, "DT did not pass correct no of args\n");
+               return NULL;
+       }
+
+       priv->mode = args->args[0];
+
+       if (priv->mode != SATA && priv->mode != PCIE) {
+               dev_err(dev, "DT did not pass correct phy mode\n");
+               return NULL;
+       }
+
+       return priv->phy;
+}
+
+static int spear1340_miphy_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct spear1340_miphy_priv *priv;
+       struct phy_provider *phy_provider;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(dev, "can't alloc spear1340_miphy private date memory\n");
+               return -ENOMEM;
+       }
+
+       priv->misc =
+               syscon_regmap_lookup_by_phandle(dev->of_node, "misc");
+       if (IS_ERR(priv->misc)) {
+               dev_err(dev, "failed to find misc regmap\n");
+               return PTR_ERR(priv->misc);
+       }
+
+       priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL);
+       if (IS_ERR(priv->phy)) {
+               dev_err(dev, "failed to create SATA PCIe PHY\n");
+               return PTR_ERR(priv->phy);
+       }
+
+       dev_set_drvdata(dev, priv);
+       phy_set_drvdata(priv->phy, priv);
+
+       phy_provider =
+               devm_of_phy_provider_register(dev, spear1340_miphy_xlate);
+       if (IS_ERR(phy_provider)) {
+               dev_err(dev, "failed to register phy provider\n");
+               return PTR_ERR(phy_provider);
+       }
+
+       return 0;
+}
+
+static struct platform_driver spear1340_miphy_driver = {
+       .probe          = spear1340_miphy_probe,
+       .driver = {
+               .name = "spear1340-miphy",
+               .owner = THIS_MODULE,
+               .pm = &spear1340_miphy_pm_ops,
+               .of_match_table = of_match_ptr(spear1340_miphy_of_match),
+       },
+};
+
+static int __init spear1340_miphy_phy_init(void)
+{
+       return platform_driver_register(&spear1340_miphy_driver);
+}
+module_init(spear1340_miphy_phy_init);
+
+static void __exit spear1340_miphy_phy_exit(void)
+{
+       platform_driver_unregister(&spear1340_miphy_driver);
+}
+module_exit(spear1340_miphy_phy_exit);
+
+MODULE_DESCRIPTION("ST SPEAR1340-MIPHY driver");
+MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>");
+MODULE_LICENSE("GPL v2");
index 6aea373..ee3de34 100644 (file)
@@ -74,7 +74,7 @@ config DP83640_PHY
 
 config PTP_1588_CLOCK_PCH
        tristate "Intel PCH EG20T as PTP clock"
-       depends on X86 || COMPILE_TEST
+       depends on X86_32 || COMPILE_TEST
        depends on HAS_IOMEM && NET
        select PTP_1588_CLOCK
        help
index 4ad7b89..331dfca 100644 (file)
@@ -43,7 +43,7 @@ config PWM_AB8500
 
 config PWM_ATMEL
        tristate "Atmel PWM support"
-       depends on ARCH_AT91
+       depends on ARCH_AT91 || AVR32
        help
          Generic PWM framework driver for Atmel SoC.
 
index 8558521..ad9e0c9 100644 (file)
@@ -433,6 +433,7 @@ static struct regulator_ops as3722_ldo3_extcntrl_ops = {
 };
 
 static const struct regulator_linear_range as3722_ldo_ranges[] = {
+       REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0),
        REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000),
        REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000),
 };
@@ -609,6 +610,7 @@ static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs)
 }
 
 static const struct regulator_linear_range as3722_sd2345_ranges[] = {
+       REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0),
        REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500),
        REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
        REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7F, 50000),
index 57544e2..58ece59 100644 (file)
@@ -119,6 +119,10 @@ static const unsigned int ldo_c_table[] = {
        2900000, 3000000, 3300000,
 };
 
+static const unsigned int ldo_vbus[] = {
+       5000000,
+};
+
 /* DCDC group CSR: supported voltages in microvolts */
 static const struct regulator_linear_range dcdc_csr_ranges[] = {
        REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
@@ -192,6 +196,7 @@ static struct bcm590xx_info bcm590xx_regs[] = {
        BCM590XX_REG_TABLE(gpldo4, ldo_a_table),
        BCM590XX_REG_TABLE(gpldo5, ldo_a_table),
        BCM590XX_REG_TABLE(gpldo6, ldo_a_table),
+       BCM590XX_REG_TABLE(vbus, ldo_vbus),
 };
 
 struct bcm590xx_reg {
index 110a99e..c810518 100644 (file)
@@ -255,7 +255,7 @@ static int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589)
        struct device_node *node;
        int i, ret;
 
-       node = of_find_node_by_name(dev->of_node, "regulators");
+       node = of_get_child_by_name(dev->of_node, "regulators");
        if (!node) {
                dev_err(dev, "regulators node not found\n");
                return -EINVAL;
index 864ed02..93b4ad8 100644 (file)
@@ -37,12 +37,14 @@ struct regs_info {
 };
 
 static const struct regulator_linear_range smps_low_ranges[] = {
+       REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
        REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0),
        REGULATOR_LINEAR_RANGE(510000, 0x7, 0x79, 10000),
        REGULATOR_LINEAR_RANGE(1650000, 0x7A, 0x7f, 0),
 };
 
 static const struct regulator_linear_range smps_high_ranges[] = {
+       REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
        REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x6, 0),
        REGULATOR_LINEAR_RANGE(1020000, 0x7, 0x79, 20000),
        REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0),
@@ -323,6 +325,10 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
        if (rail_enable)
                palmas_smps_write(pmic->palmas,
                        palmas_regs_info[id].ctrl_addr, reg);
+
+       /* Switch the enable value to ensure this is used for enable */
+       pmic->desc[id].enable_val = pmic->current_reg_mode[id];
+
        return 0;
 }
 
@@ -962,6 +968,14 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                                return ret;
                        pmic->current_reg_mode[id] = reg &
                                        PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+
+                       pmic->desc[id].enable_reg =
+                                       PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                               palmas_regs_info[id].ctrl_addr);
+                       pmic->desc[id].enable_mask =
+                                       PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+                       /* set_mode overrides this value */
+                       pmic->desc[id].enable_val = SMPS_CTRL_MODE_ON;
                }
 
                pmic->desc[id].type = REGULATOR_VOLTAGE;
index 69b4b77..9effe48 100644 (file)
@@ -209,7 +209,7 @@ static const struct regulator_desc regulators[] = {
                           1, -1, -1, TPS65218_REG_ENABLE1,
                           TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0),
        TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64,
-                          TPS65218_REG_CONTROL_DCDC4,
+                          TPS65218_REG_CONTROL_LDO1,
                           TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
                           TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges,
                           2, 0),
@@ -240,6 +240,7 @@ static int tps65218_regulator_probe(struct platform_device *pdev)
        config.init_data = init_data;
        config.driver_data = tps;
        config.regmap = tps->regmap;
+       config.of_node = pdev->dev.of_node;
 
        rdev = devm_regulator_register(&pdev->dev, &regulators[id], &config);
        if (IS_ERR(rdev)) {
index ce1743d..5e343ba 100644 (file)
@@ -44,7 +44,7 @@ config STE_MODEM_RPROC
 config DA8XX_REMOTEPROC
        tristate "DA8xx/OMAP-L13x remoteproc support"
        depends on ARCH_DAVINCI_DA8XX
-       select CMA
+       select CMA if MMU
        select REMOTEPROC
        select RPMSG
        help
index 1ecfe3b..1cff2a2 100644 (file)
@@ -71,7 +71,7 @@ static int puv3_rtc_setpie(struct device *dev, int enabled)
 {
        unsigned int tmp;
 
-       dev_debug(dev, "%s: pie=%d\n", __func__, enabled);
+       dev_dbg(dev, "%s: pie=%d\n", __func__, enabled);
 
        spin_lock_irq(&puv3_rtc_pie_lock);
        tmp = readl(RTC_RTSR) & ~RTC_RTSR_HZE;
@@ -140,7 +140,7 @@ static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
        rtc_tm_to_time(tm, &rtcalarm_count);
        writel(rtcalarm_count, RTC_RTAR);
 
-       puv3_rtc_setaie(&dev->dev, alrm->enabled);
+       puv3_rtc_setaie(dev, alrm->enabled);
 
        if (alrm->enabled)
                enable_irq_wake(puv3_rtc_alarmno);
index ee0e85a..0f47175 100644 (file)
@@ -593,7 +593,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
        dev_info->start = dcssblk_find_lowest_addr(dev_info);
        dev_info->end = dcssblk_find_highest_addr(dev_info);
 
-       dev_set_name(&dev_info->dev, dev_info->segment_name);
+       dev_set_name(&dev_info->dev, "%s", dev_info->segment_name);
        dev_info->dev.release = dcssblk_release_segment;
        dev_info->dev.groups = dcssblk_dev_attr_groups;
        INIT_LIST_HEAD(&dev_info->lh);
index 629fcc2..78b6ace 100644 (file)
@@ -19,7 +19,6 @@ obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
 obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
 obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o
 
-obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o
 obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
 obj-$(CONFIG_VMCP) += vmcp.o
 
index cd9c919..b9a9f72 100644 (file)
@@ -838,8 +838,6 @@ sclp_vt220_con_init(void)
 {
        int rc;
 
-       if (!CONSOLE_IS_SCLP)
-               return 0;
        rc = __sclp_vt220_init(sclp_console_pages);
        if (rc)
                return rc;
index cf31d33..a8848db 100644 (file)
@@ -761,7 +761,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
 
        dev = kzalloc(sizeof(struct device), GFP_KERNEL);
        if (dev) {
-               dev_set_name(dev, priv->internal_name);
+               dev_set_name(dev, "%s", priv->internal_name);
                dev->bus = &iucv_bus;
                dev->parent = iucv_root;
                dev->driver = &vmlogrdr_driver;
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
deleted file mode 100644 (file)
index d5eac98..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Watchdog implementation based on z/VM Watchdog Timer API
- *
- * Copyright IBM Corp. 2004, 2009
- *
- * The user space watchdog daemon can use this driver as
- * /dev/vmwatchdog to have z/VM execute the specified CP
- * command when the timeout expires. The default command is
- * "IPL", which which cause an immediate reboot.
- */
-#define KMSG_COMPONENT "vmwatchdog"
-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
-
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/suspend.h>
-#include <linux/watchdog.h>
-
-#include <asm/ebcdic.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#define MAX_CMDLEN 240
-#define MIN_INTERVAL 15
-static char vmwdt_cmd[MAX_CMDLEN] = "IPL";
-static bool vmwdt_conceal;
-
-static bool vmwdt_nowayout = WATCHDOG_NOWAYOUT;
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
-MODULE_DESCRIPTION("z/VM Watchdog Timer");
-module_param_string(cmd, vmwdt_cmd, MAX_CMDLEN, 0644);
-MODULE_PARM_DESC(cmd, "CP command that is run when the watchdog triggers");
-module_param_named(conceal, vmwdt_conceal, bool, 0644);
-MODULE_PARM_DESC(conceal, "Enable the CONCEAL CP option while the watchdog "
-               " is active");
-module_param_named(nowayout, vmwdt_nowayout, bool, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"
-               " (default=CONFIG_WATCHDOG_NOWAYOUT)");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-
-static unsigned int vmwdt_interval = 60;
-static unsigned long vmwdt_is_open;
-static int vmwdt_expect_close;
-
-static DEFINE_MUTEX(vmwdt_mutex);
-
-#define VMWDT_OPEN     0       /* devnode is open or suspend in progress */
-#define VMWDT_RUNNING  1       /* The watchdog is armed */
-
-enum vmwdt_func {
-       /* function codes */
-       wdt_init   = 0,
-       wdt_change = 1,
-       wdt_cancel = 2,
-       /* flags */
-       wdt_conceal = 0x80000000,
-};
-
-static int __diag288(enum vmwdt_func func, unsigned int timeout,
-                           char *cmd, size_t len)
-{
-       register unsigned long __func asm("2") = func;
-       register unsigned long __timeout asm("3") = timeout;
-       register unsigned long __cmdp asm("4") = virt_to_phys(cmd);
-       register unsigned long __cmdl asm("5") = len;
-       int err;
-
-       err = -EINVAL;
-       asm volatile(
-               "       diag    %1,%3,0x288\n"
-               "0:     la      %0,0\n"
-               "1:\n"
-               EX_TABLE(0b,1b)
-               : "+d" (err) : "d"(__func), "d"(__timeout),
-                 "d"(__cmdp), "d"(__cmdl) : "1", "cc");
-       return err;
-}
-
-static int vmwdt_keepalive(void)
-{
-       /* we allocate new memory every time to avoid having
-        * to track the state. static allocation is not an
-        * option since that might not be contiguous in real
-        * storage in case of a modular build */
-       static char *ebc_cmd;
-       size_t len;
-       int ret;
-       unsigned int func;
-
-       ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL);
-       if (!ebc_cmd)
-               return -ENOMEM;
-
-       len = strlcpy(ebc_cmd, vmwdt_cmd, MAX_CMDLEN);
-       ASCEBC(ebc_cmd, MAX_CMDLEN);
-       EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
-
-       func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init;
-       set_bit(VMWDT_RUNNING, &vmwdt_is_open);
-       ret = __diag288(func, vmwdt_interval, ebc_cmd, len);
-       WARN_ON(ret != 0);
-       kfree(ebc_cmd);
-       return ret;
-}
-
-static int vmwdt_disable(void)
-{
-       char cmd[] = {'\0'};
-       int ret = __diag288(wdt_cancel, 0, cmd, 0);
-       WARN_ON(ret != 0);
-       clear_bit(VMWDT_RUNNING, &vmwdt_is_open);
-       return ret;
-}
-
-static int __init vmwdt_probe(void)
-{
-       /* there is no real way to see if the watchdog is supported,
-        * so we try initializing it with a NOP command ("BEGIN")
-        * that won't cause any harm even if the following disable
-        * fails for some reason */
-       char ebc_begin[] = {
-               194, 197, 199, 201, 213
-       };
-       if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0)
-               return -EINVAL;
-       return vmwdt_disable();
-}
-
-static int vmwdt_open(struct inode *i, struct file *f)
-{
-       int ret;
-       if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open))
-               return -EBUSY;
-       ret = vmwdt_keepalive();
-       if (ret)
-               clear_bit(VMWDT_OPEN, &vmwdt_is_open);
-       return ret ? ret : nonseekable_open(i, f);
-}
-
-static int vmwdt_close(struct inode *i, struct file *f)
-{
-       if (vmwdt_expect_close == 42)
-               vmwdt_disable();
-       vmwdt_expect_close = 0;
-       clear_bit(VMWDT_OPEN, &vmwdt_is_open);
-       return 0;
-}
-
-static struct watchdog_info vmwdt_info = {
-       .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
-       .firmware_version = 0,
-       .identity = "z/VM Watchdog Timer",
-};
-
-static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case WDIOC_GETSUPPORT:
-               if (copy_to_user((void __user *)arg, &vmwdt_info,
-                                       sizeof(vmwdt_info)))
-                       return -EFAULT;
-               return 0;
-       case WDIOC_GETSTATUS:
-       case WDIOC_GETBOOTSTATUS:
-               return put_user(0, (int __user *)arg);
-       case WDIOC_GETTEMP:
-               return -EINVAL;
-       case WDIOC_SETOPTIONS:
-               {
-                       int options, ret;
-                       if (get_user(options, (int __user *)arg))
-                               return -EFAULT;
-                       ret = -EINVAL;
-                       if (options & WDIOS_DISABLECARD) {
-                               ret = vmwdt_disable();
-                               if (ret)
-                                       return ret;
-                       }
-                       if (options & WDIOS_ENABLECARD) {
-                               ret = vmwdt_keepalive();
-                       }
-                       return ret;
-               }
-       case WDIOC_GETTIMEOUT:
-               return put_user(vmwdt_interval, (int __user *)arg);
-       case WDIOC_SETTIMEOUT:
-               {
-                       int interval;
-                       if (get_user(interval, (int __user *)arg))
-                               return -EFAULT;
-                       if (interval < MIN_INTERVAL)
-                               return -EINVAL;
-                       vmwdt_interval = interval;
-               }
-               return vmwdt_keepalive();
-       case WDIOC_KEEPALIVE:
-               return vmwdt_keepalive();
-       }
-       return -EINVAL;
-}
-
-static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
-{
-       int rc;
-
-       mutex_lock(&vmwdt_mutex);
-       rc = __vmwdt_ioctl(cmd, arg);
-       mutex_unlock(&vmwdt_mutex);
-       return (long) rc;
-}
-
-static ssize_t vmwdt_write(struct file *f, const char __user *buf,
-                               size_t count, loff_t *ppos)
-{
-       if(count) {
-               if (!vmwdt_nowayout) {
-                       size_t i;
-
-                       /* note: just in case someone wrote the magic character
-                        * five months ago... */
-                       vmwdt_expect_close = 0;
-
-                       for (i = 0; i != count; i++) {
-                               char c;
-                               if (get_user(c, buf+i))
-                                       return -EFAULT;
-                               if (c == 'V')
-                                       vmwdt_expect_close = 42;
-                       }
-               }
-               /* someone wrote to us, we should restart timer */
-               vmwdt_keepalive();
-       }
-       return count;
-}
-
-static int vmwdt_resume(void)
-{
-       clear_bit(VMWDT_OPEN, &vmwdt_is_open);
-       return NOTIFY_DONE;
-}
-
-/*
- * It makes no sense to go into suspend while the watchdog is running.
- * Depending on the memory size, the watchdog might trigger, while we
- * are still saving the memory.
- * We reuse the open flag to ensure that suspend and watchdog open are
- * exclusive operations
- */
-static int vmwdt_suspend(void)
-{
-       if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
-               pr_err("The system cannot be suspended while the watchdog"
-                       " is in use\n");
-               return notifier_from_errno(-EBUSY);
-       }
-       if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) {
-               clear_bit(VMWDT_OPEN, &vmwdt_is_open);
-               pr_err("The system cannot be suspended while the watchdog"
-                       " is running\n");
-               return notifier_from_errno(-EBUSY);
-       }
-       return NOTIFY_DONE;
-}
-
-/*
- * This function is called for suspend and resume.
- */
-static int vmwdt_power_event(struct notifier_block *this, unsigned long event,
-                            void *ptr)
-{
-       switch (event) {
-       case PM_POST_HIBERNATION:
-       case PM_POST_SUSPEND:
-               return vmwdt_resume();
-       case PM_HIBERNATION_PREPARE:
-       case PM_SUSPEND_PREPARE:
-               return vmwdt_suspend();
-       default:
-               return NOTIFY_DONE;
-       }
-}
-
-static struct notifier_block vmwdt_power_notifier = {
-       .notifier_call = vmwdt_power_event,
-};
-
-static const struct file_operations vmwdt_fops = {
-       .open    = &vmwdt_open,
-       .release = &vmwdt_close,
-       .unlocked_ioctl = &vmwdt_ioctl,
-       .write   = &vmwdt_write,
-       .owner   = THIS_MODULE,
-       .llseek  = noop_llseek,
-};
-
-static struct miscdevice vmwdt_dev = {
-       .minor      = WATCHDOG_MINOR,
-       .name       = "watchdog",
-       .fops       = &vmwdt_fops,
-};
-
-static int __init vmwdt_init(void)
-{
-       int ret;
-
-       ret = vmwdt_probe();
-       if (ret)
-               return ret;
-       ret = register_pm_notifier(&vmwdt_power_notifier);
-       if (ret)
-               return ret;
-       /*
-        * misc_register() has to be the last action in module_init(), because
-        * file operations will be available right after this.
-        */
-       ret = misc_register(&vmwdt_dev);
-       if (ret) {
-               unregister_pm_notifier(&vmwdt_power_notifier);
-               return ret;
-       }
-       return 0;
-}
-module_init(vmwdt_init);
-
-static void __exit vmwdt_exit(void)
-{
-       unregister_pm_notifier(&vmwdt_power_notifier);
-       misc_deregister(&vmwdt_dev);
-}
-module_exit(vmwdt_exit);
index 445564c..00bfbee 100644 (file)
@@ -196,11 +196,11 @@ EXPORT_SYMBOL(airq_iv_release);
  */
 unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)
 {
-       unsigned long bit, i;
+       unsigned long bit, i, flags;
 
        if (!iv->avail || num == 0)
                return -1UL;
-       spin_lock(&iv->lock);
+       spin_lock_irqsave(&iv->lock, flags);
        bit = find_first_bit_inv(iv->avail, iv->bits);
        while (bit + num <= iv->bits) {
                for (i = 1; i < num; i++)
@@ -218,9 +218,8 @@ unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)
        }
        if (bit + num > iv->bits)
                bit = -1UL;
-       spin_unlock(&iv->lock);
+       spin_unlock_irqrestore(&iv->lock, flags);
        return bit;
-
 }
 EXPORT_SYMBOL(airq_iv_alloc);
 
@@ -232,11 +231,11 @@ EXPORT_SYMBOL(airq_iv_alloc);
  */
 void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)
 {
-       unsigned long i;
+       unsigned long i, flags;
 
        if (!iv->avail || num == 0)
                return;
-       spin_lock(&iv->lock);
+       spin_lock_irqsave(&iv->lock, flags);
        for (i = 0; i < num; i++) {
                /* Clear (possibly left over) interrupt bit */
                clear_bit_inv(bit + i, iv->vector);
@@ -248,7 +247,7 @@ void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)
                while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail))
                        iv->end--;
        }
-       spin_unlock(&iv->lock);
+       spin_unlock_irqrestore(&iv->lock, flags);
 }
 EXPORT_SYMBOL(airq_iv_free);
 
index dfd7bc6..e443b0d 100644 (file)
@@ -184,7 +184,7 @@ static ssize_t ccwgroup_ungroup_store(struct device *dev,
                                      const char *buf, size_t count)
 {
        struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
-       int rc;
+       int rc = 0;
 
        /* Prevent concurrent online/offline processing and ungrouping. */
        if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
@@ -196,11 +196,12 @@ static ssize_t ccwgroup_ungroup_store(struct device *dev,
 
        if (device_remove_file_self(dev, attr))
                ccwgroup_ungroup(gdev);
+       else
+               rc = -ENODEV;
 out:
        if (rc) {
-               if (rc != -EAGAIN)
-                       /* Release onoff "lock" when ungrouping failed. */
-                       atomic_set(&gdev->onoff, 0);
+               /* Release onoff "lock" when ungrouping failed. */
+               atomic_set(&gdev->onoff, 0);
                return rc;
        }
        return count;
@@ -227,6 +228,7 @@ static void ccwgroup_ungroup_workfn(struct work_struct *work)
                container_of(work, struct ccwgroup_device, ungroup_work);
 
        ccwgroup_ungroup(gdev);
+       put_device(&gdev->dev);
 }
 
 static void ccwgroup_release(struct device *dev)
@@ -412,8 +414,10 @@ static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
 {
        struct ccwgroup_device *gdev = to_ccwgroupdev(data);
 
-       if (action == BUS_NOTIFY_UNBIND_DRIVER)
+       if (action == BUS_NOTIFY_UNBIND_DRIVER) {
+               get_device(&gdev->dev);
                schedule_work(&gdev->ungroup_work);
+       }
 
        return NOTIFY_OK;
 }
@@ -582,11 +586,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
                                         __ccwgroup_match_all))) {
                struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
 
-               mutex_lock(&gdev->reg_mutex);
-               __ccwgroup_remove_symlinks(gdev);
-               device_unregister(dev);
-               __ccwgroup_remove_cdev_refs(gdev);
-               mutex_unlock(&gdev->reg_mutex);
+               ccwgroup_ungroup(gdev);
                put_device(dev);
        }
        driver_unregister(&cdriver->driver);
@@ -633,13 +633,7 @@ void ccwgroup_remove_ccwdev(struct ccw_device *cdev)
        get_device(&gdev->dev);
        spin_unlock_irq(cdev->ccwlock);
        /* Unregister group device. */
-       mutex_lock(&gdev->reg_mutex);
-       if (device_is_registered(&gdev->dev)) {
-               __ccwgroup_remove_symlinks(gdev);
-               device_unregister(&gdev->dev);
-               __ccwgroup_remove_cdev_refs(gdev);
-       }
-       mutex_unlock(&gdev->reg_mutex);
+       ccwgroup_ungroup(gdev);
        /* Release ccwgroup device reference for local processing. */
        put_device(&gdev->dev);
 }
index 77f9c92..2905d8b 100644 (file)
@@ -602,6 +602,7 @@ void __init init_cio_interrupts(void)
 
 #ifdef CONFIG_CCW_CONSOLE
 static struct subchannel *console_sch;
+static struct lock_class_key console_sch_key;
 
 /*
  * Use cio_tsch to update the subchannel status and call the interrupt handler
@@ -686,6 +687,7 @@ struct subchannel *cio_probe_console(void)
        if (IS_ERR(sch))
                return sch;
 
+       lockdep_set_class(sch->lock, &console_sch_key);
        isc_register(CONSOLE_ISC);
        sch->config.isc = CONSOLE_ISC;
        sch->config.intparm = (u32)(addr_t)sch;
index d8d9b5b..dfef5e6 100644 (file)
@@ -678,18 +678,11 @@ static const struct attribute_group *ccwdev_attr_groups[] = {
        NULL,
 };
 
-/* this is a simple abstraction for device_register that sets the
- * correct bus type and adds the bus specific files */
-static int ccw_device_register(struct ccw_device *cdev)
+static int ccw_device_add(struct ccw_device *cdev)
 {
        struct device *dev = &cdev->dev;
-       int ret;
 
        dev->bus = &ccw_bus_type;
-       ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid,
-                          cdev->private->dev_id.devno);
-       if (ret)
-               return ret;
        return device_add(dev);
 }
 
@@ -764,22 +757,46 @@ static void ccw_device_todo(struct work_struct *work);
 static int io_subchannel_initialize_dev(struct subchannel *sch,
                                        struct ccw_device *cdev)
 {
-       cdev->private->cdev = cdev;
-       cdev->private->int_class = IRQIO_CIO;
-       atomic_set(&cdev->private->onoff, 0);
+       struct ccw_device_private *priv = cdev->private;
+       int ret;
+
+       priv->cdev = cdev;
+       priv->int_class = IRQIO_CIO;
+       priv->state = DEV_STATE_NOT_OPER;
+       priv->dev_id.devno = sch->schib.pmcw.dev;
+       priv->dev_id.ssid = sch->schid.ssid;
+       priv->schid = sch->schid;
+
+       INIT_WORK(&priv->todo_work, ccw_device_todo);
+       INIT_LIST_HEAD(&priv->cmb_list);
+       init_waitqueue_head(&priv->wait_q);
+       init_timer(&priv->timer);
+
+       atomic_set(&priv->onoff, 0);
+       cdev->ccwlock = sch->lock;
        cdev->dev.parent = &sch->dev;
        cdev->dev.release = ccw_device_release;
-       INIT_WORK(&cdev->private->todo_work, ccw_device_todo);
        cdev->dev.groups = ccwdev_attr_groups;
        /* Do first half of device_register. */
        device_initialize(&cdev->dev);
+       ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid,
+                          cdev->private->dev_id.devno);
+       if (ret)
+               goto out_put;
        if (!get_device(&sch->dev)) {
-               /* Release reference from device_initialize(). */
-               put_device(&cdev->dev);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_put;
        }
-       cdev->private->flags.initialized = 1;
+       priv->flags.initialized = 1;
+       spin_lock_irq(sch->lock);
+       sch_set_cdev(sch, cdev);
+       spin_unlock_irq(sch->lock);
        return 0;
+
+out_put:
+       /* Release reference from device_initialize(). */
+       put_device(&cdev->dev);
+       return ret;
 }
 
 static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch)
@@ -858,7 +875,7 @@ static void io_subchannel_register(struct ccw_device *cdev)
        dev_set_uevent_suppress(&sch->dev, 0);
        kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
        /* make it known to the system */
-       ret = ccw_device_register(cdev);
+       ret = ccw_device_add(cdev);
        if (ret) {
                CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n",
                              cdev->private->dev_id.ssid,
@@ -923,26 +940,11 @@ io_subchannel_recog_done(struct ccw_device *cdev)
 
 static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
 {
-       struct ccw_device_private *priv;
-
-       cdev->ccwlock = sch->lock;
-
-       /* Init private data. */
-       priv = cdev->private;
-       priv->dev_id.devno = sch->schib.pmcw.dev;
-       priv->dev_id.ssid = sch->schid.ssid;
-       priv->schid = sch->schid;
-       priv->state = DEV_STATE_NOT_OPER;
-       INIT_LIST_HEAD(&priv->cmb_list);
-       init_waitqueue_head(&priv->wait_q);
-       init_timer(&priv->timer);
-
        /* Increase counter of devices currently in recognition. */
        atomic_inc(&ccw_device_init_count);
 
        /* Start async. device sensing. */
        spin_lock_irq(sch->lock);
-       sch_set_cdev(sch, cdev);
        ccw_device_recognition(cdev);
        spin_unlock_irq(sch->lock);
 }
@@ -1083,7 +1085,7 @@ static int io_subchannel_probe(struct subchannel *sch)
                dev_set_uevent_suppress(&sch->dev, 0);
                kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
                cdev = sch_get_cdev(sch);
-               rc = ccw_device_register(cdev);
+               rc = ccw_device_add(cdev);
                if (rc) {
                        /* Release online reference. */
                        put_device(&cdev->dev);
@@ -1597,7 +1599,6 @@ int __init ccw_device_enable_console(struct ccw_device *cdev)
        if (rc)
                return rc;
        sch->driver = &io_subchannel_driver;
-       sch_set_cdev(sch, cdev);
        io_subchannel_recog(cdev, sch);
        /* Now wait for the async. recognition to come to an end. */
        spin_lock_irq(cdev->ccwlock);
@@ -1639,6 +1640,7 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv)
                put_device(&sch->dev);
                return ERR_PTR(-ENOMEM);
        }
+       set_io_private(sch, io_priv);
        cdev = io_subchannel_create_ccwdev(sch);
        if (IS_ERR(cdev)) {
                put_device(&sch->dev);
@@ -1646,7 +1648,6 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv)
                return cdev;
        }
        cdev->drv = drv;
-       set_io_private(sch, io_priv);
        ccw_device_set_int_class(cdev);
        return cdev;
 }
index 4221b02..f1f3baa 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/export.h>
+#include <linux/slab.h>
 #include <asm/debug.h>
 #include "qdio_debug.h"
 #include "qdio.h"
@@ -16,11 +17,51 @@ debug_info_t *qdio_dbf_error;
 
 static struct dentry *debugfs_root;
 #define QDIO_DEBUGFS_NAME_LEN  10
+#define QDIO_DBF_NAME_LEN      20
 
-void qdio_allocate_dbf(struct qdio_initialize *init_data,
+struct qdio_dbf_entry {
+       char dbf_name[QDIO_DBF_NAME_LEN];
+       debug_info_t *dbf_info;
+       struct list_head dbf_list;
+};
+
+static LIST_HEAD(qdio_dbf_list);
+static DEFINE_MUTEX(qdio_dbf_list_mutex);
+
+static debug_info_t *qdio_get_dbf_entry(char *name)
+{
+       struct qdio_dbf_entry *entry;
+       debug_info_t *rc = NULL;
+
+       mutex_lock(&qdio_dbf_list_mutex);
+       list_for_each_entry(entry, &qdio_dbf_list, dbf_list) {
+               if (strcmp(entry->dbf_name, name) == 0) {
+                       rc = entry->dbf_info;
+                       break;
+               }
+       }
+       mutex_unlock(&qdio_dbf_list_mutex);
+       return rc;
+}
+
+static void qdio_clear_dbf_list(void)
+{
+       struct qdio_dbf_entry *entry, *tmp;
+
+       mutex_lock(&qdio_dbf_list_mutex);
+       list_for_each_entry_safe(entry, tmp, &qdio_dbf_list, dbf_list) {
+               list_del(&entry->dbf_list);
+               debug_unregister(entry->dbf_info);
+               kfree(entry);
+       }
+       mutex_unlock(&qdio_dbf_list_mutex);
+}
+
+int qdio_allocate_dbf(struct qdio_initialize *init_data,
                       struct qdio_irq *irq_ptr)
 {
-       char text[20];
+       char text[QDIO_DBF_NAME_LEN];
+       struct qdio_dbf_entry *new_entry;
 
        DBF_EVENT("qfmt:%1d", init_data->q_format);
        DBF_HEX(init_data->adapter_name, 8);
@@ -38,11 +79,34 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data,
        DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
 
        /* allocate trace view for the interface */
-       snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev));
-       irq_ptr->debug_area = debug_register(text, 2, 1, 16);
-       debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view);
-       debug_set_level(irq_ptr->debug_area, DBF_WARN);
-       DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
+       snprintf(text, QDIO_DBF_NAME_LEN, "qdio_%s",
+                                       dev_name(&init_data->cdev->dev));
+       irq_ptr->debug_area = qdio_get_dbf_entry(text);
+       if (irq_ptr->debug_area)
+               DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf reused");
+       else {
+               irq_ptr->debug_area = debug_register(text, 2, 1, 16);
+               if (!irq_ptr->debug_area)
+                       return -ENOMEM;
+               if (debug_register_view(irq_ptr->debug_area,
+                                               &debug_hex_ascii_view)) {
+                       debug_unregister(irq_ptr->debug_area);
+                       return -ENOMEM;
+               }
+               debug_set_level(irq_ptr->debug_area, DBF_WARN);
+               DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
+               new_entry = kzalloc(sizeof(struct qdio_dbf_entry), GFP_KERNEL);
+               if (!new_entry) {
+                       debug_unregister(irq_ptr->debug_area);
+                       return -ENOMEM;
+               }
+               strlcpy(new_entry->dbf_name, text, QDIO_DBF_NAME_LEN);
+               new_entry->dbf_info = irq_ptr->debug_area;
+               mutex_lock(&qdio_dbf_list_mutex);
+               list_add(&new_entry->dbf_list, &qdio_dbf_list);
+               mutex_unlock(&qdio_dbf_list_mutex);
+       }
+       return 0;
 }
 
 static int qstat_show(struct seq_file *m, void *v)
@@ -300,6 +364,7 @@ int __init qdio_debug_init(void)
 
 void qdio_debug_exit(void)
 {
+       qdio_clear_dbf_list();
        debugfs_remove(debugfs_root);
        if (qdio_dbf_setup)
                debug_unregister(qdio_dbf_setup);
index dfac9bf..f33ce85 100644 (file)
@@ -75,7 +75,7 @@ static inline void DBF_DEV_HEX(struct qdio_irq *dev, void *addr,
        }
 }
 
-void qdio_allocate_dbf(struct qdio_initialize *init_data,
+int qdio_allocate_dbf(struct qdio_initialize *init_data,
                       struct qdio_irq *irq_ptr);
 void qdio_setup_debug_entries(struct qdio_irq *irq_ptr,
                              struct ccw_device *cdev);
index 77466c4..848e3b6 100644 (file)
@@ -409,17 +409,16 @@ static inline void qdio_stop_polling(struct qdio_q *q)
                set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
 }
 
-static inline void account_sbals(struct qdio_q *q, int count)
+static inline void account_sbals(struct qdio_q *q, unsigned int count)
 {
-       int pos = 0;
+       int pos;
 
        q->q_stats.nr_sbal_total += count;
        if (count == QDIO_MAX_BUFFERS_MASK) {
                q->q_stats.nr_sbals[7]++;
                return;
        }
-       while (count >>= 1)
-               pos++;
+       pos = ilog2(count);
        q->q_stats.nr_sbals[pos]++;
 }
 
@@ -1234,12 +1233,10 @@ int qdio_free(struct ccw_device *cdev)
                return -ENODEV;
 
        DBF_EVENT("qfree:%4x", cdev->private->schid.sch_no);
+       DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf abandoned");
        mutex_lock(&irq_ptr->setup_mutex);
 
-       if (irq_ptr->debug_area != NULL) {
-               debug_unregister(irq_ptr->debug_area);
-               irq_ptr->debug_area = NULL;
-       }
+       irq_ptr->debug_area = NULL;
        cdev->private->qdio_data = NULL;
        mutex_unlock(&irq_ptr->setup_mutex);
 
@@ -1276,7 +1273,8 @@ int qdio_allocate(struct qdio_initialize *init_data)
                goto out_err;
 
        mutex_init(&irq_ptr->setup_mutex);
-       qdio_allocate_dbf(init_data, irq_ptr);
+       if (qdio_allocate_dbf(init_data, irq_ptr))
+               goto out_rel;
 
        /*
         * Allocate a page for the chsc calls in qdio_establish.
index 8eec165..69ef4f8 100644 (file)
@@ -77,12 +77,12 @@ MODULE_ALIAS("z90crypt");
  * Module parameter
  */
 int ap_domain_index = -1;      /* Adjunct Processor Domain Index */
-module_param_named(domain, ap_domain_index, int, 0000);
+module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
 MODULE_PARM_DESC(domain, "domain index for ap devices");
 EXPORT_SYMBOL(ap_domain_index);
 
 static int ap_thread_flag = 0;
-module_param_named(poll_thread, ap_thread_flag, int, 0000);
+module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
 MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
 
 static struct device *ap_root_device = NULL;
index 5222ebe..0e18c5d 100644 (file)
@@ -356,7 +356,7 @@ struct zcrypt_ops *zcrypt_msgtype_request(unsigned char *name, int variant)
 
        zops = __ops_lookup(name, variant);
        if (!zops) {
-               request_module(name);
+               request_module("%s", name);
                zops = __ops_lookup(name, variant);
        }
        if ((!zops) || (!try_module_get(zops->owner)))
index 1e4479f..9270d15 100644 (file)
@@ -564,7 +564,7 @@ static void mvs_94xx_interrupt_enable(struct mvs_info *mvi)
        u32 tmp;
 
        tmp = mr32(MVS_GBL_CTL);
-       tmp |= (IRQ_SAS_A | IRQ_SAS_B);
+       tmp |= (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
        mw32(MVS_GBL_INT_STAT, tmp);
        writel(tmp, regs + 0x0C);
        writel(tmp, regs + 0x10);
@@ -580,7 +580,7 @@ static void mvs_94xx_interrupt_disable(struct mvs_info *mvi)
 
        tmp = mr32(MVS_GBL_CTL);
 
-       tmp &= ~(IRQ_SAS_A | IRQ_SAS_B);
+       tmp &= ~(MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
        mw32(MVS_GBL_INT_STAT, tmp);
        writel(tmp, regs + 0x0C);
        writel(tmp, regs + 0x10);
@@ -596,7 +596,7 @@ static u32 mvs_94xx_isr_status(struct mvs_info *mvi, int irq)
        if (!(mvi->flags & MVF_FLAG_SOC)) {
                stat = mr32(MVS_GBL_INT_STAT);
 
-               if (!(stat & (IRQ_SAS_A | IRQ_SAS_B)))
+               if (!(stat & (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B)))
                        return 0;
        }
        return stat;
@@ -606,8 +606,8 @@ static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat)
 {
        void __iomem *regs = mvi->regs;
 
-       if (((stat & IRQ_SAS_A) && mvi->id == 0) ||
-                       ((stat & IRQ_SAS_B) && mvi->id == 1)) {
+       if (((stat & MVS_IRQ_SAS_A) && mvi->id == 0) ||
+                       ((stat & MVS_IRQ_SAS_B) && mvi->id == 1)) {
                mw32_f(MVS_INT_STAT, CINT_DONE);
 
                spin_lock(&mvi->lock);
index 487aa6f..14e1974 100644 (file)
@@ -150,35 +150,35 @@ enum chip_register_bits {
 
 enum pci_interrupt_cause {
        /*  MAIN_IRQ_CAUSE (R10200) Bits*/
-       IRQ_COM_IN_I2O_IOP0            = (1 << 0),
-       IRQ_COM_IN_I2O_IOP1            = (1 << 1),
-       IRQ_COM_IN_I2O_IOP2            = (1 << 2),
-       IRQ_COM_IN_I2O_IOP3            = (1 << 3),
-       IRQ_COM_OUT_I2O_HOS0           = (1 << 4),
-       IRQ_COM_OUT_I2O_HOS1           = (1 << 5),
-       IRQ_COM_OUT_I2O_HOS2           = (1 << 6),
-       IRQ_COM_OUT_I2O_HOS3           = (1 << 7),
-       IRQ_PCIF_TO_CPU_DRBL0          = (1 << 8),
-       IRQ_PCIF_TO_CPU_DRBL1          = (1 << 9),
-       IRQ_PCIF_TO_CPU_DRBL2          = (1 << 10),
-       IRQ_PCIF_TO_CPU_DRBL3          = (1 << 11),
-       IRQ_PCIF_DRBL0                 = (1 << 12),
-       IRQ_PCIF_DRBL1                 = (1 << 13),
-       IRQ_PCIF_DRBL2                 = (1 << 14),
-       IRQ_PCIF_DRBL3                 = (1 << 15),
-       IRQ_XOR_A                      = (1 << 16),
-       IRQ_XOR_B                      = (1 << 17),
-       IRQ_SAS_A                      = (1 << 18),
-       IRQ_SAS_B                      = (1 << 19),
-       IRQ_CPU_CNTRL                  = (1 << 20),
-       IRQ_GPIO                       = (1 << 21),
-       IRQ_UART                       = (1 << 22),
-       IRQ_SPI                        = (1 << 23),
-       IRQ_I2C                        = (1 << 24),
-       IRQ_SGPIO                      = (1 << 25),
-       IRQ_COM_ERR                    = (1 << 29),
-       IRQ_I2O_ERR                    = (1 << 30),
-       IRQ_PCIE_ERR                   = (1 << 31),
+       MVS_IRQ_COM_IN_I2O_IOP0        = (1 << 0),
+       MVS_IRQ_COM_IN_I2O_IOP1        = (1 << 1),
+       MVS_IRQ_COM_IN_I2O_IOP2        = (1 << 2),
+       MVS_IRQ_COM_IN_I2O_IOP3        = (1 << 3),
+       MVS_IRQ_COM_OUT_I2O_HOS0       = (1 << 4),
+       MVS_IRQ_COM_OUT_I2O_HOS1       = (1 << 5),
+       MVS_IRQ_COM_OUT_I2O_HOS2       = (1 << 6),
+       MVS_IRQ_COM_OUT_I2O_HOS3       = (1 << 7),
+       MVS_IRQ_PCIF_TO_CPU_DRBL0      = (1 << 8),
+       MVS_IRQ_PCIF_TO_CPU_DRBL1      = (1 << 9),
+       MVS_IRQ_PCIF_TO_CPU_DRBL2      = (1 << 10),
+       MVS_IRQ_PCIF_TO_CPU_DRBL3      = (1 << 11),
+       MVS_IRQ_PCIF_DRBL0             = (1 << 12),
+       MVS_IRQ_PCIF_DRBL1             = (1 << 13),
+       MVS_IRQ_PCIF_DRBL2             = (1 << 14),
+       MVS_IRQ_PCIF_DRBL3             = (1 << 15),
+       MVS_IRQ_XOR_A                  = (1 << 16),
+       MVS_IRQ_XOR_B                  = (1 << 17),
+       MVS_IRQ_SAS_A                  = (1 << 18),
+       MVS_IRQ_SAS_B                  = (1 << 19),
+       MVS_IRQ_CPU_CNTRL              = (1 << 20),
+       MVS_IRQ_GPIO                   = (1 << 21),
+       MVS_IRQ_UART                   = (1 << 22),
+       MVS_IRQ_SPI                    = (1 << 23),
+       MVS_IRQ_I2C                    = (1 << 24),
+       MVS_IRQ_SGPIO                  = (1 << 25),
+       MVS_IRQ_COM_ERR                = (1 << 29),
+       MVS_IRQ_I2O_ERR                = (1 << 30),
+       MVS_IRQ_PCIE_ERR               = (1 << 31),
 };
 
 union reg_phy_cfg {
index f6759dc..c41ff14 100644 (file)
@@ -368,7 +368,7 @@ int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,
         * otherwise we use the default. Also we use the default FIFO
         * thresholds for now.
         */
-       *burst_code = chip_info ? chip_info->dma_burst_size : 16;
+       *burst_code = chip_info ? chip_info->dma_burst_size : 1;
        *threshold = SSCR1_RxTresh(RX_THRESH_DFLT)
                   | SSCR1_TxTresh(TX_THRESH_DFLT);
 
index a98df7e..fe79210 100644 (file)
@@ -118,6 +118,7 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
         */
        orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
 
+       /* Test SPI_CS_CONTROL_SW_MODE bit enabling */
        value = orig | SPI_CS_CONTROL_SW_MODE;
        writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
        value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
@@ -126,10 +127,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
                goto detection_done;
        }
 
-       value &= ~SPI_CS_CONTROL_SW_MODE;
+       orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
+
+       /* Test SPI_CS_CONTROL_SW_MODE bit disabling */
+       value = orig & ~SPI_CS_CONTROL_SW_MODE;
        writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL);
        value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL);
-       if (value != orig) {
+       if (value != (orig & ~SPI_CS_CONTROL_SW_MODE)) {
                offset = 0x800;
                goto detection_done;
        }
index fc1de86..c08da38 100644 (file)
@@ -424,31 +424,6 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
        return 0;
 }
 
-static void spi_qup_set_cs(struct spi_device *spi, bool enable)
-{
-       struct spi_qup *controller = spi_master_get_devdata(spi->master);
-
-       u32 iocontol, mask;
-
-       iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL);
-
-       /* Disable auto CS toggle and use manual */
-       iocontol &= ~SPI_IO_C_MX_CS_MODE;
-       iocontol |= SPI_IO_C_FORCE_CS;
-
-       iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
-       iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select);
-
-       mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
-
-       if (enable)
-               iocontol |= mask;
-       else
-               iocontol &= ~mask;
-
-       writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL);
-}
-
 static int spi_qup_transfer_one(struct spi_master *master,
                              struct spi_device *spi,
                              struct spi_transfer *xfer)
@@ -571,12 +546,16 @@ static int spi_qup_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       /* use num-cs unless not present or out of range */
+       if (of_property_read_u16(dev->of_node, "num-cs",
+                       &master->num_chipselect) ||
+                       (master->num_chipselect > SPI_NUM_CHIPSELECTS))
+               master->num_chipselect = SPI_NUM_CHIPSELECTS;
+
        master->bus_num = pdev->id;
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
-       master->num_chipselect = SPI_NUM_CHIPSELECTS;
        master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
        master->max_speed_hz = max_freq;
-       master->set_cs = spi_qup_set_cs;
        master->transfer_one = spi_qup_transfer_one;
        master->dev.of_node = pdev->dev.of_node;
        master->auto_runtime_pm = true;
@@ -640,16 +619,19 @@ static int spi_qup_probe(struct platform_device *pdev)
        if (ret)
                goto error;
 
-       ret = devm_spi_register_master(dev, master);
-       if (ret)
-               goto error;
-
        pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
        pm_runtime_use_autosuspend(dev);
        pm_runtime_set_active(dev);
        pm_runtime_enable(dev);
+
+       ret = devm_spi_register_master(dev, master);
+       if (ret)
+               goto disable_pm;
+
        return 0;
 
+disable_pm:
+       pm_runtime_disable(&pdev->dev);
 error:
        clk_disable_unprepare(cclk);
        clk_disable_unprepare(iclk);
index 1f56ef6..b83dd73 100644 (file)
@@ -175,9 +175,9 @@ static int sh_sci_spi_remove(struct platform_device *dev)
 {
        struct sh_sci_spi *sp = platform_get_drvdata(dev);
 
-       iounmap(sp->membase);
-       setbits(sp, PIN_INIT, 0);
        spi_bitbang_stop(&sp->bitbang);
+       setbits(sp, PIN_INIT, 0);
+       iounmap(sp->membase);
        spi_master_put(sp->bitbang.master);
        return 0;
 }
index 2c61783..c341ac1 100644 (file)
@@ -97,7 +97,6 @@ void timed_output_dev_unregister(struct timed_output_dev *tdev)
 {
        tdev->enable(tdev, 0);
        device_destroy(timed_output_class, MKDEV(0, tdev->index));
-       dev_set_drvdata(tdev->dev, NULL);
 }
 EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
 
index 5d56428..a2f6957 100644 (file)
@@ -651,6 +651,7 @@ config COMEDI_ADDI_APCI_1516
 
 config COMEDI_ADDI_APCI_1564
        tristate "ADDI-DATA APCI_1564 support"
+       select COMEDI_ADDI_WATCHDOG
        ---help---
          Enable support for ADDI-DATA APCI_1564 cards
 
index b36feb0..fa38be0 100644 (file)
@@ -36,10 +36,11 @@ config IIO_SIMPLE_DUMMY_EVENTS
          Add some dummy events to the simple dummy driver.
 
 config IIO_SIMPLE_DUMMY_BUFFER
-       boolean "Buffered capture support"
-       select IIO_KFIFO_BUF
-       help
-         Add buffered data capture to the simple dummy driver.
+       boolean "Buffered capture support"
+       select IIO_BUFFER
+       select IIO_KFIFO_BUF
+       help
+         Add buffered data capture to the simple dummy driver.
 
 endif # IIO_SIMPLE_DUMMY
 
index dae8d1a..52d7517 100644 (file)
@@ -846,6 +846,14 @@ static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val)
                        LRADC_CTRL1);
        mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
 
+       /* Enable / disable the divider per requirement */
+       if (test_bit(chan, &lradc->is_divided))
+               mxs_lradc_reg_set(lradc, 1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+                       LRADC_CTRL2);
+       else
+               mxs_lradc_reg_clear(lradc,
+                       1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, LRADC_CTRL2);
+
        /* Clean the slot's previous content, then set new one. */
        mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0),
                        LRADC_CTRL4);
@@ -961,15 +969,11 @@ static int mxs_lradc_write_raw(struct iio_dev *iio_dev,
                if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer &&
                    val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) {
                        /* divider by two disabled */
-                       writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
-                              lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR);
                        clear_bit(chan->channel, &lradc->is_divided);
                        ret = 0;
                } else if (val == scale_avail[MXS_LRADC_DIV_ENABLED].integer &&
                           val2 == scale_avail[MXS_LRADC_DIV_ENABLED].nano) {
                        /* divider by two enabled */
-                       writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
-                              lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET);
                        set_bit(chan->channel, &lradc->is_divided);
                        ret = 0;
                }
index 9e0f2a9..ab338e3 100644 (file)
@@ -667,9 +667,13 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
        chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] =
                        chip->tsl2x7x_settings.prox_pulse_count;
        chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] =
-       chip->tsl2x7x_settings.prox_thres_low;
+                       (chip->tsl2x7x_settings.prox_thres_low) & 0xFF;
+       chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHHI] =
+                       (chip->tsl2x7x_settings.prox_thres_low >> 8) & 0xFF;
        chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] =
-                       chip->tsl2x7x_settings.prox_thres_high;
+                       (chip->tsl2x7x_settings.prox_thres_high) & 0xFF;
+       chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHHI] =
+                       (chip->tsl2x7x_settings.prox_thres_high >> 8) & 0xFF;
 
        /* and make sure we're not already on */
        if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
index b567832..4ca61af 100644 (file)
@@ -173,6 +173,13 @@ static int imx_pd_register(struct drm_device *drm,
        if (ret)
                return ret;
 
+       /* set the connector's dpms to OFF so that
+        * drm_helper_connector_dpms() won't return
+        * immediately since the current state is ON
+        * at this point.
+        */
+       imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
+
        drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs);
        drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs,
                         DRM_MODE_ENCODER_NONE);
index 0acacab..46f5abc 100644 (file)
@@ -298,7 +298,7 @@ int rtl8723a_FirmwareDownload(struct rtw_adapter *padapter)
        RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__));
 
        if (IS_8723A_A_CUT(pHalData->VersionID)) {
-               fw_name = "rtlwifi/rtl8723aufw.bin";
+               fw_name = "rtlwifi/rtl8723aufw_A.bin";
                RT_TRACE(_module_hal_init_c_, _drv_info_,
                         ("rtl8723a_FirmwareDownload: R8723FwImageArray_UMC "
                          "for RTL8723A A CUT\n"));
index 4e32003..1fb3438 100644 (file)
@@ -29,7 +29,9 @@ MODULE_AUTHOR("Realtek Semiconductor Corp.");
 MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
 MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>");
 MODULE_VERSION(DRIVERVERSION);
-MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B.bin");
+MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B_NoBT.bin");
 
 /* module param defaults */
 static int rtw_chip_version = 0x00;
index 5663f4d..1f4c794 100644 (file)
@@ -1309,7 +1309,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
        if (cmd->data_direction != DMA_TO_DEVICE) {
                pr_err("Command ITT: 0x%08x received DataOUT for a"
                        " NON-WRITE command.\n", cmd->init_task_tag);
-               return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
+               return iscsit_dump_data_payload(conn, payload_length, 1);
        }
        se_cmd = &cmd->se_cmd;
        iscsit_mod_dataout_timer(cmd);
index 19b842c..ab4915c 100644 (file)
@@ -174,7 +174,6 @@ static int chap_server_compute_md5(
        char *nr_out_ptr,
        unsigned int *nr_out_len)
 {
-       char *endptr;
        unsigned long id;
        unsigned char id_as_uchar;
        unsigned char digest[MD5_SIGNATURE_SIZE];
@@ -320,9 +319,14 @@ static int chap_server_compute_md5(
        }
 
        if (type == HEX)
-               id = simple_strtoul(&identifier[2], &endptr, 0);
+               ret = kstrtoul(&identifier[2], 0, &id);
        else
-               id = simple_strtoul(identifier, &endptr, 0);
+               ret = kstrtoul(identifier, 0, &id);
+
+       if (ret < 0) {
+               pr_err("kstrtoul() failed for CHAP identifier: %d\n", ret);
+               goto out;
+       }
        if (id > 255) {
                pr_err("chap identifier: %lu greater than 255\n", id);
                goto out;
@@ -351,6 +355,10 @@ static int chap_server_compute_md5(
                pr_err("Unable to convert incoming challenge\n");
                goto out;
        }
+       if (challenge_len > 1024) {
+               pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
+               goto out;
+       }
        /*
         * During mutual authentication, the CHAP_C generated by the
         * initiator must not match the original CHAP_C generated by
index fecb695..5e71ac6 100644 (file)
@@ -1216,7 +1216,7 @@ old_sess_out:
 static int __iscsi_target_login_thread(struct iscsi_np *np)
 {
        u8 *buffer, zero_tsih = 0;
-       int ret = 0, rc, stop;
+       int ret = 0, rc;
        struct iscsi_conn *conn = NULL;
        struct iscsi_login *login;
        struct iscsi_portal_group *tpg = NULL;
@@ -1230,6 +1230,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
        if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
                np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
                complete(&np->np_restart_comp);
+       } else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
+               spin_unlock_bh(&np->np_thread_lock);
+               goto exit;
        } else {
                np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
        }
@@ -1422,10 +1425,8 @@ old_sess_out:
        }
 
 out:
-       stop = kthread_should_stop();
-       /* Wait for another socket.. */
-       if (!stop)
-               return 1;
+       return 1;
+
 exit:
        iscsi_stop_login_thread_timer(np);
        spin_lock_bh(&np->np_thread_lock);
@@ -1442,7 +1443,7 @@ int iscsi_target_login_thread(void *arg)
 
        allow_signal(SIGINT);
 
-       while (!kthread_should_stop()) {
+       while (1) {
                ret = __iscsi_target_login_thread(np);
                /*
                 * We break and exit here unless another sock_accept() call
index 53e157c..fd90b28 100644 (file)
@@ -1295,6 +1295,8 @@ int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_deta
        login->login_failed = 1;
        iscsit_collect_login_stats(conn, status_class, status_detail);
 
+       memset(&login->rsp[0], 0, ISCSI_HDR_LEN);
+
        hdr     = (struct iscsi_login_rsp *)&login->rsp[0];
        hdr->opcode             = ISCSI_OP_LOGIN_RSP;
        hdr->status_class       = status_class;
index 6d2f375..8c64b87 100644 (file)
@@ -239,6 +239,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
        return;
 
 out_done:
+       kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
        sc->scsi_done(sc);
        return;
 }
index 11d26fe..98da901 100644 (file)
@@ -616,6 +616,7 @@ void core_dev_unexport(
        dev->export_count--;
        spin_unlock(&hba->device_lock);
 
+       lun->lun_sep = NULL;
        lun->lun_se_dev = NULL;
 }
 
index a8aaf6a..9465623 100644 (file)
@@ -129,7 +129,10 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
 
                tc_device_get_irq(tdev);
 
-               device_register(&tdev->dev);
+               if (device_register(&tdev->dev)) {
+                       put_device(&tdev->dev);
+                       goto out_err;
+               }
                list_add_tail(&tdev->node, &tbus->devices);
 
 out_err:
@@ -148,7 +151,10 @@ static int __init tc_init(void)
 
        INIT_LIST_HEAD(&tc_bus.devices);
        dev_set_name(&tc_bus.dev, "tc");
-       device_register(&tc_bus.dev);
+       if (device_register(&tc_bus.dev)) {
+               put_device(&tc_bus.dev);
+               return 0;
+       }
 
        if (tc_bus.info.slot_size) {
                unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000;
index f95569d..f44f1ba 100644 (file)
@@ -1214,15 +1214,16 @@ static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c)
 {
        struct n_tty_data *ldata = tty->disc_data;
 
-       if (I_IGNPAR(tty))
-               return;
-       if (I_PARMRK(tty)) {
-               put_tty_queue('\377', ldata);
-               put_tty_queue('\0', ldata);
-               put_tty_queue(c, ldata);
-       } else  if (I_INPCK(tty))
-               put_tty_queue('\0', ldata);
-       else
+       if (I_INPCK(tty)) {
+               if (I_IGNPAR(tty))
+                       return;
+               if (I_PARMRK(tty)) {
+                       put_tty_queue('\377', ldata);
+                       put_tty_queue('\0', ldata);
+                       put_tty_queue(c, ldata);
+               } else
+                       put_tty_queue('\0', ldata);
+       } else
                put_tty_queue(c, ldata);
        if (waitqueue_active(&tty->read_wait))
                wake_up_interruptible(&tty->read_wait);
index 27f7ad6..7a91c6d 100644 (file)
@@ -2357,7 +2357,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
        port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= UART_LSR_BI;
 
        /*
index cfef801..4858b8a 100644 (file)
@@ -144,8 +144,11 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
        if (!(device->port.membase || device->port.iobase))
                return 0;
 
-       if (!device->baud)
+       if (!device->baud) {
                device->baud = probe_baud(&device->port);
+               snprintf(device->options, sizeof(device->options), "%u",
+                        device->baud);
+       }
 
        init_port(device);
 
index 501667e..3233766 100644 (file)
@@ -185,6 +185,12 @@ static void altera_uart_set_termios(struct uart_port *port,
        uart_update_timeout(port, termios->c_cflag, baud);
        altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG);
        spin_unlock_irqrestore(&port->lock, flags);
+
+       /*
+        * FIXME: port->read_status_mask and port->ignore_status_mask
+        * need to be initialized based on termios settings for
+        * INPCK, IGNBRK, IGNPAR, PARMRK, BRKINT
+        */
 }
 
 static void altera_uart_rx_chars(struct altera_uart *pp)
index 01c9e72..971af1e 100644 (file)
@@ -420,7 +420,7 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
        uap->port.read_status_mask = UART01x_RSR_OE;
        if (termios->c_iflag & INPCK)
                uap->port.read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                uap->port.read_status_mask |= UART01x_RSR_BE;
 
        /*
index 908a6e3..0e26dcb 100644 (file)
@@ -1744,7 +1744,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
        port->read_status_mask = UART011_DR_OE | 255;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= UART011_DR_FE | UART011_DR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= UART011_DR_BE;
 
        /*
index 3fceae0..c4f7503 100644 (file)
@@ -1932,7 +1932,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
        port->read_status_mask = ATMEL_US_OVRE;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= (ATMEL_US_FRAME | ATMEL_US_PARE);
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= ATMEL_US_RXBRK;
 
        if (atmel_use_pdc_rx(port))
index a47421e..2315190 100644 (file)
@@ -567,7 +567,7 @@ static void bcm_uart_set_termios(struct uart_port *port,
                port->read_status_mask |= UART_FIFO_FRAMEERR_MASK;
                port->read_status_mask |= UART_FIFO_PARERR_MASK;
        }
-       if (new->c_iflag & (BRKINT))
+       if (new->c_iflag & (IGNBRK | BRKINT))
                port->read_status_mask |= UART_FIFO_BRKDET_MASK;
 
        port->ignore_status_mask = 0;
index 869ceba..ac86a20 100644 (file)
@@ -833,7 +833,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
        port->read_status_mask = OE;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= (FE | PE);
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= BI;
 
        /*
index 2f2b2e5..cdbbc78 100644 (file)
@@ -625,7 +625,7 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
        dport->port.read_status_mask = DZ_OERR;
        if (termios->c_iflag & INPCK)
                dport->port.read_status_mask |= DZ_FERR | DZ_PERR;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                dport->port.read_status_mask |= DZ_BREAK;
 
        /* characters to ignore */
index 5131b5e..a514ee6 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/serial.h>
 
 static struct console early_con = {
-       .name =         "earlycon",
+       .name =         "uart", /* 8250 console switch requires this name */
        .flags =        CON_PRINTBUFFER | CON_BOOT,
        .index =        -1,
 };
index b373f64..3b0ee9a 100644 (file)
@@ -407,7 +407,7 @@ static void efm32_uart_set_termios(struct uart_port *port,
        if (new->c_iflag & INPCK)
                port->read_status_mask |=
                        UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR;
-       if (new->c_iflag & (BRKINT | PARMRK))
+       if (new->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= SW_UARTn_RXDATAX_BERR;
 
        port->ignore_status_mask = 0;
index c5eb897..49385c8 100644 (file)
@@ -902,7 +902,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
        sport->port.read_status_mask = 0;
        if (termios->c_iflag & INPCK)
                sport->port.read_status_mask |= (UARTSR1_FE | UARTSR1_PE);
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                sport->port.read_status_mask |= UARTSR1_FE;
 
        /* characters to ignore */
index 1d94205..1efd4c3 100644 (file)
@@ -850,7 +850,7 @@ ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
        up->port.read_status_mask = Rx_OVR;
        if (iflag & INPCK)
                up->port.read_status_mask |= CRC_ERR | PAR_ERR;
-       if (iflag & (BRKINT | PARMRK))
+       if (iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= BRK_ABRT;
 
        up->port.ignore_status_mask = 0;
index 9cd9b4e..68f2c53 100644 (file)
@@ -737,7 +737,7 @@ static void m32r_sio_set_termios(struct uart_port *port,
        up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
        if (termios->c_iflag & INPCK)
                up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= UART_LSR_BI;
 
        /*
index 2a99d0c..ba285cd 100644 (file)
@@ -835,7 +835,7 @@ static void max310x_set_termios(struct uart_port *port,
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= MAX310X_LSR_RXPAR_BIT |
                                          MAX310X_LSR_FRERR_BIT;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= MAX310X_LSR_RXBRK_BIT;
 
        /* Set status ignore mask */
index 0edfaf8..a6f0857 100644 (file)
@@ -248,6 +248,12 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
                mr1 |= MCFUART_MR1_PARITYNONE;
        }
 
+       /*
+        * FIXME: port->read_status_mask and port->ignore_status_mask
+        * need to be initialized based on termios settings for
+        * INPCK, IGNBRK, IGNPAR, PARMRK, BRKINT
+        */
+
        if (termios->c_cflag & CSTOPB)
                mr2 |= MCFUART_MR2_STOP2;
        else
index 52c930f..445799d 100644 (file)
@@ -977,7 +977,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
        if (termios->c_iflag & INPCK)
                up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= UART_LSR_BI;
 
        /* Characters to ignore */
index e30a3ca..759c6a6 100644 (file)
@@ -1458,7 +1458,7 @@ static void mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
                pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_PE
                        | SDMA_DESC_CMDSTAT_FR;
 
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_BR;
 
        /* Characters/events to ignore */
index 778e376..72000a6 100644 (file)
@@ -582,7 +582,7 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
        port->read_status_mask = 0;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= UART_SR_PAR_FRAME_ERR;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= UART_SR_RX_BREAK;
 
        uart_update_timeout(port, termios->c_cflag, baud);
@@ -991,7 +991,7 @@ static const struct of_device_id msm_uartdm_table[] = {
        { }
 };
 
-static int __init msm_serial_probe(struct platform_device *pdev)
+static int msm_serial_probe(struct platform_device *pdev)
 {
        struct msm_port *msm_port;
        struct resource *resource;
index 4b5b3c2..86de447 100644 (file)
@@ -604,7 +604,7 @@ static void mxs_auart_settermios(struct uart_port *u,
 
        if (termios->c_iflag & INPCK)
                u->read_status_mask |= AUART_STAT_PERR;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                u->read_status_mask |= AUART_STAT_BERR;
 
        /*
index 0a4dd70..7a67456 100644 (file)
@@ -419,7 +419,7 @@ netx_set_termios(struct uart_port *port, struct ktermios *termios,
        }
 
        port->read_status_mask = 0;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= SR_BE;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= SR_PE | SR_FE;
index e9d420f..8193635 100644 (file)
@@ -1092,7 +1092,7 @@ static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag,
        uap->port.read_status_mask = Rx_OVR;
        if (iflag & INPCK)
                uap->port.read_status_mask |= CRC_ERR | PAR_ERR;
-       if (iflag & (BRKINT | PARMRK))
+       if (iflag & (IGNBRK | BRKINT | PARMRK))
                uap->port.read_status_mask |= BRK_ABRT;
 
        uap->port.ignore_status_mask = 0;
index de6c05c..2ba24a4 100644 (file)
@@ -477,7 +477,7 @@ pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios,
                sport->port.read_status_mask |=
                        FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
                        FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR);
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                sport->port.read_status_mask |=
                        ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK);
 
index 9e7ee39..c638c53 100644 (file)
@@ -492,7 +492,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
        up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
        if (termios->c_iflag & INPCK)
                up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= UART_LSR_BI;
 
        /*
index 3293377..c1d3ebd 100644 (file)
@@ -66,7 +66,7 @@ static void dbg(const char *fmt, ...)
        char buff[256];
 
        va_start(va, fmt);
-       vscnprintf(buff, sizeof(buf), fmt, va);
+       vscnprintf(buff, sizeof(buff), fmt, va);
        va_end(va);
 
        printascii(buff);
index a7cdec2..771f361 100644 (file)
@@ -596,7 +596,7 @@ static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios,
        if (termios->c_iflag & INPCK)
                uport->read_status_mask |= M_DUART_FRM_ERR |
                                           M_DUART_PARITY_ERR;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                uport->read_status_mask |= M_DUART_RCVD_BRK;
 
        uport->ignore_status_mask = 0;
index 5443b46..e84b6a3 100644 (file)
@@ -665,7 +665,7 @@ static void sccnxp_set_termios(struct uart_port *port,
        port->read_status_mask = SR_OVR;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= SR_PE | SR_FE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= SR_BRK;
 
        /* Set status ignore mask */
index e1caa99..5c79bda 100644 (file)
@@ -437,7 +437,7 @@ static void ks8695uart_set_termios(struct uart_port *port, struct ktermios *term
        port->read_status_mask = URLS_URROE;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= (URLS_URFE | URLS_URPE);
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= URLS_URBI;
 
        /*
index 60f49b9..ea85460 100644 (file)
@@ -697,7 +697,7 @@ serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios,
                TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS;
        if (termios->c_iflag & INPCK)
                up->port.read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= TXX9_SIDISR_UBRK;
 
        /*
index 1f2be48..9b4d71c 100644 (file)
@@ -896,7 +896,7 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
                if (termios->c_iflag & INPCK)
                        port->read_status_mask |= uint_en->sirfsoc_frm_err_en;
        }
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                        port->read_status_mask |= uint_en->sirfsoc_rxd_brk_en;
        if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) {
                if (termios->c_iflag & IGNPAR)
index c7f61ac..f48b1cc 100644 (file)
@@ -547,7 +547,7 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
        ascport->port.read_status_mask = ASC_RXBUF_DUMMY_OE;
        if (termios->c_iflag & INPCK)
                ascport->port.read_status_mask |= ASC_RXBUF_FE | ASC_RXBUF_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                ascport->port.read_status_mask |= ASC_RXBUF_DUMMY_BE;
 
        /*
index 5faa8e9..80a58ec 100644 (file)
@@ -719,7 +719,7 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
        if (iflag & INPCK)
                up->port.read_status_mask |= (SAB82532_ISR0_PERR |
                                              SAB82532_ISR0_FERR);
-       if (iflag & (BRKINT | PARMRK))
+       if (iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= (SAB82532_ISR1_BRK << 8);
 
        /*
index 9a0f24f..5326ae1 100644 (file)
@@ -834,7 +834,7 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
        up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
        if (iflag & INPCK)
                up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (iflag & (BRKINT | PARMRK))
+       if (iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= UART_LSR_BI;
 
        /*
index a2c40ed..a85db8b 100644 (file)
@@ -915,7 +915,7 @@ sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
        up->port.read_status_mask = Rx_OVR;
        if (iflag & INPCK)
                up->port.read_status_mask |= CRC_ERR | PAR_ERR;
-       if (iflag & (BRKINT | PARMRK))
+       if (iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= BRK_ABRT;
 
        up->port.ignore_status_mask = 0;
index d569ca5..1c52074 100644 (file)
@@ -936,7 +936,7 @@ static void qe_uart_set_termios(struct uart_port *port,
        port->read_status_mask = BD_SC_EMPTY | BD_SC_OV;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= BD_SC_FR | BD_SC_PR;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= BD_SC_BR;
 
        /*
index a63c14b..db0c8a4 100644 (file)
@@ -559,7 +559,7 @@ static void siu_set_termios(struct uart_port *port, struct ktermios *new,
        port->read_status_mask = UART_LSR_THRE | UART_LSR_OE | UART_LSR_DR;
        if (c_iflag & INPCK)
                port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (c_iflag & (BRKINT | PARMRK))
+       if (c_iflag & (IGNBRK | BRKINT | PARMRK))
                port->read_status_mask |= UART_LSR_BI;
 
        port->ignore_status_mask = 0;
index 6a16987..2b65bb7 100644 (file)
@@ -923,7 +923,7 @@ static void zs_set_termios(struct uart_port *uport, struct ktermios *termios,
        uport->read_status_mask = Rx_OVR;
        if (termios->c_iflag & INPCK)
                uport->read_status_mask |= FRM_ERR | PAR_ERR;
-       if (termios->c_iflag & (BRKINT | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                uport->read_status_mask |= Rx_BRK;
 
        uport->ignore_status_mask = 0;
index 5e0f6ff..b33b00b 100644 (file)
@@ -3226,8 +3226,7 @@ int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt
        for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
                con_back = &registered_con_driver[i];
 
-               if (con_back->con &&
-                   !(con_back->flag & CON_DRIVER_FLAG_MODULE)) {
+               if (con_back->con && con_back->con != csw) {
                        defcsw = con_back->con;
                        retval = 0;
                        break;
@@ -3332,6 +3331,7 @@ static int vt_unbind(struct con_driver *con)
 {
        const struct consw *csw = NULL;
        int i, more = 1, first = -1, last = -1, deflt = 0;
+       int ret;
 
        if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
            con_is_graphics(con->con, con->first, con->last))
@@ -3357,8 +3357,10 @@ static int vt_unbind(struct con_driver *con)
 
                if (first != -1) {
                        console_lock();
-                       do_unbind_con_driver(csw, first, last, deflt);
+                       ret = do_unbind_con_driver(csw, first, last, deflt);
                        console_unlock();
+                       if (ret != 0)
+                               return ret;
                }
 
                first = -1;
@@ -3645,17 +3647,20 @@ err:
  */
 int do_unregister_con_driver(const struct consw *csw)
 {
-       int i, retval = -ENODEV;
+       int i;
 
        /* cannot unregister a bound driver */
        if (con_is_bound(csw))
-               goto err;
+               return -EBUSY;
+
+       if (csw == conswitchp)
+               return -EINVAL;
 
        for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
                struct con_driver *con_driver = &registered_con_driver[i];
 
                if (con_driver->con == csw &&
-                   con_driver->flag & CON_DRIVER_FLAG_MODULE) {
+                   con_driver->flag & CON_DRIVER_FLAG_INIT) {
                        vtconsole_deinit_device(con_driver);
                        device_destroy(vtconsole_class,
                                       MKDEV(0, con_driver->node));
@@ -3666,12 +3671,11 @@ int do_unregister_con_driver(const struct consw *csw)
                        con_driver->flag = 0;
                        con_driver->first = 0;
                        con_driver->last = 0;
-                       retval = 0;
-                       break;
+                       return 0;
                }
        }
-err:
-       return retval;
+
+       return -ENODEV;
 }
 EXPORT_SYMBOL_GPL(do_unregister_con_driver);
 
index e371f5a..a673e5b 100644 (file)
@@ -655,7 +655,7 @@ static int uio_mmap_physical(struct vm_area_struct *vma)
 
        if (mem->addr & ~PAGE_MASK)
                return -ENODEV;
-       if (vma->vm_end - vma->vm_start > PAGE_ALIGN(mem->size))
+       if (vma->vm_end - vma->vm_start > mem->size)
                return -EINVAL;
 
        vma->vm_ops = &uio_physical_vm_ops;
index 879b66e..21b99b4 100644 (file)
@@ -1526,18 +1526,6 @@ static int hub_configure(struct usb_hub *hub,
                dev_dbg(hub_dev, "%umA bus power budget for each child\n",
                                hub->mA_per_port);
 
-       /* Update the HCD's internal representation of this hub before khubd
-        * starts getting port status changes for devices under the hub.
-        */
-       if (hcd->driver->update_hub_device) {
-               ret = hcd->driver->update_hub_device(hcd, hdev,
-                               &hub->tt, GFP_KERNEL);
-               if (ret < 0) {
-                       message = "can't update HCD hub info";
-                       goto fail;
-               }
-       }
-
        ret = hub_hub_status(hub, &hubstatus, &hubchange);
        if (ret < 0) {
                message = "can't get hub status";
@@ -1589,10 +1577,28 @@ static int hub_configure(struct usb_hub *hub,
                }
        }
        hdev->maxchild = i;
+       for (i = 0; i < hdev->maxchild; i++) {
+               struct usb_port *port_dev = hub->ports[i];
+
+               pm_runtime_put(&port_dev->dev);
+       }
+
        mutex_unlock(&usb_port_peer_mutex);
        if (ret < 0)
                goto fail;
 
+       /* Update the HCD's internal representation of this hub before khubd
+        * starts getting port status changes for devices under the hub.
+        */
+       if (hcd->driver->update_hub_device) {
+               ret = hcd->driver->update_hub_device(hcd, hdev,
+                               &hub->tt, GFP_KERNEL);
+               if (ret < 0) {
+                       message = "can't update HCD hub info";
+                       goto fail;
+               }
+       }
+
        usb_hub_adjust_deviceremovable(hdev, hub->descriptor);
 
        hub_activate(hub, HUB_INIT);
@@ -3458,7 +3464,8 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
                struct usb_device *udev = port_dev->child;
 
                if (udev && udev->can_submit) {
-                       dev_warn(&port_dev->dev, "not suspended yet\n");
+                       dev_warn(&port_dev->dev, "device %s not suspended yet\n",
+                                       dev_name(&udev->dev));
                        if (PMSG_IS_AUTO(msg))
                                return -EBUSY;
                }
index 0a7cdc0..326308e 100644 (file)
@@ -84,6 +84,7 @@ struct usb_hub {
  * @dev: generic device interface
  * @port_owner: port's owner
  * @peer: related usb2 and usb3 ports (share the same connector)
+ * @req: default pm qos request for hubs without port power control
  * @connect_type: port's connect type
  * @location: opaque representation of platform connector location
  * @status_lock: synchronize port_event() vs usb_port_{suspend|resume}
@@ -95,6 +96,7 @@ struct usb_port {
        struct device dev;
        struct usb_dev_state *port_owner;
        struct usb_port *peer;
+       struct dev_pm_qos_request *req;
        enum usb_port_connect_type connect_type;
        usb_port_location_t location;
        struct mutex status_lock;
index 62036fa..fe1b6d0 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "hub.h"
 
+static int usb_port_block_power_off;
+
 static const struct attribute_group *port_dev_group[];
 
 static ssize_t connect_type_show(struct device *dev,
@@ -66,6 +68,7 @@ static void usb_port_device_release(struct device *dev)
 {
        struct usb_port *port_dev = to_usb_port(dev);
 
+       kfree(port_dev->req);
        kfree(port_dev);
 }
 
@@ -142,6 +145,9 @@ static int usb_port_runtime_suspend(struct device *dev)
                        == PM_QOS_FLAGS_ALL)
                return -EAGAIN;
 
+       if (usb_port_block_power_off)
+               return -EBUSY;
+
        usb_autopm_get_interface(intf);
        retval = usb_hub_set_port_power(hdev, hub, port1, false);
        usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
@@ -190,11 +196,19 @@ static int link_peers(struct usb_port *left, struct usb_port *right)
        if (left->peer || right->peer) {
                struct usb_port *lpeer = left->peer;
                struct usb_port *rpeer = right->peer;
-
-               WARN(1, "failed to peer %s and %s (%s -> %p) (%s -> %p)\n",
-                       dev_name(&left->dev), dev_name(&right->dev),
-                       dev_name(&left->dev), lpeer,
-                       dev_name(&right->dev), rpeer);
+               char *method;
+
+               if (left->location && left->location == right->location)
+                       method = "location";
+               else
+                       method = "default";
+
+               pr_warn("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
+                       dev_name(&left->dev), dev_name(&right->dev), method,
+                       dev_name(&left->dev),
+                       lpeer ? dev_name(&lpeer->dev) : "none",
+                       dev_name(&right->dev),
+                       rpeer ? dev_name(&rpeer->dev) : "none");
                return -EBUSY;
        }
 
@@ -251,6 +265,7 @@ static void link_peers_report(struct usb_port *left, struct usb_port *right)
                dev_warn(&left->dev, "failed to peer to %s (%d)\n",
                                dev_name(&right->dev), rc);
                pr_warn_once("usb: port power management may be unreliable\n");
+               usb_port_block_power_off = 1;
        }
 }
 
@@ -386,9 +401,13 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
        int retval;
 
        port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
-       if (!port_dev) {
-               retval = -ENOMEM;
-               goto exit;
+       if (!port_dev)
+               return -ENOMEM;
+
+       port_dev->req = kzalloc(sizeof(*(port_dev->req)), GFP_KERNEL);
+       if (!port_dev->req) {
+               kfree(port_dev);
+               return -ENOMEM;
        }
 
        hub->ports[port1 - 1] = port_dev;
@@ -404,31 +423,53 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
                        port1);
        mutex_init(&port_dev->status_lock);
        retval = device_register(&port_dev->dev);
-       if (retval)
-               goto error_register;
+       if (retval) {
+               put_device(&port_dev->dev);
+               return retval;
+       }
+
+       /* Set default policy of port-poweroff disabled. */
+       retval = dev_pm_qos_add_request(&port_dev->dev, port_dev->req,
+                       DEV_PM_QOS_FLAGS, PM_QOS_FLAG_NO_POWER_OFF);
+       if (retval < 0) {
+               device_unregister(&port_dev->dev);
+               return retval;
+       }
 
        find_and_link_peer(hub, port1);
 
+       /*
+        * Enable runtime pm and hold a refernce that hub_configure()
+        * will drop once the PM_QOS_NO_POWER_OFF flag state has been set
+        * and the hub has been fully registered (hdev->maxchild set).
+        */
        pm_runtime_set_active(&port_dev->dev);
+       pm_runtime_get_noresume(&port_dev->dev);
+       pm_runtime_enable(&port_dev->dev);
+       device_enable_async_suspend(&port_dev->dev);
 
        /*
-        * Do not enable port runtime pm if the hub does not support
-        * power switching.  Also, userspace must have final say of
-        * whether a port is permitted to power-off.  Do not enable
-        * runtime pm if we fail to expose pm_qos_no_power_off.
+        * Keep hidden the ability to enable port-poweroff if the hub
+        * does not support power switching.
         */
-       if (hub_is_port_power_switchable(hub)
-                       && dev_pm_qos_expose_flags(&port_dev->dev,
-                       PM_QOS_FLAG_NO_POWER_OFF) == 0)
-               pm_runtime_enable(&port_dev->dev);
+       if (!hub_is_port_power_switchable(hub))
+               return 0;
 
-       device_enable_async_suspend(&port_dev->dev);
-       return 0;
+       /* Attempt to let userspace take over the policy. */
+       retval = dev_pm_qos_expose_flags(&port_dev->dev,
+                       PM_QOS_FLAG_NO_POWER_OFF);
+       if (retval < 0) {
+               dev_warn(&port_dev->dev, "failed to expose pm_qos_no_poweroff\n");
+               return 0;
+       }
 
-error_register:
-       put_device(&port_dev->dev);
-exit:
-       return retval;
+       /* Userspace owns the policy, drop the kernel 'no_poweroff' request. */
+       retval = dev_pm_qos_remove_request(port_dev->req);
+       if (retval >= 0) {
+               kfree(port_dev->req);
+               port_dev->req = NULL;
+       }
+       return 0;
 }
 
 void usb_hub_remove_port_device(struct usb_hub *hub, int port1)
index 4a6d3dd..2f3aceb 100644 (file)
@@ -656,6 +656,14 @@ static const struct dmi_system_id ehci_dmi_nohandoff_table[] = {
                        DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
                },
        },
+       {
+               /* HASEE E200 */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "HASEE"),
+                       DMI_MATCH(DMI_BOARD_NAME, "E210"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "6.00"),
+               },
+       },
        { }
 };
 
@@ -665,9 +673,14 @@ static void ehci_bios_handoff(struct pci_dev *pdev,
 {
        int try_handoff = 1, tried_handoff = 0;
 
-       /* The Pegatron Lucid tablet sporadically waits for 98 seconds trying
-        * the handoff on its unused controller.  Skip it. */
-       if (pdev->vendor == 0x8086 && pdev->device == 0x283a) {
+       /*
+        * The Pegatron Lucid tablet sporadically waits for 98 seconds trying
+        * the handoff on its unused controller.  Skip it.
+        *
+        * The HASEE E200 hangs when the semaphore is set (bugzilla #77021).
+        */
+       if (pdev->vendor == 0x8086 && (pdev->device == 0x283a ||
+                       pdev->device == 0x27cc)) {
                if (dmi_check_system(ehci_dmi_nohandoff_table))
                        try_handoff = 0;
        }
index 6231ce6..2b998c6 100644 (file)
@@ -287,7 +287,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
                if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) {
                        struct xhci_command *command;
                        command = xhci_alloc_command(xhci, false, false,
-                                                    GFP_NOIO);
+                                                    GFP_NOWAIT);
                        if (!command) {
                                spin_unlock_irqrestore(&xhci->lock, flags);
                                xhci_free_command(xhci, cmd);
index 51a6da2..829f446 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/moduleparam.h>
 #include <linux/scatterlist.h>
 #include <linux/mutex.h>
-
+#include <linux/timer.h>
 #include <linux/usb.h>
 
 #define SIMPLE_IO_TIMEOUT      10000   /* in milliseconds */
@@ -484,6 +484,14 @@ alloc_sglist(int nents, int max, int vary)
        return sg;
 }
 
+static void sg_timeout(unsigned long _req)
+{
+       struct usb_sg_request   *req = (struct usb_sg_request *) _req;
+
+       req->status = -ETIMEDOUT;
+       usb_sg_cancel(req);
+}
+
 static int perform_sglist(
        struct usbtest_dev      *tdev,
        unsigned                iterations,
@@ -495,6 +503,9 @@ static int perform_sglist(
 {
        struct usb_device       *udev = testdev_to_usbdev(tdev);
        int                     retval = 0;
+       struct timer_list       sg_timer;
+
+       setup_timer_on_stack(&sg_timer, sg_timeout, (unsigned long) req);
 
        while (retval == 0 && iterations-- > 0) {
                retval = usb_sg_init(req, udev, pipe,
@@ -505,7 +516,10 @@ static int perform_sglist(
 
                if (retval)
                        break;
+               mod_timer(&sg_timer, jiffies +
+                               msecs_to_jiffies(SIMPLE_IO_TIMEOUT));
                usb_sg_wait(req);
+               del_timer_sync(&sg_timer);
                retval = req->status;
 
                /* FIXME check resulting data pattern */
index 971a760..8dae2f7 100644 (file)
@@ -700,14 +700,6 @@ static void handle_rx_net(struct vhost_work *work)
        handle_rx(net);
 }
 
-static void vhost_net_free(void *addr)
-{
-       if (is_vmalloc_addr(addr))
-               vfree(addr);
-       else
-               kfree(addr);
-}
-
 static int vhost_net_open(struct inode *inode, struct file *f)
 {
        struct vhost_net *n;
@@ -723,7 +715,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
        }
        vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL);
        if (!vqs) {
-               vhost_net_free(n);
+               kvfree(n);
                return -ENOMEM;
        }
 
@@ -840,7 +832,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
         * since jobs can re-queue themselves. */
        vhost_net_flush(n);
        kfree(n->dev.vqs);
-       vhost_net_free(n);
+       kvfree(n);
        return 0;
 }
 
index 4f4ffa4..69906ca 100644 (file)
@@ -1503,14 +1503,6 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
        return 0;
 }
 
-static void vhost_scsi_free(struct vhost_scsi *vs)
-{
-       if (is_vmalloc_addr(vs))
-               vfree(vs);
-       else
-               kfree(vs);
-}
-
 static int vhost_scsi_open(struct inode *inode, struct file *f)
 {
        struct vhost_scsi *vs;
@@ -1550,7 +1542,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
        return 0;
 
 err_vqs:
-       vhost_scsi_free(vs);
+       kvfree(vs);
 err_vs:
        return r;
 }
@@ -1569,7 +1561,7 @@ static int vhost_scsi_release(struct inode *inode, struct file *f)
        /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */
        vhost_scsi_flush(vs);
        kfree(vs->dev.vqs);
-       vhost_scsi_free(vs);
+       kvfree(vs);
        return 0;
 }
 
index 5d44905..c3c1833 100644 (file)
@@ -178,17 +178,6 @@ config BACKLIGHT_ATMEL_LCDC
          If in doubt, it's safe to enable this option; it doesn't kick
          in unless the board's description says it's wired that way.
 
-config BACKLIGHT_ATMEL_PWM
-       tristate "Atmel PWM backlight control"
-       depends on ATMEL_PWM
-       help
-         Say Y here if you want to use the PWM peripheral in Atmel AT91 and
-         AVR32 devices. This driver will need additional platform data to know
-         which PWM instance to use and how to configure it.
-
-         To compile this driver as a module, choose M here: the module will be
-         called atmel-pwm-bl.
-
 config BACKLIGHT_EP93XX
        tristate "Cirrus EP93xx Backlight Driver"
        depends on FB_EP93XX
index bb82002..351451d 100644 (file)
@@ -25,7 +25,6 @@ obj-$(CONFIG_BACKLIGHT_ADP8860)               += adp8860_bl.o
 obj-$(CONFIG_BACKLIGHT_ADP8870)                += adp8870_bl.o
 obj-$(CONFIG_BACKLIGHT_APPLE)          += apple_bl.o
 obj-$(CONFIG_BACKLIGHT_AS3711)         += as3711_bl.o
-obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)      += atmel-pwm-bl.o
 obj-$(CONFIG_BACKLIGHT_BD6107)         += bd6107.o
 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH)  += cr_bllcd.o
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE)   += backlight.o
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
deleted file mode 100644 (file)
index 261b1a4..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2008 Atmel Corporation
- *
- * Backlight driver using Atmel PWM peripheral.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/backlight.h>
-#include <linux/atmel_pwm.h>
-#include <linux/atmel-pwm-bl.h>
-#include <linux/slab.h>
-
-struct atmel_pwm_bl {
-       const struct atmel_pwm_bl_platform_data *pdata;
-       struct backlight_device                 *bldev;
-       struct platform_device                  *pdev;
-       struct pwm_channel                      pwmc;
-       int                                     gpio_on;
-};
-
-static void atmel_pwm_bl_set_gpio_on(struct atmel_pwm_bl *pwmbl, int on)
-{
-       if (!gpio_is_valid(pwmbl->gpio_on))
-               return;
-
-       gpio_set_value(pwmbl->gpio_on, on ^ pwmbl->pdata->on_active_low);
-}
-
-static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
-{
-       struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
-       int intensity = bd->props.brightness;
-       int pwm_duty;
-
-       if (bd->props.power != FB_BLANK_UNBLANK)
-               intensity = 0;
-       if (bd->props.fb_blank != FB_BLANK_UNBLANK)
-               intensity = 0;
-
-       if (pwmbl->pdata->pwm_active_low)
-               pwm_duty = pwmbl->pdata->pwm_duty_min + intensity;
-       else
-               pwm_duty = pwmbl->pdata->pwm_duty_max - intensity;
-
-       if (pwm_duty > pwmbl->pdata->pwm_duty_max)
-               pwm_duty = pwmbl->pdata->pwm_duty_max;
-       if (pwm_duty < pwmbl->pdata->pwm_duty_min)
-               pwm_duty = pwmbl->pdata->pwm_duty_min;
-
-       if (!intensity) {
-               atmel_pwm_bl_set_gpio_on(pwmbl, 0);
-               pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
-               pwm_channel_disable(&pwmbl->pwmc);
-       } else {
-               pwm_channel_enable(&pwmbl->pwmc);
-               pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
-               atmel_pwm_bl_set_gpio_on(pwmbl, 1);
-       }
-
-       return 0;
-}
-
-static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
-{
-       struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
-       u32 cdty;
-       u32 intensity;
-
-       cdty = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
-       if (pwmbl->pdata->pwm_active_low)
-               intensity = cdty - pwmbl->pdata->pwm_duty_min;
-       else
-               intensity = pwmbl->pdata->pwm_duty_max - cdty;
-
-       return intensity & 0xffff;
-}
-
-static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
-{
-       unsigned long pwm_rate = pwmbl->pwmc.mck;
-       unsigned long prescale = DIV_ROUND_UP(pwm_rate,
-                       (pwmbl->pdata->pwm_frequency *
-                        pwmbl->pdata->pwm_compare_max)) - 1;
-
-       /*
-        * Prescale must be power of two and maximum 0xf in size because of
-        * hardware limit. PWM speed will be:
-        *      PWM module clock speed / (2 ^ prescale).
-        */
-       prescale = fls(prescale);
-       if (prescale > 0xf)
-               prescale = 0xf;
-
-       pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale);
-       pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY,
-                       pwmbl->pdata->pwm_duty_min +
-                       pwmbl->bldev->props.brightness);
-       pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
-                       pwmbl->pdata->pwm_compare_max);
-
-       dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver (%lu Hz)\n",
-               pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max /
-               (1 << prescale));
-
-       return pwm_channel_enable(&pwmbl->pwmc);
-}
-
-static const struct backlight_ops atmel_pwm_bl_ops = {
-       .get_brightness = atmel_pwm_bl_get_intensity,
-       .update_status  = atmel_pwm_bl_set_intensity,
-};
-
-static int atmel_pwm_bl_probe(struct platform_device *pdev)
-{
-       struct backlight_properties props;
-       const struct atmel_pwm_bl_platform_data *pdata;
-       struct backlight_device *bldev;
-       struct atmel_pwm_bl *pwmbl;
-       unsigned long flags;
-       int retval;
-
-       pdata = dev_get_platdata(&pdev->dev);
-       if (!pdata)
-               return -ENODEV;
-
-       if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
-                       pdata->pwm_duty_min > pdata->pwm_duty_max ||
-                       pdata->pwm_frequency == 0)
-               return -EINVAL;
-
-       pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl),
-                               GFP_KERNEL);
-       if (!pwmbl)
-               return -ENOMEM;
-
-       pwmbl->pdev = pdev;
-       pwmbl->pdata = pdata;
-       pwmbl->gpio_on = pdata->gpio_on;
-
-       retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
-       if (retval)
-               return retval;
-
-       if (gpio_is_valid(pwmbl->gpio_on)) {
-               /* Turn display off by default. */
-               if (pdata->on_active_low)
-                       flags = GPIOF_OUT_INIT_HIGH;
-               else
-                       flags = GPIOF_OUT_INIT_LOW;
-
-               retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on,
-                                               flags, "gpio_atmel_pwm_bl");
-               if (retval)
-                       goto err_free_pwm;
-       }
-
-       memset(&props, 0, sizeof(struct backlight_properties));
-       props.type = BACKLIGHT_RAW;
-       props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
-       bldev = devm_backlight_device_register(&pdev->dev, "atmel-pwm-bl",
-                                       &pdev->dev, pwmbl, &atmel_pwm_bl_ops,
-                                       &props);
-       if (IS_ERR(bldev)) {
-               retval = PTR_ERR(bldev);
-               goto err_free_pwm;
-       }
-
-       pwmbl->bldev = bldev;
-
-       platform_set_drvdata(pdev, pwmbl);
-
-       /* Power up the backlight by default at middle intesity. */
-       bldev->props.power = FB_BLANK_UNBLANK;
-       bldev->props.brightness = bldev->props.max_brightness / 2;
-
-       retval = atmel_pwm_bl_init_pwm(pwmbl);
-       if (retval)
-               goto err_free_pwm;
-
-       atmel_pwm_bl_set_intensity(bldev);
-
-       return 0;
-
-err_free_pwm:
-       pwm_channel_free(&pwmbl->pwmc);
-
-       return retval;
-}
-
-static int atmel_pwm_bl_remove(struct platform_device *pdev)
-{
-       struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
-
-       atmel_pwm_bl_set_gpio_on(pwmbl, 0);
-       pwm_channel_disable(&pwmbl->pwmc);
-       pwm_channel_free(&pwmbl->pwmc);
-
-       return 0;
-}
-
-static struct platform_driver atmel_pwm_bl_driver = {
-       .driver = {
-               .name = "atmel-pwm-bl",
-       },
-       /* REVISIT add suspend() and resume() */
-       .probe = atmel_pwm_bl_probe,
-       .remove = atmel_pwm_bl_remove,
-};
-
-module_platform_driver(atmel_pwm_bl_driver);
-
-MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
-MODULE_DESCRIPTION("Atmel PWM backlight driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:atmel-pwm-bl");
index b63860f..40bec8d 100644 (file)
@@ -77,3 +77,4 @@ const struct consw dummy_con = {
     .con_set_palette = DUMMY,
     .con_scrolldelta = DUMMY,
 };
+EXPORT_SYMBOL_GPL(dummy_con);
index f267284..6e6aa70 100644 (file)
@@ -1441,5 +1441,6 @@ const struct consw vga_con = {
        .con_build_attr = vgacon_build_attr,
        .con_invert_region = vgacon_invert_region,
 };
+EXPORT_SYMBOL(vga_con);
 
 MODULE_LICENSE("GPL");
index 7d44d66..43a0a52 100644 (file)
@@ -91,15 +91,6 @@ extern boot_infos_t *boot_infos;
 #define AVIVO_DC_LUTB_WHITE_OFFSET_GREEN        0x6cd4
 #define AVIVO_DC_LUTB_WHITE_OFFSET_RED          0x6cd8
 
-#define FB_RIGHT_POS(p, bpp)         (fb_be_math(p) ? 0 : (32 - (bpp)))
-
-static inline u32 offb_cmap_byteswap(struct fb_info *info, u32 value)
-{
-       u32 bpp = info->var.bits_per_pixel;
-
-       return cpu_to_be32(value) >> FB_RIGHT_POS(info, bpp);
-}
-
     /*
      *  Set a single color register. The values supplied are already
      *  rounded down to the hardware's capabilities (according to the
@@ -129,7 +120,7 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                        mask <<= info->var.transp.offset;
                        value |= mask;
                }
-               pal[regno] = offb_cmap_byteswap(info, value);
+               pal[regno] = value;
                return 0;
        }
 
index 67b067a..a5df5e8 100644 (file)
@@ -66,7 +66,7 @@ static u8 mxc_w1_ds2_reset_bus(void *data)
 
                udelay(100);
        }
-       return !!(reg_val & MXC_W1_CONTROL_PST);
+       return !(reg_val & MXC_W1_CONTROL_PST);
 }
 
 /*
index c845527..76dd541 100644 (file)
@@ -1280,14 +1280,17 @@ config WATCHDOG_RTAS
 
 # S390 Architecture
 
-config ZVM_WATCHDOG
-       tristate "z/VM Watchdog Timer"
+config DIAG288_WATCHDOG
+       tristate "System z diag288 Watchdog"
        depends on S390
+       select WATCHDOG_CORE
        help
          IBM s/390 and zSeries machines running under z/VM 5.1 or later
          provide a virtual watchdog timer to their guest that cause a
          user define Control Program command to be executed after a
          timeout.
+         LPAR provides a very similar interface. This driver handles
+         both.
 
          To compile this driver as a module, choose M here. The module
          will be called vmwatchdog.
index 7b8a91e..468c320 100644 (file)
@@ -153,6 +153,7 @@ obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.o
 obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
 
 # S390 Architecture
+obj-$(CONFIG_DIAG288_WATCHDOG) += diag288_wdt.o
 
 # SUPERH (sh + sh64) Architecture
 obj-$(CONFIG_SH_WDT) += shwdt.o
diff --git a/drivers/watchdog/diag288_wdt.c b/drivers/watchdog/diag288_wdt.c
new file mode 100644 (file)
index 0000000..429494b
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Watchdog driver for z/VM and LPAR using the diag 288 interface.
+ *
+ * Under z/VM, expiration of the watchdog will send a "system restart" command
+ * to CP.
+ *
+ * The command can be altered using the module parameter "cmd". This is
+ * not recommended because it's only supported on z/VM but not whith LPAR.
+ *
+ * On LPAR, the watchdog will always trigger a system restart. the module
+ * paramter cmd is meaningless here.
+ *
+ *
+ * Copyright IBM Corp. 2004, 2013
+ * Author(s): Arnd Bergmann (arndb@de.ibm.com)
+ *           Philipp Hachtmann (phacht@de.ibm.com)
+ *
+ */
+
+#define KMSG_COMPONENT "diag288_wdt"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/suspend.h>
+#include <asm/ebcdic.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#define MAX_CMDLEN 240
+#define DEFAULT_CMD "SYSTEM RESTART"
+
+#define MIN_INTERVAL 15     /* Minimal time supported by diag88 */
+#define MAX_INTERVAL 3600   /* One hour should be enough - pure estimation */
+
+#define WDT_DEFAULT_TIMEOUT 30
+
+/* Function codes - init, change, cancel */
+#define WDT_FUNC_INIT 0
+#define WDT_FUNC_CHANGE 1
+#define WDT_FUNC_CANCEL 2
+#define WDT_FUNC_CONCEAL 0x80000000
+
+/* Action codes for LPAR watchdog */
+#define LPARWDT_RESTART 0
+
+static char wdt_cmd[MAX_CMDLEN] = DEFAULT_CMD;
+static bool conceal_on;
+static bool nowayout_info = WATCHDOG_NOWAYOUT;
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
+MODULE_AUTHOR("Philipp Hachtmann <phacht@de.ibm.com>");
+
+MODULE_DESCRIPTION("System z diag288  Watchdog Timer");
+
+module_param_string(cmd, wdt_cmd, MAX_CMDLEN, 0644);
+MODULE_PARM_DESC(cmd, "CP command that is run when the watchdog triggers (z/VM only)");
+
+module_param_named(conceal, conceal_on, bool, 0644);
+MODULE_PARM_DESC(conceal, "Enable the CONCEAL CP option while the watchdog is active (z/VM only)");
+
+module_param_named(nowayout, nowayout_info, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default = CONFIG_WATCHDOG_NOWAYOUT)");
+
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("vmwatchdog");
+
+static int __diag288(unsigned int func, unsigned int timeout,
+                    unsigned long action, unsigned int len)
+{
+       register unsigned long __func asm("2") = func;
+       register unsigned long __timeout asm("3") = timeout;
+       register unsigned long __action asm("4") = action;
+       register unsigned long __len asm("5") = len;
+       int err;
+
+       err = -EINVAL;
+       asm volatile(
+               "       diag    %1, %3, 0x288\n"
+               "0:     la      %0, 0\n"
+               "1:\n"
+               EX_TABLE(0b, 1b)
+               : "+d" (err) : "d"(__func), "d"(__timeout),
+                 "d"(__action), "d"(__len) : "1", "cc");
+       return err;
+}
+
+static int __diag288_vm(unsigned int  func, unsigned int timeout,
+                       char *cmd, size_t len)
+{
+       return __diag288(func, timeout, virt_to_phys(cmd), len);
+}
+
+static int __diag288_lpar(unsigned int func, unsigned int timeout,
+                         unsigned long action)
+{
+       return __diag288(func, timeout, action, 0);
+}
+
+static int wdt_start(struct watchdog_device *dev)
+{
+       char *ebc_cmd;
+       size_t len;
+       int ret;
+       unsigned int func;
+
+       ret = -ENODEV;
+
+       if (MACHINE_IS_VM) {
+               ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL);
+               if (!ebc_cmd)
+                       return -ENOMEM;
+               len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN);
+               ASCEBC(ebc_cmd, MAX_CMDLEN);
+               EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
+
+               func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL)
+                       : WDT_FUNC_INIT;
+               ret = __diag288_vm(func, dev->timeout, ebc_cmd, len);
+               WARN_ON(ret != 0);
+               kfree(ebc_cmd);
+       }
+
+       if (MACHINE_IS_LPAR) {
+               ret = __diag288_lpar(WDT_FUNC_INIT,
+                                    dev->timeout, LPARWDT_RESTART);
+       }
+
+       if (ret) {
+               pr_err("The watchdog cannot be activated\n");
+               return ret;
+       }
+       pr_info("The watchdog was activated\n");
+       return 0;
+}
+
+static int wdt_stop(struct watchdog_device *dev)
+{
+       int ret;
+
+       ret = __diag288(WDT_FUNC_CANCEL, 0, 0, 0);
+       pr_info("The watchdog was deactivated\n");
+       return ret;
+}
+
+static int wdt_ping(struct watchdog_device *dev)
+{
+       char *ebc_cmd;
+       size_t len;
+       int ret;
+       unsigned int func;
+
+       ret = -ENODEV;
+
+       if (MACHINE_IS_VM) {
+               ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL);
+               if (!ebc_cmd)
+                       return -ENOMEM;
+               len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN);
+               ASCEBC(ebc_cmd, MAX_CMDLEN);
+               EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
+
+               /*
+                * It seems to be ok to z/VM to use the init function to
+                * retrigger the watchdog. On LPAR WDT_FUNC_CHANGE must
+                * be used when the watchdog is running.
+                */
+               func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL)
+                       : WDT_FUNC_INIT;
+
+               ret = __diag288_vm(func, dev->timeout, ebc_cmd, len);
+               WARN_ON(ret != 0);
+               kfree(ebc_cmd);
+       }
+
+       if (MACHINE_IS_LPAR)
+               ret = __diag288_lpar(WDT_FUNC_CHANGE, dev->timeout, 0);
+
+       if (ret)
+               pr_err("The watchdog timer cannot be started or reset\n");
+       return ret;
+}
+
+static int wdt_set_timeout(struct watchdog_device * dev, unsigned int new_to)
+{
+       dev->timeout = new_to;
+       return wdt_ping(dev);
+}
+
+static struct watchdog_ops wdt_ops = {
+       .owner = THIS_MODULE,
+       .start = wdt_start,
+       .stop = wdt_stop,
+       .ping = wdt_ping,
+       .set_timeout = wdt_set_timeout,
+};
+
+static struct watchdog_info wdt_info = {
+       .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
+       .firmware_version = 0,
+       .identity = "z Watchdog",
+};
+
+static struct watchdog_device wdt_dev = {
+       .parent = NULL,
+       .info = &wdt_info,
+       .ops = &wdt_ops,
+       .bootstatus = 0,
+       .timeout = WDT_DEFAULT_TIMEOUT,
+       .min_timeout = MIN_INTERVAL,
+       .max_timeout = MAX_INTERVAL,
+};
+
+/*
+ * It makes no sense to go into suspend while the watchdog is running.
+ * Depending on the memory size, the watchdog might trigger, while we
+ * are still saving the memory.
+ * We reuse the open flag to ensure that suspend and watchdog open are
+ * exclusive operations
+ */
+static int wdt_suspend(void)
+{
+       if (test_and_set_bit(WDOG_DEV_OPEN, &wdt_dev.status)) {
+               pr_err("Linux cannot be suspended while the watchdog is in use\n");
+               return notifier_from_errno(-EBUSY);
+       }
+       if (test_bit(WDOG_ACTIVE, &wdt_dev.status)) {
+               clear_bit(WDOG_DEV_OPEN, &wdt_dev.status);
+               pr_err("Linux cannot be suspended while the watchdog is in use\n");
+               return notifier_from_errno(-EBUSY);
+       }
+       return NOTIFY_DONE;
+}
+
+static int wdt_resume(void)
+{
+       clear_bit(WDOG_DEV_OPEN, &wdt_dev.status);
+       return NOTIFY_DONE;
+}
+
+static int wdt_power_event(struct notifier_block *this, unsigned long event,
+                          void *ptr)
+{
+       switch (event) {
+       case PM_POST_HIBERNATION:
+       case PM_POST_SUSPEND:
+               return wdt_resume();
+       case PM_HIBERNATION_PREPARE:
+       case PM_SUSPEND_PREPARE:
+               return wdt_suspend();
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
+static struct notifier_block wdt_power_notifier = {
+       .notifier_call = wdt_power_event,
+};
+
+static int __init diag288_init(void)
+{
+       int ret;
+       char ebc_begin[] = {
+               194, 197, 199, 201, 213
+       };
+
+       watchdog_set_nowayout(&wdt_dev, nowayout_info);
+
+       if (MACHINE_IS_VM) {
+               pr_info("The watchdog device driver detected a z/VM environment\n");
+               if (__diag288_vm(WDT_FUNC_INIT, 15,
+                                ebc_begin, sizeof(ebc_begin)) != 0) {
+                       pr_err("The watchdog cannot be initialized\n");
+                       return -EINVAL;
+               }
+       } else if (MACHINE_IS_LPAR) {
+               pr_info("The watchdog device driver detected an LPAR environment\n");
+               if (__diag288_lpar(WDT_FUNC_INIT, 30, LPARWDT_RESTART)) {
+                       pr_err("The watchdog cannot be initialized\n");
+                       return -EINVAL;
+               }
+       } else {
+               pr_err("Linux runs in an environment that does not support the diag288 watchdog\n");
+               return -ENODEV;
+       }
+
+       if (__diag288_lpar(WDT_FUNC_CANCEL, 0, 0)) {
+               pr_err("The watchdog cannot be deactivated\n");
+               return -EINVAL;
+       }
+
+       ret = register_pm_notifier(&wdt_power_notifier);
+       if (ret)
+               return ret;
+
+       ret = watchdog_register_device(&wdt_dev);
+       if (ret)
+               unregister_pm_notifier(&wdt_power_notifier);
+
+       return ret;
+}
+
+static void __exit diag288_exit(void)
+{
+       watchdog_unregister_device(&wdt_dev);
+       unregister_pm_notifier(&wdt_power_notifier);
+}
+
+module_init(diag288_init);
+module_exit(diag288_exit);
index 6d325bd..5d4de88 100644 (file)
@@ -1168,7 +1168,8 @@ int gnttab_resume(void)
 
 int gnttab_suspend(void)
 {
-       gnttab_interface->unmap_frames();
+       if (!xen_feature(XENFEAT_auto_translated_physmap))
+               gnttab_interface->unmap_frames();
        return 0;
 }
 
index 4f078c0..955947e 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1021,6 +1021,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
 
        /* everything turned out well, dispose of the aiocb. */
        kiocb_free(iocb);
+       put_reqs_available(ctx, 1);
 
        /*
         * We have to order our ring_info tail store above and test
@@ -1062,6 +1063,9 @@ static long aio_read_events_ring(struct kioctx *ctx,
        if (head == tail)
                goto out;
 
+       head %= ctx->nr_events;
+       tail %= ctx->nr_events;
+
        while (ret < nr) {
                long avail;
                struct io_event *ev;
@@ -1100,8 +1104,6 @@ static long aio_read_events_ring(struct kioctx *ctx,
        flush_dcache_page(ctx->ring_pages[0]);
 
        pr_debug("%li  h%u t%u\n", ret, head, tail);
-
-       put_reqs_available(ctx, ret);
 out:
        mutex_unlock(&ctx->ring_lock);
 
index b7e2c1c..be91397 100644 (file)
@@ -1259,11 +1259,19 @@ struct btrfs_block_group_cache {
        spinlock_t lock;
        u64 pinned;
        u64 reserved;
+       u64 delalloc_bytes;
        u64 bytes_super;
        u64 flags;
        u64 sectorsize;
        u64 cache_generation;
 
+       /*
+        * It is just used for the delayed data space allocation because
+        * only the data space allocation and the relative metadata update
+        * can be done cross the transaction.
+        */
+       struct rw_semaphore data_rwsem;
+
        /* for raid56, this is a full stripe, without parity */
        unsigned long full_stripe_len;
 
@@ -3316,7 +3324,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
                                   struct btrfs_key *ins);
 int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes,
                         u64 min_alloc_size, u64 empty_size, u64 hint_byte,
-                        struct btrfs_key *ins, int is_data);
+                        struct btrfs_key *ins, int is_data, int delalloc);
 int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                  struct extent_buffer *buf, int full_backref, int no_quota);
 int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
@@ -3330,7 +3338,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
                      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
                      u64 owner, u64 offset, int no_quota);
 
-int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len);
+int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len,
+                              int delalloc);
 int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root,
                                       u64 start, u64 len);
 void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
index fafb3e5..99c2539 100644 (file)
@@ -105,7 +105,8 @@ static int find_next_key(struct btrfs_path *path, int level,
 static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
                            int dump_block_groups);
 static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
-                                      u64 num_bytes, int reserve);
+                                      u64 num_bytes, int reserve,
+                                      int delalloc);
 static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv,
                               u64 num_bytes);
 int btrfs_pin_extent(struct btrfs_root *root,
@@ -3260,7 +3261,8 @@ again:
 
        spin_lock(&block_group->lock);
        if (block_group->cached != BTRFS_CACHE_FINISHED ||
-           !btrfs_test_opt(root, SPACE_CACHE)) {
+           !btrfs_test_opt(root, SPACE_CACHE) ||
+           block_group->delalloc_bytes) {
                /*
                 * don't bother trying to write stuff out _if_
                 * a) we're not cached,
@@ -5613,6 +5615,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log,
  * @cache:     The cache we are manipulating
  * @num_bytes: The number of bytes in question
  * @reserve:   One of the reservation enums
+ * @delalloc:   The blocks are allocated for the delalloc write
  *
  * This is called by the allocator when it reserves space, or by somebody who is
  * freeing space that was never actually used on disk.  For example if you
@@ -5631,7 +5634,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log,
  * succeeds.
  */
 static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
-                                      u64 num_bytes, int reserve)
+                                      u64 num_bytes, int reserve, int delalloc)
 {
        struct btrfs_space_info *space_info = cache->space_info;
        int ret = 0;
@@ -5650,12 +5653,18 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
                                                num_bytes, 0);
                                space_info->bytes_may_use -= num_bytes;
                        }
+
+                       if (delalloc)
+                               cache->delalloc_bytes += num_bytes;
                }
        } else {
                if (cache->ro)
                        space_info->bytes_readonly += num_bytes;
                cache->reserved -= num_bytes;
                space_info->bytes_reserved -= num_bytes;
+
+               if (delalloc)
+                       cache->delalloc_bytes -= num_bytes;
        }
        spin_unlock(&cache->lock);
        spin_unlock(&space_info->lock);
@@ -6206,7 +6215,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
                WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags));
 
                btrfs_add_free_space(cache, buf->start, buf->len);
-               btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE);
+               btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE, 0);
                trace_btrfs_reserved_extent_free(root, buf->start, buf->len);
                pin = 0;
        }
@@ -6365,6 +6374,70 @@ enum btrfs_loop_type {
        LOOP_NO_EMPTY_SIZE = 3,
 };
 
+static inline void
+btrfs_lock_block_group(struct btrfs_block_group_cache *cache,
+                      int delalloc)
+{
+       if (delalloc)
+               down_read(&cache->data_rwsem);
+}
+
+static inline void
+btrfs_grab_block_group(struct btrfs_block_group_cache *cache,
+                      int delalloc)
+{
+       btrfs_get_block_group(cache);
+       if (delalloc)
+               down_read(&cache->data_rwsem);
+}
+
+static struct btrfs_block_group_cache *
+btrfs_lock_cluster(struct btrfs_block_group_cache *block_group,
+                  struct btrfs_free_cluster *cluster,
+                  int delalloc)
+{
+       struct btrfs_block_group_cache *used_bg;
+       bool locked = false;
+again:
+       spin_lock(&cluster->refill_lock);
+       if (locked) {
+               if (used_bg == cluster->block_group)
+                       return used_bg;
+
+               up_read(&used_bg->data_rwsem);
+               btrfs_put_block_group(used_bg);
+       }
+
+       used_bg = cluster->block_group;
+       if (!used_bg)
+               return NULL;
+
+       if (used_bg == block_group)
+               return used_bg;
+
+       btrfs_get_block_group(used_bg);
+
+       if (!delalloc)
+               return used_bg;
+
+       if (down_read_trylock(&used_bg->data_rwsem))
+               return used_bg;
+
+       spin_unlock(&cluster->refill_lock);
+       down_read(&used_bg->data_rwsem);
+       locked = true;
+       goto again;
+}
+
+static inline void
+btrfs_release_block_group(struct btrfs_block_group_cache *cache,
+                        int delalloc)
+{
+       if (delalloc)
+               up_read(&cache->data_rwsem);
+       btrfs_put_block_group(cache);
+}
+
 /*
  * walks the btree of allocated extents and find a hole of a given size.
  * The key ins is changed to record the hole:
@@ -6379,7 +6452,7 @@ enum btrfs_loop_type {
 static noinline int find_free_extent(struct btrfs_root *orig_root,
                                     u64 num_bytes, u64 empty_size,
                                     u64 hint_byte, struct btrfs_key *ins,
-                                    u64 flags)
+                                    u64 flags, int delalloc)
 {
        int ret = 0;
        struct btrfs_root *root = orig_root->fs_info->extent_root;
@@ -6467,6 +6540,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
                                up_read(&space_info->groups_sem);
                        } else {
                                index = get_block_group_index(block_group);
+                               btrfs_lock_block_group(block_group, delalloc);
                                goto have_block_group;
                        }
                } else if (block_group) {
@@ -6481,7 +6555,7 @@ search:
                u64 offset;
                int cached;
 
-               btrfs_get_block_group(block_group);
+               btrfs_grab_block_group(block_group, delalloc);
                search_start = block_group->key.objectid;
 
                /*
@@ -6529,16 +6603,16 @@ have_block_group:
                         * the refill lock keeps out other
                         * people trying to start a new cluster
                         */
-                       spin_lock(&last_ptr->refill_lock);
-                       used_block_group = last_ptr->block_group;
-                       if (used_block_group != block_group &&
-                           (!used_block_group ||
-                            used_block_group->ro ||
-                            !block_group_bits(used_block_group, flags)))
+                       used_block_group = btrfs_lock_cluster(block_group,
+                                                             last_ptr,
+                                                             delalloc);
+                       if (!used_block_group)
                                goto refill_cluster;
 
-                       if (used_block_group != block_group)
-                               btrfs_get_block_group(used_block_group);
+                       if (used_block_group != block_group &&
+                           (used_block_group->ro ||
+                            !block_group_bits(used_block_group, flags)))
+                               goto release_cluster;
 
                        offset = btrfs_alloc_from_cluster(used_block_group,
                                                last_ptr,
@@ -6552,16 +6626,15 @@ have_block_group:
                                                used_block_group,
                                                search_start, num_bytes);
                                if (used_block_group != block_group) {
-                                       btrfs_put_block_group(block_group);
+                                       btrfs_release_block_group(block_group,
+                                                                 delalloc);
                                        block_group = used_block_group;
                                }
                                goto checks;
                        }
 
                        WARN_ON(last_ptr->block_group != used_block_group);
-                       if (used_block_group != block_group)
-                               btrfs_put_block_group(used_block_group);
-refill_cluster:
+release_cluster:
                        /* If we are on LOOP_NO_EMPTY_SIZE, we can't
                         * set up a new clusters, so lets just skip it
                         * and let the allocator find whatever block
@@ -6578,8 +6651,10 @@ refill_cluster:
                         * succeeding in the unclustered
                         * allocation.  */
                        if (loop >= LOOP_NO_EMPTY_SIZE &&
-                           last_ptr->block_group != block_group) {
+                           used_block_group != block_group) {
                                spin_unlock(&last_ptr->refill_lock);
+                               btrfs_release_block_group(used_block_group,
+                                                         delalloc);
                                goto unclustered_alloc;
                        }
 
@@ -6589,6 +6664,10 @@ refill_cluster:
                         */
                        btrfs_return_cluster_to_free_space(NULL, last_ptr);
 
+                       if (used_block_group != block_group)
+                               btrfs_release_block_group(used_block_group,
+                                                         delalloc);
+refill_cluster:
                        if (loop >= LOOP_NO_EMPTY_SIZE) {
                                spin_unlock(&last_ptr->refill_lock);
                                goto unclustered_alloc;
@@ -6696,7 +6775,7 @@ checks:
                BUG_ON(offset > search_start);
 
                ret = btrfs_update_reserved_bytes(block_group, num_bytes,
-                                                 alloc_type);
+                                                 alloc_type, delalloc);
                if (ret == -EAGAIN) {
                        btrfs_add_free_space(block_group, offset, num_bytes);
                        goto loop;
@@ -6708,13 +6787,13 @@ checks:
 
                trace_btrfs_reserve_extent(orig_root, block_group,
                                           search_start, num_bytes);
-               btrfs_put_block_group(block_group);
+               btrfs_release_block_group(block_group, delalloc);
                break;
 loop:
                failed_cluster_refill = false;
                failed_alloc = false;
                BUG_ON(index != get_block_group_index(block_group));
-               btrfs_put_block_group(block_group);
+               btrfs_release_block_group(block_group, delalloc);
        }
        up_read(&space_info->groups_sem);
 
@@ -6827,7 +6906,7 @@ again:
 int btrfs_reserve_extent(struct btrfs_root *root,
                         u64 num_bytes, u64 min_alloc_size,
                         u64 empty_size, u64 hint_byte,
-                        struct btrfs_key *ins, int is_data)
+                        struct btrfs_key *ins, int is_data, int delalloc)
 {
        bool final_tried = false;
        u64 flags;
@@ -6837,7 +6916,7 @@ int btrfs_reserve_extent(struct btrfs_root *root,
 again:
        WARN_ON(num_bytes < root->sectorsize);
        ret = find_free_extent(root, num_bytes, empty_size, hint_byte, ins,
-                              flags);
+                              flags, delalloc);
 
        if (ret == -ENOSPC) {
                if (!final_tried && ins->offset) {
@@ -6862,7 +6941,8 @@ again:
 }
 
 static int __btrfs_free_reserved_extent(struct btrfs_root *root,
-                                       u64 start, u64 len, int pin)
+                                       u64 start, u64 len,
+                                       int pin, int delalloc)
 {
        struct btrfs_block_group_cache *cache;
        int ret = 0;
@@ -6881,7 +6961,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root,
                pin_down_extent(root, cache, start, len, 1);
        else {
                btrfs_add_free_space(cache, start, len);
-               btrfs_update_reserved_bytes(cache, len, RESERVE_FREE);
+               btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc);
        }
        btrfs_put_block_group(cache);
 
@@ -6891,15 +6971,15 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root,
 }
 
 int btrfs_free_reserved_extent(struct btrfs_root *root,
-                                       u64 start, u64 len)
+                              u64 start, u64 len, int delalloc)
 {
-       return __btrfs_free_reserved_extent(root, start, len, 0);
+       return __btrfs_free_reserved_extent(root, start, len, 0, delalloc);
 }
 
 int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root,
                                       u64 start, u64 len)
 {
-       return __btrfs_free_reserved_extent(root, start, len, 1);
+       return __btrfs_free_reserved_extent(root, start, len, 1, 0);
 }
 
 static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
@@ -7114,7 +7194,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
                return -EINVAL;
 
        ret = btrfs_update_reserved_bytes(block_group, ins->offset,
-                                         RESERVE_ALLOC_NO_ACCOUNT);
+                                         RESERVE_ALLOC_NO_ACCOUNT, 0);
        BUG_ON(ret); /* logic error */
        ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
                                         0, owner, offset, ins, 1);
@@ -7256,7 +7336,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
                return ERR_CAST(block_rsv);
 
        ret = btrfs_reserve_extent(root, blocksize, blocksize,
-                                  empty_size, hint, &ins, 0);
+                                  empty_size, hint, &ins, 0, 0);
        if (ret) {
                unuse_block_rsv(root->fs_info, block_rsv, blocksize);
                return ERR_PTR(ret);
@@ -8659,6 +8739,7 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size)
                                               start);
        atomic_set(&cache->count, 1);
        spin_lock_init(&cache->lock);
+       init_rwsem(&cache->data_rwsem);
        INIT_LIST_HEAD(&cache->list);
        INIT_LIST_HEAD(&cache->cluster_list);
        INIT_LIST_HEAD(&cache->new_bg_list);
index 15ce5f2..ccc264e 100644 (file)
@@ -158,7 +158,6 @@ struct extent_buffer {
         * to unlock
         */
        wait_queue_head_t read_lock_wq;
-       wait_queue_head_t lock_wq;
        struct page *pages[INLINE_EXTENT_BUFFER_PAGES];
 #ifdef CONFIG_BTRFS_DEBUG
        struct list_head leak_list;
index 1874aee..225302b 100644 (file)
@@ -75,6 +75,8 @@ void free_extent_map(struct extent_map *em)
        if (atomic_dec_and_test(&em->refs)) {
                WARN_ON(extent_map_in_tree(em));
                WARN_ON(!list_empty(&em->list));
+               if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags))
+                       kfree(em->bdev);
                kmem_cache_free(extent_map_cache, em);
        }
 }
index e7fd8a5..b2991fd 100644 (file)
@@ -15,6 +15,7 @@
 #define EXTENT_FLAG_PREALLOC 3 /* pre-allocated extent */
 #define EXTENT_FLAG_LOGGING 4 /* Logging this extent */
 #define EXTENT_FLAG_FILLING 5 /* Filling in a preallocated extent */
+#define EXTENT_FLAG_FS_MAPPING 6 /* filesystem extent mapping type */
 
 struct extent_map {
        struct rb_node rb_node;
index 372b05f..2b0a627 100644 (file)
@@ -274,18 +274,32 @@ struct io_ctl {
 };
 
 static int io_ctl_init(struct io_ctl *io_ctl, struct inode *inode,
-                      struct btrfs_root *root)
+                      struct btrfs_root *root, int write)
 {
+       int num_pages;
+       int check_crcs = 0;
+
+       num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
+                   PAGE_CACHE_SHIFT;
+
+       if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID)
+               check_crcs = 1;
+
+       /* Make sure we can fit our crcs into the first page */
+       if (write && check_crcs &&
+           (num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE)
+               return -ENOSPC;
+
        memset(io_ctl, 0, sizeof(struct io_ctl));
-       io_ctl->num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
-               PAGE_CACHE_SHIFT;
-       io_ctl->pages = kzalloc(sizeof(struct page *) * io_ctl->num_pages,
-                               GFP_NOFS);
+
+       io_ctl->pages = kzalloc(sizeof(struct page *) * num_pages, GFP_NOFS);
        if (!io_ctl->pages)
                return -ENOMEM;
+
+       io_ctl->num_pages = num_pages;
        io_ctl->root = root;
-       if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID)
-               io_ctl->check_crcs = 1;
+       io_ctl->check_crcs = check_crcs;
+
        return 0;
 }
 
@@ -666,6 +680,13 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
        generation = btrfs_free_space_generation(leaf, header);
        btrfs_release_path(path);
 
+       if (!BTRFS_I(inode)->generation) {
+               btrfs_info(root->fs_info,
+                          "The free space cache file (%llu) is invalid. skip it\n",
+                          offset);
+               return 0;
+       }
+
        if (BTRFS_I(inode)->generation != generation) {
                btrfs_err(root->fs_info,
                        "free space inode generation (%llu) "
@@ -677,7 +698,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
        if (!num_entries)
                return 0;
 
-       ret = io_ctl_init(&io_ctl, inode, root);
+       ret = io_ctl_init(&io_ctl, inode, root, 0);
        if (ret)
                return ret;
 
@@ -957,19 +978,18 @@ fail:
 }
 
 static noinline_for_stack int
-add_ioctl_entries(struct btrfs_root *root,
-                 struct inode *inode,
-                 struct btrfs_block_group_cache *block_group,
-                 struct io_ctl *io_ctl,
-                 struct extent_state **cached_state,
-                 struct list_head *bitmap_list,
-                 int *entries)
+write_pinned_extent_entries(struct btrfs_root *root,
+                           struct btrfs_block_group_cache *block_group,
+                           struct io_ctl *io_ctl,
+                           int *entries)
 {
        u64 start, extent_start, extent_end, len;
-       struct list_head *pos, *n;
        struct extent_io_tree *unpin = NULL;
        int ret;
 
+       if (!block_group)
+               return 0;
+
        /*
         * We want to add any pinned extents to our free space cache
         * so we don't leak the space
@@ -979,23 +999,19 @@ add_ioctl_entries(struct btrfs_root *root,
         */
        unpin = root->fs_info->pinned_extents;
 
-       if (block_group)
-               start = block_group->key.objectid;
+       start = block_group->key.objectid;
 
-       while (block_group && (start < block_group->key.objectid +
-                              block_group->key.offset)) {
+       while (start < block_group->key.objectid + block_group->key.offset) {
                ret = find_first_extent_bit(unpin, start,
                                            &extent_start, &extent_end,
                                            EXTENT_DIRTY, NULL);
-               if (ret) {
-                       ret = 0;
-                       break;
-               }
+               if (ret)
+                       return 0;
 
                /* This pinned extent is out of our range */
                if (extent_start >= block_group->key.objectid +
                    block_group->key.offset)
-                       break;
+                       return 0;
 
                extent_start = max(extent_start, start);
                extent_end = min(block_group->key.objectid +
@@ -1005,11 +1021,20 @@ add_ioctl_entries(struct btrfs_root *root,
                *entries += 1;
                ret = io_ctl_add_entry(io_ctl, extent_start, len, NULL);
                if (ret)
-                       goto out_nospc;
+                       return -ENOSPC;
 
                start = extent_end;
        }
 
+       return 0;
+}
+
+static noinline_for_stack int
+write_bitmap_entries(struct io_ctl *io_ctl, struct list_head *bitmap_list)
+{
+       struct list_head *pos, *n;
+       int ret;
+
        /* Write out the bitmaps */
        list_for_each_safe(pos, n, bitmap_list) {
                struct btrfs_free_space *entry =
@@ -1017,36 +1042,24 @@ add_ioctl_entries(struct btrfs_root *root,
 
                ret = io_ctl_add_bitmap(io_ctl, entry->bitmap);
                if (ret)
-                       goto out_nospc;
+                       return -ENOSPC;
                list_del_init(&entry->list);
        }
 
-       /* Zero out the rest of the pages just to make sure */
-       io_ctl_zero_remaining_pages(io_ctl);
-
-       ret = btrfs_dirty_pages(root, inode, io_ctl->pages, io_ctl->num_pages,
-                               0, i_size_read(inode), cached_state);
-       io_ctl_drop_pages(io_ctl);
-       unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
-                            i_size_read(inode) - 1, cached_state, GFP_NOFS);
+       return 0;
+}
 
-       if (ret)
-               goto fail;
+static int flush_dirty_cache(struct inode *inode)
+{
+       int ret;
 
        ret = btrfs_wait_ordered_range(inode, 0, (u64)-1);
-       if (ret) {
+       if (ret)
                clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1,
                                 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL,
                                 GFP_NOFS);
-               goto fail;
-       }
-       return 0;
 
-fail:
-       return -1;
-
-out_nospc:
-       return -ENOSPC;
+       return ret;
 }
 
 static void noinline_for_stack
@@ -1056,6 +1069,7 @@ cleanup_write_cache_enospc(struct inode *inode,
                           struct list_head *bitmap_list)
 {
        struct list_head *pos, *n;
+
        list_for_each_safe(pos, n, bitmap_list) {
                struct btrfs_free_space *entry =
                        list_entry(pos, struct btrfs_free_space, list);
@@ -1088,64 +1102,104 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
 {
        struct extent_state *cached_state = NULL;
        struct io_ctl io_ctl;
-       struct list_head bitmap_list;
+       LIST_HEAD(bitmap_list);
        int entries = 0;
        int bitmaps = 0;
        int ret;
-       int err = -1;
-
-       INIT_LIST_HEAD(&bitmap_list);
 
        if (!i_size_read(inode))
                return -1;
 
-       ret = io_ctl_init(&io_ctl, inode, root);
+       ret = io_ctl_init(&io_ctl, inode, root, 1);
        if (ret)
                return -1;
 
+       if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) {
+               down_write(&block_group->data_rwsem);
+               spin_lock(&block_group->lock);
+               if (block_group->delalloc_bytes) {
+                       block_group->disk_cache_state = BTRFS_DC_WRITTEN;
+                       spin_unlock(&block_group->lock);
+                       up_write(&block_group->data_rwsem);
+                       BTRFS_I(inode)->generation = 0;
+                       ret = 0;
+                       goto out;
+               }
+               spin_unlock(&block_group->lock);
+       }
+
        /* Lock all pages first so we can lock the extent safely. */
        io_ctl_prepare_pages(&io_ctl, inode, 0);
 
        lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
                         0, &cached_state);
 
-
-       /* 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)
-               goto out_nospc;
-
        io_ctl_set_generation(&io_ctl, trans->transid);
 
+       /* Write out the extent entries in the free space cache */
        ret = write_cache_extent_entries(&io_ctl, ctl,
                                         block_group, &entries, &bitmaps,
                                         &bitmap_list);
        if (ret)
                goto out_nospc;
 
-       ret = add_ioctl_entries(root, inode, block_group, &io_ctl,
-                               &cached_state, &bitmap_list, &entries);
+       /*
+        * Some spaces that are freed in the current transaction are pinned,
+        * they will be added into free space cache after the transaction is
+        * committed, we shouldn't lose them.
+        */
+       ret = write_pinned_extent_entries(root, block_group, &io_ctl, &entries);
+       if (ret)
+               goto out_nospc;
 
-       if (ret == -ENOSPC)
+       /* At last, we write out all the bitmaps. */
+       ret = write_bitmap_entries(&io_ctl, &bitmap_list);
+       if (ret)
                goto out_nospc;
-       else if (ret)
+
+       /* Zero out the rest of the pages just to make sure */
+       io_ctl_zero_remaining_pages(&io_ctl);
+
+       /* Everything is written out, now we dirty the pages in the file. */
+       ret = btrfs_dirty_pages(root, inode, io_ctl.pages, io_ctl.num_pages,
+                               0, i_size_read(inode), &cached_state);
+       if (ret)
+               goto out_nospc;
+
+       if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA))
+               up_write(&block_group->data_rwsem);
+       /*
+        * Release the pages and unlock the extent, we will flush
+        * them out later
+        */
+       io_ctl_drop_pages(&io_ctl);
+
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
+                            i_size_read(inode) - 1, &cached_state, GFP_NOFS);
+
+       /* Flush the dirty pages in the cache file. */
+       ret = flush_dirty_cache(inode);
+       if (ret)
                goto out;
 
-       err = update_cache_item(trans, root, inode, path, offset,
+       /* Update the cache item to tell everyone this cache file is valid. */
+       ret = update_cache_item(trans, root, inode, path, offset,
                                entries, bitmaps);
-
 out:
        io_ctl_free(&io_ctl);
-       if (err) {
+       if (ret) {
                invalidate_inode_pages2(inode->i_mapping);
                BTRFS_I(inode)->generation = 0;
        }
        btrfs_update_inode(trans, root, inode);
-       return err;
+       return ret;
 
 out_nospc:
-
        cleanup_write_cache_enospc(inode, &io_ctl, &cached_state, &bitmap_list);
+
+       if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA))
+               up_write(&block_group->data_rwsem);
+
        goto out;
 }
 
@@ -1165,6 +1219,12 @@ int btrfs_write_out_cache(struct btrfs_root *root,
                spin_unlock(&block_group->lock);
                return 0;
        }
+
+       if (block_group->delalloc_bytes) {
+               block_group->disk_cache_state = BTRFS_DC_WRITTEN;
+               spin_unlock(&block_group->lock);
+               return 0;
+       }
        spin_unlock(&block_group->lock);
 
        inode = lookup_free_space_inode(root, block_group, path);
index 8925f66..3668048 100644 (file)
@@ -693,7 +693,7 @@ retry:
                ret = btrfs_reserve_extent(root,
                                           async_extent->compressed_size,
                                           async_extent->compressed_size,
-                                          0, alloc_hint, &ins, 1);
+                                          0, alloc_hint, &ins, 1, 1);
                if (ret) {
                        int i;
 
@@ -794,7 +794,7 @@ retry:
 out:
        return ret;
 out_free_reserve:
-       btrfs_free_reserved_extent(root, ins.objectid, ins.offset);
+       btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);
 out_free:
        extent_clear_unlock_delalloc(inode, async_extent->start,
                                     async_extent->start +
@@ -917,7 +917,7 @@ static noinline int cow_file_range(struct inode *inode,
                cur_alloc_size = disk_num_bytes;
                ret = btrfs_reserve_extent(root, cur_alloc_size,
                                           root->sectorsize, 0, alloc_hint,
-                                          &ins, 1);
+                                          &ins, 1, 1);
                if (ret < 0)
                        goto out_unlock;
 
@@ -995,7 +995,7 @@ out:
        return ret;
 
 out_reserve:
-       btrfs_free_reserved_extent(root, ins.objectid, ins.offset);
+       btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);
 out_unlock:
        extent_clear_unlock_delalloc(inode, start, end, locked_page,
                                     EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
@@ -2599,6 +2599,21 @@ out_kfree:
        return NULL;
 }
 
+static void btrfs_release_delalloc_bytes(struct btrfs_root *root,
+                                        u64 start, u64 len)
+{
+       struct btrfs_block_group_cache *cache;
+
+       cache = btrfs_lookup_block_group(root->fs_info, start);
+       ASSERT(cache);
+
+       spin_lock(&cache->lock);
+       cache->delalloc_bytes -= len;
+       spin_unlock(&cache->lock);
+
+       btrfs_put_block_group(cache);
+}
+
 /* as ordered data IO finishes, this gets called so we can finish
  * an ordered extent if the range of bytes in the file it covers are
  * fully written.
@@ -2698,6 +2713,10 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                                                logical_len, logical_len,
                                                compress_type, 0, 0,
                                                BTRFS_FILE_EXTENT_REG);
+               if (!ret)
+                       btrfs_release_delalloc_bytes(root,
+                                                    ordered_extent->start,
+                                                    ordered_extent->disk_len);
        }
        unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
                           ordered_extent->file_offset, ordered_extent->len,
@@ -2750,7 +2769,7 @@ out:
                    !test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
                    !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags))
                        btrfs_free_reserved_extent(root, ordered_extent->start,
-                                                  ordered_extent->disk_len);
+                                                  ordered_extent->disk_len, 1);
        }
 
 
@@ -6535,21 +6554,21 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
 
        alloc_hint = get_extent_allocation_hint(inode, start, len);
        ret = btrfs_reserve_extent(root, len, root->sectorsize, 0,
-                                  alloc_hint, &ins, 1);
+                                  alloc_hint, &ins, 1, 1);
        if (ret)
                return ERR_PTR(ret);
 
        em = create_pinned_em(inode, start, ins.offset, start, ins.objectid,
                              ins.offset, ins.offset, ins.offset, 0);
        if (IS_ERR(em)) {
-               btrfs_free_reserved_extent(root, ins.objectid, ins.offset);
+               btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);
                return em;
        }
 
        ret = btrfs_add_ordered_extent_dio(inode, start, ins.objectid,
                                           ins.offset, ins.offset, 0);
        if (ret) {
-               btrfs_free_reserved_extent(root, ins.objectid, ins.offset);
+               btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);
                free_extent_map(em);
                return ERR_PTR(ret);
        }
@@ -7437,7 +7456,7 @@ free_ordered:
                if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) &&
                    !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags))
                        btrfs_free_reserved_extent(root, ordered->start,
-                                                  ordered->disk_len);
+                                                  ordered->disk_len, 1);
                btrfs_put_ordered_extent(ordered);
                btrfs_put_ordered_extent(ordered);
        }
@@ -8808,7 +8827,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
                cur_bytes = min(num_bytes, 256ULL * 1024 * 1024);
                cur_bytes = max(cur_bytes, min_size);
                ret = btrfs_reserve_extent(root, cur_bytes, min_size, 0,
-                                          *alloc_hint, &ins, 1);
+                                          *alloc_hint, &ins, 1, 0);
                if (ret) {
                        if (own_trans)
                                btrfs_end_transaction(trans, root);
@@ -8822,7 +8841,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
                                                  BTRFS_FILE_EXTENT_PREALLOC);
                if (ret) {
                        btrfs_free_reserved_extent(root, ins.objectid,
-                                                  ins.offset);
+                                                  ins.offset, 0);
                        btrfs_abort_transaction(trans, root, ret);
                        if (own_trans)
                                btrfs_end_transaction(trans, root);
index 01277b8..5665d21 100644 (file)
@@ -33,14 +33,14 @@ static void btrfs_assert_tree_read_locked(struct extent_buffer *eb);
  */
 void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw)
 {
-       if (eb->lock_nested) {
-               read_lock(&eb->lock);
-               if (eb->lock_nested && current->pid == eb->lock_owner) {
-                       read_unlock(&eb->lock);
-                       return;
-               }
-               read_unlock(&eb->lock);
-       }
+       /*
+        * no lock is required.  The lock owner may change if
+        * we have a read lock, but it won't change to or away
+        * from us.  If we have the write lock, we are the owner
+        * and it'll never change.
+        */
+       if (eb->lock_nested && current->pid == eb->lock_owner)
+               return;
        if (rw == BTRFS_WRITE_LOCK) {
                if (atomic_read(&eb->blocking_writers) == 0) {
                        WARN_ON(atomic_read(&eb->spinning_writers) != 1);
@@ -65,14 +65,15 @@ void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw)
  */
 void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw)
 {
-       if (eb->lock_nested) {
-               read_lock(&eb->lock);
-               if (eb->lock_nested && current->pid == eb->lock_owner) {
-                       read_unlock(&eb->lock);
-                       return;
-               }
-               read_unlock(&eb->lock);
-       }
+       /*
+        * no lock is required.  The lock owner may change if
+        * we have a read lock, but it won't change to or away
+        * from us.  If we have the write lock, we are the owner
+        * and it'll never change.
+        */
+       if (eb->lock_nested && current->pid == eb->lock_owner)
+               return;
+
        if (rw == BTRFS_WRITE_LOCK_BLOCKING) {
                BUG_ON(atomic_read(&eb->blocking_writers) != 1);
                write_lock(&eb->lock);
@@ -99,6 +100,9 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw)
 void btrfs_tree_read_lock(struct extent_buffer *eb)
 {
 again:
+       BUG_ON(!atomic_read(&eb->blocking_writers) &&
+              current->pid == eb->lock_owner);
+
        read_lock(&eb->lock);
        if (atomic_read(&eb->blocking_writers) &&
            current->pid == eb->lock_owner) {
@@ -132,7 +136,9 @@ int btrfs_try_tree_read_lock(struct extent_buffer *eb)
        if (atomic_read(&eb->blocking_writers))
                return 0;
 
-       read_lock(&eb->lock);
+       if (!read_trylock(&eb->lock))
+               return 0;
+
        if (atomic_read(&eb->blocking_writers)) {
                read_unlock(&eb->lock);
                return 0;
@@ -151,7 +157,10 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb)
        if (atomic_read(&eb->blocking_writers) ||
            atomic_read(&eb->blocking_readers))
                return 0;
-       write_lock(&eb->lock);
+
+       if (!write_trylock(&eb->lock))
+               return 0;
+
        if (atomic_read(&eb->blocking_writers) ||
            atomic_read(&eb->blocking_readers)) {
                write_unlock(&eb->lock);
@@ -168,14 +177,15 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb)
  */
 void btrfs_tree_read_unlock(struct extent_buffer *eb)
 {
-       if (eb->lock_nested) {
-               read_lock(&eb->lock);
-               if (eb->lock_nested && current->pid == eb->lock_owner) {
-                       eb->lock_nested = 0;
-                       read_unlock(&eb->lock);
-                       return;
-               }
-               read_unlock(&eb->lock);
+       /*
+        * if we're nested, we have the write lock.  No new locking
+        * is needed as long as we are the lock owner.
+        * The write unlock will do a barrier for us, and the lock_nested
+        * field only matters to the lock owner.
+        */
+       if (eb->lock_nested && current->pid == eb->lock_owner) {
+               eb->lock_nested = 0;
+               return;
        }
        btrfs_assert_tree_read_locked(eb);
        WARN_ON(atomic_read(&eb->spinning_readers) == 0);
@@ -189,14 +199,15 @@ void btrfs_tree_read_unlock(struct extent_buffer *eb)
  */
 void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb)
 {
-       if (eb->lock_nested) {
-               read_lock(&eb->lock);
-               if (eb->lock_nested && current->pid == eb->lock_owner) {
-                       eb->lock_nested = 0;
-                       read_unlock(&eb->lock);
-                       return;
-               }
-               read_unlock(&eb->lock);
+       /*
+        * if we're nested, we have the write lock.  No new locking
+        * is needed as long as we are the lock owner.
+        * The write unlock will do a barrier for us, and the lock_nested
+        * field only matters to the lock owner.
+        */
+       if (eb->lock_nested && current->pid == eb->lock_owner) {
+               eb->lock_nested = 0;
+               return;
        }
        btrfs_assert_tree_read_locked(eb);
        WARN_ON(atomic_read(&eb->blocking_readers) == 0);
@@ -244,6 +255,7 @@ void btrfs_tree_unlock(struct extent_buffer *eb)
        BUG_ON(blockers > 1);
 
        btrfs_assert_tree_locked(eb);
+       eb->lock_owner = 0;
        atomic_dec(&eb->write_locks);
 
        if (blockers) {
index ac80188..b6d198f 100644 (file)
@@ -2725,11 +2725,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent);
                length = btrfs_dev_extent_length(l, dev_extent);
 
-               if (found_key.offset + length <= start) {
-                       key.offset = found_key.offset + length;
-                       btrfs_release_path(path);
-                       continue;
-               }
+               if (found_key.offset + length <= start)
+                       goto skip;
 
                chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent);
                chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent);
@@ -2740,10 +2737,12 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                 * the chunk from going away while we scrub it
                 */
                cache = btrfs_lookup_block_group(fs_info, chunk_offset);
-               if (!cache) {
-                       ret = -ENOENT;
-                       break;
-               }
+
+               /* some chunks are removed but not committed to disk yet,
+                * continue scrubbing */
+               if (!cache)
+                       goto skip;
+
                dev_replace->cursor_right = found_key.offset + length;
                dev_replace->cursor_left = found_key.offset;
                dev_replace->item_needs_writeback = 1;
@@ -2802,7 +2801,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
 
                dev_replace->cursor_left = dev_replace->cursor_right;
                dev_replace->item_needs_writeback = 1;
-
+skip:
                key.offset = found_key.offset + length;
                btrfs_release_path(path);
        }
index ffeed6d..c83b242 100644 (file)
@@ -2543,9 +2543,6 @@ static int btrfs_relocate_chunk(struct btrfs_root *root,
        remove_extent_mapping(em_tree, em);
        write_unlock(&em_tree->lock);
 
-       kfree(map);
-       em->bdev = NULL;
-
        /* once for the tree */
        free_extent_map(em);
        /* once for us */
@@ -4301,9 +4298,11 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 
        em = alloc_extent_map();
        if (!em) {
+               kfree(map);
                ret = -ENOMEM;
                goto error;
        }
+       set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
        em->bdev = (struct block_device *)map;
        em->start = start;
        em->len = num_bytes;
@@ -4346,7 +4345,6 @@ error_del_extent:
        /* One for the tree reference */
        free_extent_map(em);
 error:
-       kfree(map);
        kfree(devices_info);
        return ret;
 }
@@ -4558,7 +4556,6 @@ void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree)
                write_unlock(&tree->map_tree.lock);
                if (!em)
                        break;
-               kfree(em->bdev);
                /* once for us */
                free_extent_map(em);
                /* once for the tree */
@@ -5362,6 +5359,15 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
        return 0;
 }
 
+static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int err)
+{
+       if (likely(bbio->flags & BTRFS_BIO_ORIG_BIO_SUBMITTED))
+               bio_endio_nodec(bio, err);
+       else
+               bio_endio(bio, err);
+       kfree(bbio);
+}
+
 static void btrfs_end_bio(struct bio *bio, int err)
 {
        struct btrfs_bio *bbio = bio->bi_private;
@@ -5402,12 +5408,6 @@ static void btrfs_end_bio(struct bio *bio, int err)
                        bio = bbio->orig_bio;
                }
 
-               /*
-                * We have original bio now. So increment bi_remaining to
-                * account for it in endio
-                */
-               atomic_inc(&bio->bi_remaining);
-
                bio->bi_private = bbio->private;
                bio->bi_end_io = bbio->end_io;
                btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
@@ -5424,9 +5424,8 @@ static void btrfs_end_bio(struct bio *bio, int err)
                        set_bit(BIO_UPTODATE, &bio->bi_flags);
                        err = 0;
                }
-               kfree(bbio);
 
-               bio_endio(bio, err);
+               btrfs_end_bbio(bbio, bio, err);
        } else if (!is_orig_bio) {
                bio_put(bio);
        }
@@ -5589,12 +5588,15 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
 {
        atomic_inc(&bbio->error);
        if (atomic_dec_and_test(&bbio->stripes_pending)) {
+               /* Shoud be the original bio. */
+               WARN_ON(bio != bbio->orig_bio);
+
                bio->bi_private = bbio->private;
                bio->bi_end_io = bbio->end_io;
                btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
                bio->bi_iter.bi_sector = logical >> 9;
-               kfree(bbio);
-               bio_endio(bio, -EIO);
+
+               btrfs_end_bbio(bbio, bio, -EIO);
        }
 }
 
@@ -5681,6 +5683,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
                        BUG_ON(!bio); /* -ENOMEM */
                } else {
                        bio = first_bio;
+                       bbio->flags |= BTRFS_BIO_ORIG_BIO_SUBMITTED;
                }
 
                submit_stripe_bio(root, bbio, bio,
@@ -5822,6 +5825,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
                return -ENOMEM;
        }
 
+       set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
        em->bdev = (struct block_device *)map;
        em->start = logical;
        em->len = length;
@@ -5846,7 +5850,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
                map->stripes[i].dev = btrfs_find_device(root->fs_info, devid,
                                                        uuid, NULL);
                if (!map->stripes[i].dev && !btrfs_test_opt(root, DEGRADED)) {
-                       kfree(map);
                        free_extent_map(em);
                        return -EIO;
                }
@@ -5854,7 +5857,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
                        map->stripes[i].dev =
                                add_missing_dev(root, devid, uuid);
                        if (!map->stripes[i].dev) {
-                               kfree(map);
                                free_extent_map(em);
                                return -EIO;
                        }
index 1a15bbe..2aaa00c 100644 (file)
@@ -190,11 +190,14 @@ struct btrfs_bio_stripe {
 struct btrfs_bio;
 typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err);
 
+#define BTRFS_BIO_ORIG_BIO_SUBMITTED   0x1
+
 struct btrfs_bio {
        atomic_t stripes_pending;
        struct btrfs_fs_info *fs_info;
        bio_end_io_t *end_io;
        struct bio *orig_bio;
+       unsigned long flags;
        void *private;
        atomic_t error;
        int max_errors;
index 0227b45..15e9505 100644 (file)
@@ -290,7 +290,8 @@ int
 cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
                 const struct nls_table *cp, int mapChars)
 {
-       int i, j, charlen;
+       int i, charlen;
+       int j = 0;
        char src_char;
        __le16 dst_char;
        wchar_t tmp;
@@ -298,12 +299,11 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
        if (!mapChars)
                return cifs_strtoUTF16(target, source, PATH_MAX, cp);
 
-       for (i = 0, j = 0; i < srclen; j++) {
+       for (i = 0; i < srclen; j++) {
                src_char = source[i];
                charlen = 1;
                switch (src_char) {
                case 0:
-                       put_unaligned(0, &target[j]);
                        goto ctoUTF16_out;
                case ':':
                        dst_char = cpu_to_le16(UNI_COLON);
@@ -350,6 +350,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
        }
 
 ctoUTF16_out:
+       put_unaligned(0, &target[j]); /* Null terminate target unicode string */
        return j;
 }
 
index 2c90d07..8883980 100644 (file)
@@ -725,6 +725,19 @@ out_nls:
        goto out;
 }
 
+static ssize_t
+cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+       ssize_t rc;
+       struct inode *inode = file_inode(iocb->ki_filp);
+
+       rc = cifs_revalidate_mapping(inode);
+       if (rc)
+               return rc;
+
+       return generic_file_read_iter(iocb, iter);
+}
+
 static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct inode *inode = file_inode(iocb->ki_filp);
@@ -881,7 +894,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
 const struct file_operations cifs_file_ops = {
        .read = new_sync_read,
        .write = new_sync_write,
-       .read_iter = generic_file_read_iter,
+       .read_iter = cifs_loose_read_iter,
        .write_iter = cifs_file_write_iter,
        .open = cifs_open,
        .release = cifs_close,
@@ -939,7 +952,7 @@ const struct file_operations cifs_file_direct_ops = {
 const struct file_operations cifs_file_nobrl_ops = {
        .read = new_sync_read,
        .write = new_sync_write,
-       .read_iter = generic_file_read_iter,
+       .read_iter = cifs_loose_read_iter,
        .write_iter = cifs_file_write_iter,
        .open = cifs_open,
        .release = cifs_close,
index 264ece7..68559fd 100644 (file)
@@ -374,7 +374,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
        oparms.cifs_sb = cifs_sb;
        oparms.desired_access = GENERIC_WRITE;
        oparms.create_options = create_options;
-       oparms.disposition = FILE_OPEN;
+       oparms.disposition = FILE_CREATE;
        oparms.path = path;
        oparms.fid = &fid;
        oparms.reconnect = false;
index b73e062..b10b48c 100644 (file)
@@ -910,7 +910,7 @@ static const struct file_operations eventpoll_fops = {
 void eventpoll_release_file(struct file *file)
 {
        struct eventpoll *ep;
-       struct epitem *epi;
+       struct epitem *epi, *next;
 
        /*
         * We don't want to get "file->f_lock" because it is not
@@ -926,7 +926,7 @@ void eventpoll_release_file(struct file *file)
         * Besides, ep_remove() acquires the lock, so we can't hold it here.
         */
        mutex_lock(&epmutex);
-       list_for_each_entry_rcu(epi, &file->f_ep_links, fllink) {
+       list_for_each_entry_safe(epi, next, &file->f_ep_links, fllink) {
                ep = epi->ep;
                mutex_lock_nested(&ep->mtx, 0);
                ep_remove(ep, epi);
index da57c9b..717fbc4 100644 (file)
@@ -431,7 +431,7 @@ static int lease_init(struct file *filp, long type, struct file_lock *fl)
        if (assign_type(fl, type) != 0)
                return -EINVAL;
 
-       fl->fl_owner = (fl_owner_t)filp;
+       fl->fl_owner = (fl_owner_t)current->files;
        fl->fl_pid = current->tgid;
 
        fl->fl_file = filp;
index c496f8a..9927913 100644 (file)
@@ -147,6 +147,17 @@ int nfs_sync_mapping(struct address_space *mapping)
        return ret;
 }
 
+static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
+{
+       struct nfs_inode *nfsi = NFS_I(inode);
+
+       if (inode->i_mapping->nrpages == 0)
+               flags &= ~NFS_INO_INVALID_DATA;
+       nfsi->cache_validity |= flags;
+       if (flags & NFS_INO_INVALID_DATA)
+               nfs_fscache_invalidate(inode);
+}
+
 /*
  * Invalidate the local caches
  */
@@ -162,17 +173,16 @@ static void nfs_zap_caches_locked(struct inode *inode)
 
        memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf));
        if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
-               nfs_fscache_invalidate(inode);
-               nfsi->cache_validity |= NFS_INO_INVALID_ATTR
+               nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
                                        | NFS_INO_INVALID_DATA
                                        | NFS_INO_INVALID_ACCESS
                                        | NFS_INO_INVALID_ACL
-                                       | NFS_INO_REVAL_PAGECACHE;
+                                       | NFS_INO_REVAL_PAGECACHE);
        } else
-               nfsi->cache_validity |= NFS_INO_INVALID_ATTR
+               nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
                                        | NFS_INO_INVALID_ACCESS
                                        | NFS_INO_INVALID_ACL
-                                       | NFS_INO_REVAL_PAGECACHE;
+                                       | NFS_INO_REVAL_PAGECACHE);
        nfs_zap_label_cache_locked(nfsi);
 }
 
@@ -187,8 +197,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
 {
        if (mapping->nrpages != 0) {
                spin_lock(&inode->i_lock);
-               NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
-               nfs_fscache_invalidate(inode);
+               nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
                spin_unlock(&inode->i_lock);
        }
 }
@@ -209,7 +218,7 @@ EXPORT_SYMBOL_GPL(nfs_zap_acl_cache);
 void nfs_invalidate_atime(struct inode *inode)
 {
        spin_lock(&inode->i_lock);
-       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
        spin_unlock(&inode->i_lock);
 }
 EXPORT_SYMBOL_GPL(nfs_invalidate_atime);
@@ -369,7 +378,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                inode->i_mode = fattr->mode;
                if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0
                                && nfs_server_capable(inode, NFS_CAP_MODE))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                /* Why so? Because we want revalidate for devices/FIFOs, and
                 * that's precisely what we have in nfs_file_inode_operations.
                 */
@@ -415,36 +424,36 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                if (fattr->valid & NFS_ATTR_FATTR_ATIME)
                        inode->i_atime = fattr->atime;
                else if (nfs_server_capable(inode, NFS_CAP_ATIME))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                if (fattr->valid & NFS_ATTR_FATTR_MTIME)
                        inode->i_mtime = fattr->mtime;
                else if (nfs_server_capable(inode, NFS_CAP_MTIME))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                if (fattr->valid & NFS_ATTR_FATTR_CTIME)
                        inode->i_ctime = fattr->ctime;
                else if (nfs_server_capable(inode, NFS_CAP_CTIME))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
                        inode->i_version = fattr->change_attr;
                else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                if (fattr->valid & NFS_ATTR_FATTR_SIZE)
                        inode->i_size = nfs_size_to_loff_t(fattr->size);
                else
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR
-                               | NFS_INO_REVAL_PAGECACHE;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
+                               | NFS_INO_REVAL_PAGECACHE);
                if (fattr->valid & NFS_ATTR_FATTR_NLINK)
                        set_nlink(inode, fattr->nlink);
                else if (nfs_server_capable(inode, NFS_CAP_NLINK))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                if (fattr->valid & NFS_ATTR_FATTR_OWNER)
                        inode->i_uid = fattr->uid;
                else if (nfs_server_capable(inode, NFS_CAP_OWNER))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                if (fattr->valid & NFS_ATTR_FATTR_GROUP)
                        inode->i_gid = fattr->gid;
                else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
-                       nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
                if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
                        inode->i_blocks = fattr->du.nfs2.blocks;
                if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
@@ -550,6 +559,9 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset)
 
        spin_lock(&inode->i_lock);
        i_size_write(inode, offset);
+       /* Optimisation */
+       if (offset == 0)
+               NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA;
        spin_unlock(&inode->i_lock);
 
        truncate_pagecache(inode, offset);
@@ -578,7 +590,8 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
                        inode->i_uid = attr->ia_uid;
                if ((attr->ia_valid & ATTR_GID) != 0)
                        inode->i_gid = attr->ia_gid;
-               NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+               nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
+                               | NFS_INO_INVALID_ACL);
                spin_unlock(&inode->i_lock);
        }
        if ((attr->ia_valid & ATTR_SIZE) != 0) {
@@ -1101,7 +1114,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
                        && inode->i_version == fattr->pre_change_attr) {
                inode->i_version = fattr->change_attr;
                if (S_ISDIR(inode->i_mode))
-                       nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
                ret |= NFS_INO_INVALID_ATTR;
        }
        /* If we have atomic WCC data, we may update some attributes */
@@ -1117,7 +1130,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
                        && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
                memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
                if (S_ISDIR(inode->i_mode))
-                       nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
                ret |= NFS_INO_INVALID_ATTR;
        }
        if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
@@ -1128,9 +1141,6 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
                ret |= NFS_INO_INVALID_ATTR;
        }
 
-       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
-               nfs_fscache_invalidate(inode);
-
        return ret;
 }
 
@@ -1189,7 +1199,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
                invalid |= NFS_INO_INVALID_ATIME;
 
        if (invalid != 0)
-               nfsi->cache_validity |= invalid;
+               nfs_set_cache_invalid(inode, invalid);
 
        nfsi->read_cache_jiffies = fattr->time_start;
        return 0;
@@ -1402,13 +1412,11 @@ EXPORT_SYMBOL_GPL(nfs_refresh_inode);
 
 static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
 {
-       struct nfs_inode *nfsi = NFS_I(inode);
+       unsigned long invalid = NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
 
-       nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
-       if (S_ISDIR(inode->i_mode)) {
-               nfsi->cache_validity |= NFS_INO_INVALID_DATA;
-               nfs_fscache_invalidate(inode);
-       }
+       if (S_ISDIR(inode->i_mode))
+               invalid |= NFS_INO_INVALID_DATA;
+       nfs_set_cache_invalid(inode, invalid);
        if ((fattr->valid & NFS_ATTR_FATTR) == 0)
                return 0;
        return nfs_refresh_inode_locked(inode, fattr);
@@ -1601,6 +1609,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        if ((nfsi->npages == 0) || new_isize > cur_isize) {
                                i_size_write(inode, new_isize);
                                invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
+                               invalid &= ~NFS_INO_REVAL_PAGECACHE;
                        }
                        dprintk("NFS: isize change on server for file %s/%ld "
                                        "(%Ld to %Ld)\n",
@@ -1702,10 +1711,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                invalid &= ~NFS_INO_INVALID_DATA;
        if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) ||
                        (save_cache_validity & NFS_INO_REVAL_FORCED))
-               nfsi->cache_validity |= invalid;
-
-       if (invalid & NFS_INO_INVALID_DATA)
-               nfs_fscache_invalidate(inode);
+               nfs_set_cache_invalid(inode, invalid);
 
        return 0;
  out_err:
index f63cb87..ba2affa 100644 (file)
@@ -230,7 +230,7 @@ int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
 extern struct file_system_type nfs4_fs_type;
 
 /* nfs4namespace.c */
-struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
+struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *, struct qstr *);
 struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *,
                               struct nfs_fh *, struct nfs_fattr *);
 int nfs4_replace_transport(struct nfs_server *server,
index 3d5dbf8..3d83cb1 100644 (file)
@@ -139,16 +139,22 @@ static size_t nfs_parse_server_name(char *string, size_t len,
  * @server: NFS server struct
  * @flavors: List of security tuples returned by SECINFO procedure
  *
- * Return the pseudoflavor of the first security mechanism in
- * "flavors" that is locally supported.  Return RPC_AUTH_UNIX if
- * no matching flavor is found in the array.  The "flavors" array
+ * Return an rpc client that uses the first security mechanism in
+ * "flavors" that is locally supported.  The "flavors" array
  * is searched in the order returned from the server, per RFC 3530
- * recommendation.
+ * recommendation and each flavor is checked for membership in the
+ * sec= mount option list if it exists.
+ *
+ * Return -EPERM if no matching flavor is found in the array.
+ *
+ * Please call rpc_shutdown_client() when you are done with this rpc client.
+ *
  */
-static rpc_authflavor_t nfs_find_best_sec(struct nfs_server *server,
+static struct rpc_clnt *nfs_find_best_sec(struct rpc_clnt *clnt,
+                                         struct nfs_server *server,
                                          struct nfs4_secinfo_flavors *flavors)
 {
-       rpc_authflavor_t pseudoflavor;
+       rpc_authflavor_t pflavor;
        struct nfs4_secinfo4 *secinfo;
        unsigned int i;
 
@@ -159,62 +165,73 @@ static rpc_authflavor_t nfs_find_best_sec(struct nfs_server *server,
                case RPC_AUTH_NULL:
                case RPC_AUTH_UNIX:
                case RPC_AUTH_GSS:
-                       pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor,
+                       pflavor = rpcauth_get_pseudoflavor(secinfo->flavor,
                                                        &secinfo->flavor_info);
-                       /* make sure pseudoflavor matches sec= mount opt */
-                       if (pseudoflavor != RPC_AUTH_MAXFLAVOR &&
-                           nfs_auth_info_match(&server->auth_info,
-                                               pseudoflavor))
-                               return pseudoflavor;
-                       break;
+                       /* does the pseudoflavor match a sec= mount opt? */
+                       if (pflavor != RPC_AUTH_MAXFLAVOR &&
+                           nfs_auth_info_match(&server->auth_info, pflavor)) {
+                               struct rpc_clnt *new;
+                               struct rpc_cred *cred;
+
+                               /* Cloning creates an rpc_auth for the flavor */
+                               new = rpc_clone_client_set_auth(clnt, pflavor);
+                               if (IS_ERR(new))
+                                       continue;
+                               /**
+                               * Check that the user actually can use the
+                               * flavor. This is mostly for RPC_AUTH_GSS
+                               * where cr_init obtains a gss context
+                               */
+                               cred = rpcauth_lookupcred(new->cl_auth, 0);
+                               if (IS_ERR(cred)) {
+                                       rpc_shutdown_client(new);
+                                       continue;
+                               }
+                               put_rpccred(cred);
+                               return new;
+                       }
                }
        }
-
-       /* if there were any sec= options then nothing matched */
-       if (server->auth_info.flavor_len > 0)
-               return -EPERM;
-
-       return RPC_AUTH_UNIX;
+       return ERR_PTR(-EPERM);
 }
 
-static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name)
+/**
+ * nfs4_negotiate_security - in response to an NFS4ERR_WRONGSEC on lookup,
+ * return an rpc_clnt that uses the best available security flavor with
+ * respect to the secinfo flavor list and the sec= mount options.
+ *
+ * @clnt: RPC client to clone
+ * @inode: directory inode
+ * @name: lookup name
+ *
+ * Please call rpc_shutdown_client() when you are done with this rpc client.
+ */
+struct rpc_clnt *
+nfs4_negotiate_security(struct rpc_clnt *clnt, struct inode *inode,
+                                       struct qstr *name)
 {
        struct page *page;
        struct nfs4_secinfo_flavors *flavors;
-       rpc_authflavor_t flavor;
+       struct rpc_clnt *new;
        int err;
 
        page = alloc_page(GFP_KERNEL);
        if (!page)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
+
        flavors = page_address(page);
 
        err = nfs4_proc_secinfo(inode, name, flavors);
        if (err < 0) {
-               flavor = err;
+               new = ERR_PTR(err);
                goto out;
        }
 
-       flavor = nfs_find_best_sec(NFS_SERVER(inode), flavors);
+       new = nfs_find_best_sec(clnt, NFS_SERVER(inode), flavors);
 
 out:
        put_page(page);
-       return flavor;
-}
-
-/*
- * Please call rpc_shutdown_client() when you are done with this client.
- */
-struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode,
-                                       struct qstr *name)
-{
-       rpc_authflavor_t flavor;
-
-       flavor = nfs4_negotiate_security(inode, name);
-       if ((int)flavor < 0)
-               return ERR_PTR((int)flavor);
-
-       return rpc_clone_client_set_auth(clnt, flavor);
+       return new;
 }
 
 static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
@@ -397,11 +414,6 @@ struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry,
 
        if (client->cl_auth->au_flavor != flavor)
                flavor = client->cl_auth->au_flavor;
-       else {
-               rpc_authflavor_t new = nfs4_negotiate_security(dir, name);
-               if ((int)new >= 0)
-                       flavor = new;
-       }
        mnt = nfs_do_submount(dentry, fh, fattr, flavor);
 out:
        rpc_shutdown_client(client);
index 285ad53..4bf3d97 100644 (file)
@@ -3247,7 +3247,7 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
                        err = -EPERM;
                        if (client != *clnt)
                                goto out;
-                       client = nfs4_create_sec_client(client, dir, name);
+                       client = nfs4_negotiate_security(client, dir, name);
                        if (IS_ERR(client))
                                return PTR_ERR(client);
 
index 3ee5af4..98ff061 100644 (file)
@@ -934,12 +934,14 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode)
 
        if (nfs_have_delegated_attributes(inode))
                goto out;
-       if (nfsi->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE))
+       if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
                return false;
        smp_rmb();
        if (test_bit(NFS_INO_INVALIDATING, &nfsi->flags))
                return false;
 out:
+       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+               return false;
        return PageUptodate(page) != 0;
 }
 
index c0d45ce..2204e1f 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/ratelimit.h>
 #include <linux/sunrpc/svcauth_gss.h>
 #include <linux/sunrpc/addr.h>
+#include <linux/hash.h>
 #include "xdr4.h"
 #include "xdr4cb.h"
 #include "vfs.h"
@@ -364,6 +365,79 @@ static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
        return openlockstateid(nfs4_alloc_stid(clp, stateid_slab));
 }
 
+/*
+ * When we recall a delegation, we should be careful not to hand it
+ * out again straight away.
+ * To ensure this we keep a pair of bloom filters ('new' and 'old')
+ * in which the filehandles of recalled delegations are "stored".
+ * If a filehandle appear in either filter, a delegation is blocked.
+ * When a delegation is recalled, the filehandle is stored in the "new"
+ * filter.
+ * Every 30 seconds we swap the filters and clear the "new" one,
+ * unless both are empty of course.
+ *
+ * Each filter is 256 bits.  We hash the filehandle to 32bit and use the
+ * low 3 bytes as hash-table indices.
+ *
+ * 'state_lock', which is always held when block_delegations() is called,
+ * is used to manage concurrent access.  Testing does not need the lock
+ * except when swapping the two filters.
+ */
+static struct bloom_pair {
+       int     entries, old_entries;
+       time_t  swap_time;
+       int     new; /* index into 'set' */
+       DECLARE_BITMAP(set[2], 256);
+} blocked_delegations;
+
+static int delegation_blocked(struct knfsd_fh *fh)
+{
+       u32 hash;
+       struct bloom_pair *bd = &blocked_delegations;
+
+       if (bd->entries == 0)
+               return 0;
+       if (seconds_since_boot() - bd->swap_time > 30) {
+               spin_lock(&state_lock);
+               if (seconds_since_boot() - bd->swap_time > 30) {
+                       bd->entries -= bd->old_entries;
+                       bd->old_entries = bd->entries;
+                       memset(bd->set[bd->new], 0,
+                              sizeof(bd->set[0]));
+                       bd->new = 1-bd->new;
+                       bd->swap_time = seconds_since_boot();
+               }
+               spin_unlock(&state_lock);
+       }
+       hash = arch_fast_hash(&fh->fh_base, fh->fh_size, 0);
+       if (test_bit(hash&255, bd->set[0]) &&
+           test_bit((hash>>8)&255, bd->set[0]) &&
+           test_bit((hash>>16)&255, bd->set[0]))
+               return 1;
+
+       if (test_bit(hash&255, bd->set[1]) &&
+           test_bit((hash>>8)&255, bd->set[1]) &&
+           test_bit((hash>>16)&255, bd->set[1]))
+               return 1;
+
+       return 0;
+}
+
+static void block_delegations(struct knfsd_fh *fh)
+{
+       u32 hash;
+       struct bloom_pair *bd = &blocked_delegations;
+
+       hash = arch_fast_hash(&fh->fh_base, fh->fh_size, 0);
+
+       __set_bit(hash&255, bd->set[bd->new]);
+       __set_bit((hash>>8)&255, bd->set[bd->new]);
+       __set_bit((hash>>16)&255, bd->set[bd->new]);
+       if (bd->entries == 0)
+               bd->swap_time = seconds_since_boot();
+       bd->entries += 1;
+}
+
 static struct nfs4_delegation *
 alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh)
 {
@@ -372,6 +446,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
        dprintk("NFSD alloc_init_deleg\n");
        if (num_delegations > max_delegations)
                return NULL;
+       if (delegation_blocked(&current_fh->fh_handle))
+               return NULL;
        dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
        if (dp == NULL)
                return dp;
@@ -2770,6 +2846,8 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
        /* Only place dl_time is set; protected by i_lock: */
        dp->dl_time = get_seconds();
 
+       block_delegations(&dp->dl_fh);
+
        nfsd4_cb_recall(dp);
 }
 
index 2d305a1..83baf2b 100644 (file)
@@ -2687,6 +2687,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
                nfserr = nfserr_toosmall;
                goto fail;
        case nfserr_noent:
+               xdr_truncate_encode(xdr, start_offset);
                goto skip_entry;
        default:
                /*
index a106b3f..fae17c6 100644 (file)
@@ -331,6 +331,7 @@ struct dlm_lock_resource
        u16 state;
        char lvb[DLM_LVB_LEN];
        unsigned int inflight_locks;
+       unsigned int inflight_assert_workers;
        unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
 };
 
@@ -910,6 +911,9 @@ void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
 void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
                                   struct dlm_lock_resource *res);
 
+void __dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm,
+               struct dlm_lock_resource *res);
+
 void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
index 3087a21..82abf0c 100644 (file)
@@ -581,6 +581,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
        atomic_set(&res->asts_reserved, 0);
        res->migration_pending = 0;
        res->inflight_locks = 0;
+       res->inflight_assert_workers = 0;
 
        res->dlm = dlm;
 
@@ -683,6 +684,43 @@ void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
        wake_up(&res->wq);
 }
 
+void __dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm,
+               struct dlm_lock_resource *res)
+{
+       assert_spin_locked(&res->spinlock);
+       res->inflight_assert_workers++;
+       mlog(0, "%s:%.*s: inflight assert worker++: now %u\n",
+                       dlm->name, res->lockname.len, res->lockname.name,
+                       res->inflight_assert_workers);
+}
+
+static void dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm,
+               struct dlm_lock_resource *res)
+{
+       spin_lock(&res->spinlock);
+       __dlm_lockres_grab_inflight_worker(dlm, res);
+       spin_unlock(&res->spinlock);
+}
+
+static void __dlm_lockres_drop_inflight_worker(struct dlm_ctxt *dlm,
+               struct dlm_lock_resource *res)
+{
+       assert_spin_locked(&res->spinlock);
+       BUG_ON(res->inflight_assert_workers == 0);
+       res->inflight_assert_workers--;
+       mlog(0, "%s:%.*s: inflight assert worker--: now %u\n",
+                       dlm->name, res->lockname.len, res->lockname.name,
+                       res->inflight_assert_workers);
+}
+
+static void dlm_lockres_drop_inflight_worker(struct dlm_ctxt *dlm,
+               struct dlm_lock_resource *res)
+{
+       spin_lock(&res->spinlock);
+       __dlm_lockres_drop_inflight_worker(dlm, res);
+       spin_unlock(&res->spinlock);
+}
+
 /*
  * lookup a lock resource by name.
  * may already exist in the hashtable.
@@ -1603,7 +1641,8 @@ send_response:
                        mlog(ML_ERROR, "failed to dispatch assert master work\n");
                        response = DLM_MASTER_RESP_ERROR;
                        dlm_lockres_put(res);
-               }
+               } else
+                       dlm_lockres_grab_inflight_worker(dlm, res);
        } else {
                if (res)
                        dlm_lockres_put(res);
@@ -2118,6 +2157,8 @@ static void dlm_assert_master_worker(struct dlm_work_item *item, void *data)
        dlm_lockres_release_ast(dlm, res);
 
 put:
+       dlm_lockres_drop_inflight_worker(dlm, res);
+
        dlm_lockres_put(res);
 
        mlog(0, "finished with dlm_assert_master_worker\n");
@@ -3088,11 +3129,15 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm,
                        /* remove it so that only one mle will be found */
                        __dlm_unlink_mle(dlm, tmp);
                        __dlm_mle_detach_hb_events(dlm, tmp);
-                       ret = DLM_MIGRATE_RESPONSE_MASTERY_REF;
-                       mlog(0, "%s:%.*s: master=%u, newmaster=%u, "
-                           "telling master to get ref for cleared out mle "
-                           "during migration\n", dlm->name, namelen, name,
-                           master, new_master);
+                       if (tmp->type == DLM_MLE_MASTER) {
+                               ret = DLM_MIGRATE_RESPONSE_MASTERY_REF;
+                               mlog(0, "%s:%.*s: master=%u, newmaster=%u, "
+                                               "telling master to get ref "
+                                               "for cleared out mle during "
+                                               "migration\n", dlm->name,
+                                               namelen, name, master,
+                                               new_master);
+                       }
                }
                spin_unlock(&tmp->spinlock);
        }
index 5de0194..45067fa 100644 (file)
@@ -1708,7 +1708,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
                                mlog_errno(-ENOMEM);
                                /* retry!? */
                                BUG();
-                       }
+                       } else
+                               __dlm_lockres_grab_inflight_worker(dlm, res);
                } else /* put.. incase we are not the master */
                        dlm_lockres_put(res);
                spin_unlock(&res->spinlock);
index 9db869d..69aac6f 100644 (file)
@@ -259,12 +259,15 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm,
                 * refs on it. */
                unused = __dlm_lockres_unused(lockres);
                if (!unused ||
-                   (lockres->state & DLM_LOCK_RES_MIGRATING)) {
+                   (lockres->state & DLM_LOCK_RES_MIGRATING) ||
+                   (lockres->inflight_assert_workers != 0)) {
                        mlog(0, "%s: res %.*s is in use or being remastered, "
-                            "used %d, state %d\n", dlm->name,
-                            lockres->lockname.len, lockres->lockname.name,
-                            !unused, lockres->state);
-                       list_move_tail(&dlm->purge_list, &lockres->purge);
+                            "used %d, state %d, assert master workers %u\n",
+                            dlm->name, lockres->lockname.len,
+                            lockres->lockname.name,
+                            !unused, lockres->state,
+                            lockres->inflight_assert_workers);
+                       list_move_tail(&lockres->purge, &dlm->purge_list);
                        spin_unlock(&lockres->spinlock);
                        continue;
                }
index 5698b52..2e3c9db 100644 (file)
@@ -191,7 +191,9 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
                                     DLM_UNLOCK_CLEAR_CONVERT_TYPE);
                } else if (status == DLM_RECOVERING ||
                           status == DLM_MIGRATING ||
-                          status == DLM_FORWARD) {
+                          status == DLM_FORWARD ||
+                          status == DLM_NOLOCKMGR
+                          ) {
                        /* must clear the actions because this unlock
                         * is about to be retried.  cannot free or do
                         * any list manipulation. */
@@ -200,7 +202,8 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
                             res->lockname.name,
                             status==DLM_RECOVERING?"recovering":
                             (status==DLM_MIGRATING?"migrating":
-                             "forward"));
+                               (status == DLM_FORWARD ? "forward" :
+                                               "nolockmanager")));
                        actions = 0;
                }
                if (flags & LKM_CANCEL)
@@ -364,7 +367,10 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm,
                         * updated state to the recovery master.  this thread
                         * just needs to finish out the operation and call
                         * the unlockast. */
-                       ret = DLM_NORMAL;
+                       if (dlm_is_node_dead(dlm, owner))
+                               ret = DLM_NORMAL;
+                       else
+                               ret = DLM_NOLOCKMGR;
                } else {
                        /* something bad.  this will BUG in ocfs2 */
                        ret = dlm_err_to_dlm_status(tmpret);
@@ -638,7 +644,9 @@ retry:
 
        if (status == DLM_RECOVERING ||
            status == DLM_MIGRATING ||
-           status == DLM_FORWARD) {
+           status == DLM_FORWARD ||
+           status == DLM_NOLOCKMGR) {
+
                /* We want to go away for a tiny bit to allow recovery
                 * / migration to complete on this resource. I don't
                 * know of any wait queue we could sleep on as this
@@ -650,7 +658,7 @@ retry:
                msleep(50);
 
                mlog(0, "retrying unlock due to pending recovery/"
-                    "migration/in-progress\n");
+                    "migration/in-progress/reconnect\n");
                goto retry;
        }
 
index 2060fc3..8add6f1 100644 (file)
@@ -205,6 +205,21 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, umode_t mode)
        return inode;
 }
 
+static void ocfs2_cleanup_add_entry_failure(struct ocfs2_super *osb,
+               struct dentry *dentry, struct inode *inode)
+{
+       struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
+
+       ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
+       ocfs2_lock_res_free(&dl->dl_lockres);
+       BUG_ON(dl->dl_count != 1);
+       spin_lock(&dentry_attach_lock);
+       dentry->d_fsdata = NULL;
+       spin_unlock(&dentry_attach_lock);
+       kfree(dl);
+       iput(inode);
+}
+
 static int ocfs2_mknod(struct inode *dir,
                       struct dentry *dentry,
                       umode_t mode,
@@ -231,6 +246,7 @@ static int ocfs2_mknod(struct inode *dir,
        sigset_t oldset;
        int did_block_signals = 0;
        struct posix_acl *default_acl = NULL, *acl = NULL;
+       struct ocfs2_dentry_lock *dl = NULL;
 
        trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name,
                          (unsigned long long)OCFS2_I(dir)->ip_blkno,
@@ -423,6 +439,8 @@ static int ocfs2_mknod(struct inode *dir,
                goto leave;
        }
 
+       dl = dentry->d_fsdata;
+
        status = ocfs2_add_entry(handle, dentry, inode,
                                 OCFS2_I(inode)->ip_blkno, parent_fe_bh,
                                 &lookup);
@@ -469,6 +487,9 @@ leave:
         * ocfs2_delete_inode will mutex_lock again.
         */
        if ((status < 0) && inode) {
+               if (dl)
+                       ocfs2_cleanup_add_entry_failure(osb, dentry, inode);
+
                OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
                clear_nlink(inode);
                iput(inode);
@@ -991,6 +1012,65 @@ leave:
        return status;
 }
 
+static int ocfs2_check_if_ancestor(struct ocfs2_super *osb,
+               u64 src_inode_no, u64 dest_inode_no)
+{
+       int ret = 0, i = 0;
+       u64 parent_inode_no = 0;
+       u64 child_inode_no = src_inode_no;
+       struct inode *child_inode;
+
+#define MAX_LOOKUP_TIMES 32
+       while (1) {
+               child_inode = ocfs2_iget(osb, child_inode_no, 0, 0);
+               if (IS_ERR(child_inode)) {
+                       ret = PTR_ERR(child_inode);
+                       break;
+               }
+
+               ret = ocfs2_inode_lock(child_inode, NULL, 0);
+               if (ret < 0) {
+                       iput(child_inode);
+                       if (ret != -ENOENT)
+                               mlog_errno(ret);
+                       break;
+               }
+
+               ret = ocfs2_lookup_ino_from_name(child_inode, "..", 2,
+                               &parent_inode_no);
+               ocfs2_inode_unlock(child_inode, 0);
+               iput(child_inode);
+               if (ret < 0) {
+                       ret = -ENOENT;
+                       break;
+               }
+
+               if (parent_inode_no == dest_inode_no) {
+                       ret = 1;
+                       break;
+               }
+
+               if (parent_inode_no == osb->root_inode->i_ino) {
+                       ret = 0;
+                       break;
+               }
+
+               child_inode_no = parent_inode_no;
+
+               if (++i >= MAX_LOOKUP_TIMES) {
+                       mlog(ML_NOTICE, "max lookup times reached, filesystem "
+                                       "may have nested directories, "
+                                       "src inode: %llu, dest inode: %llu.\n",
+                                       (unsigned long long)src_inode_no,
+                                       (unsigned long long)dest_inode_no);
+                       ret = 0;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
 /*
  * The only place this should be used is rename!
  * if they have the same id, then the 1st one is the only one locked.
@@ -1002,6 +1082,7 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
                             struct inode *inode2)
 {
        int status;
+       int inode1_is_ancestor, inode2_is_ancestor;
        struct ocfs2_inode_info *oi1 = OCFS2_I(inode1);
        struct ocfs2_inode_info *oi2 = OCFS2_I(inode2);
        struct buffer_head **tmpbh;
@@ -1015,9 +1096,26 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
        if (*bh2)
                *bh2 = NULL;
 
-       /* we always want to lock the one with the lower lockid first. */
+       /* we always want to lock the one with the lower lockid first.
+        * and if they are nested, we lock ancestor first */
        if (oi1->ip_blkno != oi2->ip_blkno) {
-               if (oi1->ip_blkno < oi2->ip_blkno) {
+               inode1_is_ancestor = ocfs2_check_if_ancestor(osb, oi2->ip_blkno,
+                               oi1->ip_blkno);
+               if (inode1_is_ancestor < 0) {
+                       status = inode1_is_ancestor;
+                       goto bail;
+               }
+
+               inode2_is_ancestor = ocfs2_check_if_ancestor(osb, oi1->ip_blkno,
+                               oi2->ip_blkno);
+               if (inode2_is_ancestor < 0) {
+                       status = inode2_is_ancestor;
+                       goto bail;
+               }
+
+               if ((inode1_is_ancestor == 1) ||
+                               (oi1->ip_blkno < oi2->ip_blkno &&
+                               inode2_is_ancestor == 0)) {
                        /* switch id1 and id2 around */
                        tmpbh = bh2;
                        bh2 = bh1;
@@ -1098,6 +1196,7 @@ static int ocfs2_rename(struct inode *old_dir,
        struct ocfs2_dir_lookup_result old_entry_lookup = { NULL, };
        struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
        struct ocfs2_dir_lookup_result target_insert = { NULL, };
+       bool should_add_orphan = false;
 
        /* At some point it might be nice to break this function up a
         * bit. */
@@ -1134,6 +1233,21 @@ static int ocfs2_rename(struct inode *old_dir,
                        goto bail;
                }
                rename_lock = 1;
+
+               /* here we cannot guarantee the inodes haven't just been
+                * changed, so check if they are nested again */
+               status = ocfs2_check_if_ancestor(osb, new_dir->i_ino,
+                               old_inode->i_ino);
+               if (status < 0) {
+                       mlog_errno(status);
+                       goto bail;
+               } else if (status == 1) {
+                       status = -EPERM;
+                       trace_ocfs2_rename_not_permitted(
+                                       (unsigned long long)old_inode->i_ino,
+                                       (unsigned long long)new_dir->i_ino);
+                       goto bail;
+               }
        }
 
        /* if old and new are the same, this'll just do one lock. */
@@ -1304,6 +1418,7 @@ static int ocfs2_rename(struct inode *old_dir,
                                mlog_errno(status);
                                goto bail;
                        }
+                       should_add_orphan = true;
                }
        } else {
                BUG_ON(new_dentry->d_parent->d_inode != new_dir);
@@ -1348,17 +1463,6 @@ static int ocfs2_rename(struct inode *old_dir,
                        goto bail;
                }
 
-               if (S_ISDIR(new_inode->i_mode) ||
-                   (ocfs2_read_links_count(newfe) == 1)) {
-                       status = ocfs2_orphan_add(osb, handle, new_inode,
-                                                 newfe_bh, orphan_name,
-                                                 &orphan_insert, orphan_dir);
-                       if (status < 0) {
-                               mlog_errno(status);
-                               goto bail;
-                       }
-               }
-
                /* change the dirent to point to the correct inode */
                status = ocfs2_update_entry(new_dir, handle, &target_lookup_res,
                                            old_inode);
@@ -1373,6 +1477,15 @@ static int ocfs2_rename(struct inode *old_dir,
                else
                        ocfs2_add_links_count(newfe, -1);
                ocfs2_journal_dirty(handle, newfe_bh);
+               if (should_add_orphan) {
+                       status = ocfs2_orphan_add(osb, handle, new_inode,
+                                       newfe_bh, orphan_name,
+                                       &orphan_insert, orphan_dir);
+                       if (status < 0) {
+                               mlog_errno(status);
+                               goto bail;
+                       }
+               }
        } else {
                /* if the name was not found in new_dir, add it now */
                status = ocfs2_add_entry(handle, new_dentry, old_inode,
@@ -1642,6 +1755,7 @@ static int ocfs2_symlink(struct inode *dir,
        struct ocfs2_dir_lookup_result lookup = { NULL, };
        sigset_t oldset;
        int did_block_signals = 0;
+       struct ocfs2_dentry_lock *dl = NULL;
 
        trace_ocfs2_symlink_begin(dir, dentry, symname,
                                  dentry->d_name.len, dentry->d_name.name);
@@ -1830,6 +1944,8 @@ static int ocfs2_symlink(struct inode *dir,
                goto bail;
        }
 
+       dl = dentry->d_fsdata;
+
        status = ocfs2_add_entry(handle, dentry, inode,
                                 le64_to_cpu(fe->i_blkno), parent_fe_bh,
                                 &lookup);
@@ -1864,6 +1980,9 @@ bail:
        if (xattr_ac)
                ocfs2_free_alloc_context(xattr_ac);
        if ((status < 0) && inode) {
+               if (dl)
+                       ocfs2_cleanup_add_entry_failure(osb, dentry, inode);
+
                OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
                clear_nlink(inode);
                iput(inode);
index 1b60c62..6cb019b 100644 (file)
@@ -2292,6 +2292,8 @@ TRACE_EVENT(ocfs2_rename,
                  __entry->new_len, __get_str(new_name))
 );
 
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_rename_not_permitted);
+
 TRACE_EVENT(ocfs2_rename_target_exists,
        TP_PROTO(int new_len, const char *new_name),
        TP_ARGS(new_len, new_name),
index 714e53b..636aab6 100644 (file)
@@ -4288,9 +4288,16 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir,
                goto out;
        }
 
+       error = ocfs2_rw_lock(inode, 1);
+       if (error) {
+               mlog_errno(error);
+               goto out;
+       }
+
        error = ocfs2_inode_lock(inode, &old_bh, 1);
        if (error) {
                mlog_errno(error);
+               ocfs2_rw_unlock(inode, 1);
                goto out;
        }
 
@@ -4302,6 +4309,7 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir,
        up_write(&OCFS2_I(inode)->ip_xattr_sem);
 
        ocfs2_inode_unlock(inode, 1);
+       ocfs2_rw_unlock(inode, 1);
        brelse(old_bh);
 
        if (error) {
index c7a89ce..ddb662b 100644 (file)
@@ -1925,15 +1925,11 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
 
        ocfs2_shutdown_local_alloc(osb);
 
+       ocfs2_truncate_log_shutdown(osb);
+
        /* This will disable recovery and flush any recovery work. */
        ocfs2_recovery_exit(osb);
 
-       /*
-        * During dismount, when it recovers another node it will call
-        * ocfs2_recover_orphans and queue delayed work osb_truncate_log_wq.
-        */
-       ocfs2_truncate_log_shutdown(osb);
-
        ocfs2_journal_shutdown(osb);
 
        ocfs2_sync_blockdev(sb);
index 6eb1d3c..9b9b6f2 100644 (file)
@@ -53,7 +53,7 @@ struct acpi_power_register {
        u8 bit_offset;
        u8 access_size;
        u64 address;
-} __attribute__ ((packed));
+} __packed;
 
 struct acpi_processor_cx {
        u8 valid;
@@ -83,7 +83,7 @@ struct acpi_psd_package {
        u64 domain;
        u64 coord_type;
        u64 num_processors;
-} __attribute__ ((packed));
+} __packed;
 
 struct acpi_pct_register {
        u8 descriptor;
@@ -93,7 +93,7 @@ struct acpi_pct_register {
        u8 bit_offset;
        u8 reserved;
        u64 address;
-} __attribute__ ((packed));
+} __packed;
 
 struct acpi_processor_px {
        u64 core_frequency;     /* megahertz */
@@ -124,7 +124,7 @@ struct acpi_tsd_package {
        u64 domain;
        u64 coord_type;
        u64 num_processors;
-} __attribute__ ((packed));
+} __packed;
 
 struct acpi_ptc_register {
        u8 descriptor;
@@ -134,7 +134,7 @@ struct acpi_ptc_register {
        u8 bit_offset;
        u8 reserved;
        u64 address;
-} __attribute__ ((packed));
+} __packed;
 
 struct acpi_processor_tx_tss {
        u64 freqpercentage;     /* */
index 0572035..a70d456 100644 (file)
 #define INTEL_BDW_GT3D_IDS(info) \
        _INTEL_BDW_D_IDS(3, info)
 
+#define INTEL_BDW_RSVDM_IDS(info) \
+       _INTEL_BDW_M_IDS(4, info)
+
+#define INTEL_BDW_RSVDD_IDS(info) \
+       _INTEL_BDW_D_IDS(4, info)
+
 #define INTEL_BDW_M_IDS(info) \
        INTEL_BDW_GT12M_IDS(info), \
-       INTEL_BDW_GT3M_IDS(info)
+       INTEL_BDW_GT3M_IDS(info), \
+       INTEL_BDW_RSVDM_IDS(info)
 
 #define INTEL_BDW_D_IDS(info) \
        INTEL_BDW_GT12D_IDS(info), \
-       INTEL_BDW_GT3D_IDS(info)
+       INTEL_BDW_GT3D_IDS(info), \
+       INTEL_BDW_RSVDD_IDS(info)
 
 #define INTEL_CHV_IDS(info) \
        INTEL_VGA_DEVICE(0x22b0, info), \
index cfdc884..2baba99 100644 (file)
@@ -30,7 +30,7 @@
 #define _I915_POWERWELL_H_
 
 /* For use by hda_i915 driver */
-extern void i915_request_power_well(void);
-extern void i915_release_power_well(void);
+extern int i915_request_power_well(void);
+extern int i915_release_power_well(void);
 
 #endif                         /* _I915_POWERWELL_H_ */
index 7cf5c99..b91dd46 100644 (file)
 #define IMX6SL_CLK_USDHC4              132
 #define IMX6SL_CLK_PLL4_AUDIO_DIV      133
 #define IMX6SL_CLK_SPBA                        134
-#define IMX6SL_CLK_END                 135
+#define IMX6SL_CLK_ENET                        135
+#define IMX6SL_CLK_END                 136
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
index 0d2c739..d80caa6 100644 (file)
@@ -10,6 +10,7 @@
 #define CLK_ETH1_PHY           4
 
 /* CLOCKGEN A1 */
+#define CLK_ICN_IF_2           0
 #define CLK_GMAC0_PHY          3
 
 #endif
index 552c779..f9bdbd1 100644 (file)
@@ -10,6 +10,7 @@
 #define CLK_ETH1_PHY           4
 
 /* CLOCKGEN A1 */
+#define CLK_ICN_IF_2           0
 #define CLK_GMAC0_PHY          3
 
 #endif
diff --git a/include/linux/atmel-pwm-bl.h b/include/linux/atmel-pwm-bl.h
deleted file mode 100644 (file)
index 0153a47..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2007 Atmel Corporation
- *
- * Driver for the AT32AP700X PS/2 controller (PSIF).
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef __INCLUDE_ATMEL_PWM_BL_H
-#define __INCLUDE_ATMEL_PWM_BL_H
-
-/**
- * struct atmel_pwm_bl_platform_data
- * @pwm_channel: which PWM channel in the PWM module to use.
- * @pwm_frequency: PWM frequency to generate, the driver will try to be as
- *     close as the prescaler allows.
- * @pwm_compare_max: value to use in the PWM channel compare register.
- * @pwm_duty_max: maximum duty cycle value, must be less than or equal to
- *     pwm_compare_max.
- * @pwm_duty_min: minimum duty cycle value, must be less than pwm_duty_max.
- * @pwm_active_low: set to one if the low part of the PWM signal increases the
- *     brightness of the backlight.
- * @gpio_on: GPIO line to control the backlight on/off, set to -1 if not used.
- * @on_active_low: set to one if the on/off signal is on when GPIO is low.
- *
- * This struct must be added to the platform device in the board code. It is
- * used by the atmel-pwm-bl driver to setup the GPIO to control on/off and the
- * PWM device.
- */
-struct atmel_pwm_bl_platform_data {
-       unsigned int pwm_channel;
-       unsigned int pwm_frequency;
-       unsigned int pwm_compare_max;
-       unsigned int pwm_duty_max;
-       unsigned int pwm_duty_min;
-       unsigned int pwm_active_low;
-       int gpio_on;
-       unsigned int on_active_low;
-};
-
-#endif /* __INCLUDE_ATMEL_PWM_BL_H */
diff --git a/include/linux/atmel_pwm.h b/include/linux/atmel_pwm.h
deleted file mode 100644 (file)
index ea04abb..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef __LINUX_ATMEL_PWM_H
-#define __LINUX_ATMEL_PWM_H
-
-/**
- * struct pwm_channel - driver handle to a PWM channel
- * @regs: base of this channel's registers
- * @index: number of this channel (0..31)
- * @mck: base clock rate, which can be prescaled and maybe subdivided
- *
- * Drivers initialize a pwm_channel structure using pwm_channel_alloc().
- * Then they configure its clock rate (derived from MCK), alignment,
- * polarity, and duty cycle by writing directly to the channel registers,
- * before enabling the channel by calling pwm_channel_enable().
- *
- * After emitting a PWM signal for the desired length of time, drivers
- * may then pwm_channel_disable() or pwm_channel_free().  Both of these
- * disable the channel, but when it's freed the IRQ is deconfigured and
- * the channel must later be re-allocated and reconfigured.
- *
- * Note that if the period or duty cycle need to be changed while the
- * PWM channel is operating, drivers must use the PWM_CUPD double buffer
- * mechanism, either polling until they change or getting implicitly
- * notified through a once-per-period interrupt handler.
- */
-struct pwm_channel {
-       void __iomem    *regs;
-       unsigned        index;
-       unsigned long   mck;
-};
-
-extern int pwm_channel_alloc(int index, struct pwm_channel *ch);
-extern int pwm_channel_free(struct pwm_channel *ch);
-
-extern int pwm_clk_alloc(unsigned prescale, unsigned div);
-extern void pwm_clk_free(unsigned clk);
-
-extern int __pwm_channel_onoff(struct pwm_channel *ch, int enabled);
-
-#define pwm_channel_enable(ch) __pwm_channel_onoff((ch), 1)
-#define pwm_channel_disable(ch)        __pwm_channel_onoff((ch), 0)
-
-/* periodic interrupts, mostly for CUPD changes to period or cycle */
-extern int pwm_channel_handler(struct pwm_channel *ch,
-               void (*handler)(struct pwm_channel *ch));
-
-/* per-channel registers (banked at pwm_channel->regs) */
-#define PWM_CMR                0x00            /* mode register */
-#define                PWM_CPR_CPD     (1 << 10)       /* set: CUPD modifies period */
-#define                PWM_CPR_CPOL    (1 << 9)        /* set: idle high */
-#define                PWM_CPR_CALG    (1 << 8)        /* set: center align */
-#define                PWM_CPR_CPRE    (0xf << 0)      /* mask: rate is mck/(2^pre) */
-#define                PWM_CPR_CLKA    (0xb << 0)      /* rate CLKA */
-#define                PWM_CPR_CLKB    (0xc << 0)      /* rate CLKB */
-#define PWM_CDTY       0x04            /* duty cycle (max of CPRD) */
-#define PWM_CPRD       0x08            /* period (count up from zero) */
-#define PWM_CCNT       0x0c            /* counter (20 bits?) */
-#define PWM_CUPD       0x10            /* update CPRD (or CDTY) next period */
-
-static inline void
-pwm_channel_writel(struct pwm_channel *pwmc, unsigned offset, u32 val)
-{
-       __raw_writel(val, pwmc->regs + offset);
-}
-
-static inline u32 pwm_channel_readl(struct pwm_channel *pwmc, unsigned offset)
-{
-       return __raw_readl(pwmc->regs + offset);
-}
-
-#endif /* __LINUX_ATMEL_PWM_H */
index 5a64576..d2633ee 100644 (file)
@@ -186,6 +186,15 @@ static inline void *bio_data(struct bio *bio)
 #define BIOVEC_SEG_BOUNDARY(q, b1, b2) \
        __BIO_SEG_BOUNDARY(bvec_to_phys((b1)), bvec_to_phys((b2)) + (b2)->bv_len, queue_segment_boundary((q)))
 
+/*
+ * Check if adding a bio_vec after bprv with offset would create a gap in
+ * the SG list. Most drivers don't care about this, but some do.
+ */
+static inline bool bvec_gap_to_prev(struct bio_vec *bprv, unsigned int offset)
+{
+       return offset || ((bprv->bv_offset + bprv->bv_len) & (PAGE_SIZE - 1));
+}
+
 #define bio_io_error(bio) bio_endio((bio), -EIO)
 
 /*
@@ -644,10 +653,6 @@ struct biovec_slab {
 
 #if defined(CONFIG_BLK_DEV_INTEGRITY)
 
-
-
-#define bip_vec_idx(bip, idx)  (&(bip->bip_vec[(idx)]))
-
 #define bip_for_each_vec(bvl, bip, iter)                               \
        for_each_bvec(bvl, (bip)->bip_vec, iter, (bip)->bip_iter)
 
index a002cf1..eb726b9 100644 (file)
@@ -42,7 +42,7 @@ struct blk_mq_hw_ctx {
        unsigned int            nr_ctx;
        struct blk_mq_ctx       **ctxs;
 
-       unsigned int            wait_index;
+       atomic_t                wait_index;
 
        struct blk_mq_tags      *tags;
 
index 31e1105..8699bcf 100644 (file)
@@ -512,6 +512,7 @@ struct request_queue {
 #define QUEUE_FLAG_DEAD        19      /* queue tear-down finished */
 #define QUEUE_FLAG_INIT_DONE   20      /* queue is initialized */
 #define QUEUE_FLAG_NO_SG_MERGE 21      /* don't attempt to merge SG segments*/
+#define QUEUE_FLAG_SG_GAPS     22      /* queue doesn't support SG gaps */
 
 #define QUEUE_FLAG_DEFAULT     ((1 << QUEUE_FLAG_IO_STAT) |            \
                                 (1 << QUEUE_FLAG_STACKABLE)    |       \
@@ -920,7 +921,7 @@ static inline unsigned int blk_max_size_offset(struct request_queue *q,
                                               sector_t offset)
 {
        if (!q->limits.chunk_sectors)
-               return q->limits.max_hw_sectors;
+               return q->limits.max_sectors;
 
        return q->limits.chunk_sectors -
                        (offset & (q->limits.chunk_sectors - 1));
index 4ff262e..45a9147 100644 (file)
@@ -133,7 +133,6 @@ extern struct request *elv_latter_request(struct request_queue *, struct request
 extern int elv_register_queue(struct request_queue *q);
 extern void elv_unregister_queue(struct request_queue *q);
 extern int elv_may_queue(struct request_queue *, int);
-extern void elv_abort_queue(struct request_queue *);
 extern void elv_completed_request(struct request_queue *, struct request *);
 extern int elv_set_request(struct request_queue *q, struct request *rq,
                           struct bio *bio, gfp_t gfp_mask);
@@ -144,7 +143,7 @@ extern void elv_drain_elevator(struct request_queue *);
  * io scheduler registration
  */
 extern void __init load_default_elevator_module(void);
-extern int __init elv_register(struct elevator_type *);
+extern int elv_register(struct elevator_type *);
 extern void elv_unregister(struct elevator_type *);
 
 /*
index 338e6f7..e11d60c 100644 (file)
@@ -1921,6 +1921,12 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
 
 static inline int break_deleg(struct inode *inode, unsigned int mode)
 {
+       /*
+        * Since this check is lockless, we must ensure that any refcounts
+        * taken are done before checking inode->i_flock. Otherwise, we could
+        * end up racing with tasks trying to set a new lease on this file.
+        */
+       smp_mb();
        if (inode->i_flock)
                return __break_lease(inode, mode, FL_DELEG);
        return 0;
index 6a45fb5..447775e 100644 (file)
@@ -32,15 +32,24 @@ static inline void touch_nmi_watchdog(void)
 #ifdef arch_trigger_all_cpu_backtrace
 static inline bool trigger_all_cpu_backtrace(void)
 {
-       arch_trigger_all_cpu_backtrace();
+       arch_trigger_all_cpu_backtrace(true);
 
        return true;
 }
+static inline bool trigger_allbutself_cpu_backtrace(void)
+{
+       arch_trigger_all_cpu_backtrace(false);
+       return true;
+}
 #else
 static inline bool trigger_all_cpu_backtrace(void)
 {
        return false;
 }
+static inline bool trigger_allbutself_cpu_backtrace(void)
+{
+       return false;
+}
 #endif
 
 #ifdef CONFIG_LOCKUP_DETECTOR
@@ -48,6 +57,7 @@ int hw_nmi_is_cpu_stuck(struct pt_regs *);
 u64 hw_nmi_get_sample_period(int watchdog_thresh);
 extern int watchdog_user_enabled;
 extern int watchdog_thresh;
+extern int sysctl_softlockup_all_cpu_backtrace;
 struct ctl_table;
 extern int proc_dowatchdog(struct ctl_table *, int ,
                           void __user *, size_t *, loff_t *);
index 3c545b4..8304959 100644 (file)
@@ -360,6 +360,9 @@ static inline void ClearPageCompound(struct page *page)
        ClearPageHead(page);
 }
 #endif
+
+#define PG_head_mask ((1L << PG_head))
+
 #else
 /*
  * Reduce page flag use as much as possible by overlapping
index 864ddaf..6804144 100644 (file)
@@ -536,6 +536,15 @@ struct phy_driver {
        /* See set_wol, but for checking whether Wake on LAN is enabled. */
        void (*get_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol);
 
+       /*
+        * Called to inform a PHY device driver when the core is about to
+        * change the link state. This callback is supposed to be used as
+        * fixup hook for drivers that need to take action when the link
+        * state changes. Drivers are by no means allowed to mess with the
+        * PHY device structure in their implementations.
+        */
+       void (*link_change_notify)(struct phy_device *dev);
+
        struct device_driver driver;
 };
 #define to_phy_driver(d) container_of(d, struct phy_driver, driver)
index aaad386..b537a25 100644 (file)
@@ -44,6 +44,7 @@ extern int prof_on __read_mostly;
 int profile_init(void);
 int profile_setup(char *str);
 void profile_tick(int type);
+int setup_profiling_timer(unsigned int multiplier);
 
 /*
  * Add multiple profiler hits to a given address:
index a2d9d81..14ec18d 100644 (file)
@@ -395,6 +395,11 @@ static inline void regulator_bulk_free(int num_consumers,
 {
 }
 
+static inline int regulator_can_change_voltage(struct regulator *regulator)
+{
+       return 0;
+}
+
 static inline int regulator_set_voltage(struct regulator *regulator,
                                        int min_uV, int max_uV)
 {
index 8e98297..ec538fc 100644 (file)
@@ -305,8 +305,6 @@ struct ucred {
 /* IPX options */
 #define IPX_TYPE       1
 
-extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
-                              int offset, int len);
 extern int csum_partial_copy_fromiovecend(unsigned char *kdata, 
                                          struct iovec *iov, 
                                          int offset, 
@@ -315,8 +313,6 @@ extern unsigned long iov_pages(const struct iovec *iov, int offset,
                               unsigned long nr_segs);
 
 extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode);
-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);
 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
 
index f76994b..519064e 100644 (file)
@@ -327,6 +327,7 @@ extern unsigned long get_safe_page(gfp_t gfp_mask);
 extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
 extern int hibernate(void);
 extern bool system_entering_hibernation(void);
+extern bool hibernation_available(void);
 asmlinkage int swsusp_save(void);
 extern struct pbe *restore_pblist;
 #else /* CONFIG_HIBERNATION */
@@ -339,6 +340,7 @@ static inline void swsusp_unset_page_free(struct page *p) {}
 static inline void hibernation_set_ops(const struct platform_hibernation_ops *ops) {}
 static inline int hibernate(void) { return -ENOSYS; }
 static inline bool system_entering_hibernation(void) { return false; }
+static inline bool hibernation_available(void) { return false; }
 #endif /* CONFIG_HIBERNATION */
 
 /* Hibernation and suspend events */
index e2231e4..09a7cff 100644 (file)
@@ -94,8 +94,20 @@ static inline size_t iov_iter_count(struct iov_iter *i)
        return i->count;
 }
 
-static inline void iov_iter_truncate(struct iov_iter *i, size_t count)
+/*
+ * Cap the iov_iter by given limit; note that the second argument is
+ * *not* the new size - it's upper limit for such.  Passing it a value
+ * greater than the amount of data in iov_iter is fine - it'll just do
+ * nothing in that case.
+ */
+static inline void iov_iter_truncate(struct iov_iter *i, u64 count)
 {
+       /*
+        * count doesn't have to fit in size_t - comparison extends both
+        * operands to u64 here and any value that would be truncated by
+        * conversion in assignement is by definition greater than all
+        * values of size_t, including old i->count.
+        */
        if (i->count > count)
                i->count = count;
 }
@@ -111,6 +123,9 @@ static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
 
 int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
-
+int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+                       int offset, int len);
+int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
+                     int offset, int len);
 
 #endif
index 7ee6ce6..713b0b8 100644 (file)
@@ -503,9 +503,9 @@ enum nft_chain_flags {
  *     @net: net namespace that this chain belongs to
  *     @table: table that this chain belongs to
  *     @handle: chain handle
- *     @flags: bitmask of enum nft_chain_flags
  *     @use: number of jump references to this chain
  *     @level: length of longest path to this chain
+ *     @flags: bitmask of enum nft_chain_flags
  *     @name: name of the chain
  */
 struct nft_chain {
@@ -514,9 +514,9 @@ struct nft_chain {
        struct net                      *net;
        struct nft_table                *table;
        u64                             handle;
-       u8                              flags;
-       u16                             use;
+       u32                             use;
        u16                             level;
+       u8                              flags;
        char                            name[NFT_CHAIN_MAXNAMELEN];
 };
 
index 07b7fcd..173cae4 100644 (file)
@@ -1730,8 +1730,8 @@ sk_dst_get(struct sock *sk)
 
        rcu_read_lock();
        dst = rcu_dereference(sk->sk_dst_cache);
-       if (dst)
-               dst_hold(dst);
+       if (dst && !atomic_inc_not_zero(&dst->__refcnt))
+               dst = NULL;
        rcu_read_unlock();
        return dst;
 }
index eedda2c..1df3f2f 100644 (file)
@@ -116,6 +116,8 @@ struct snd_card {
        int user_ctl_count;             /* count of all user controls */
        struct list_head controls;      /* all controls for this card */
        struct list_head ctl_files;     /* active control files */
+       struct mutex user_ctl_lock;     /* protects user controls against
+                                          concurrent access */
 
        struct snd_info_entry *proc_root;       /* root for soundcard specific files */
        struct snd_info_entry *proc_id; /* the card id */
index 0fd06fe..26b4f2e 100644 (file)
 #undef __field_ext
 #define __field_ext(type, item, filter_type)   type    item;
 
+#undef __field_struct
+#define __field_struct(type, item)     type    item;
+
+#undef __field_struct_ext
+#define __field_struct_ext(type, item, filter_type)    type    item;
+
 #undef __array
 #define __array(type, item, len)       type    item[len];
 
 #undef __field_ext
 #define __field_ext(type, item, filter_type)
 
+#undef __field_struct
+#define __field_struct(type, item)
+
+#undef __field_struct_ext
+#define __field_struct_ext(type, item, filter_type)
+
 #undef __array
 #define __array(type, item, len)
 
@@ -315,9 +327,21 @@ static struct trace_event_functions ftrace_event_type_funcs_##call = {     \
        if (ret)                                                        \
                return ret;
 
+#undef __field_struct_ext
+#define __field_struct_ext(type, item, filter_type)                    \
+       ret = trace_define_field(event_call, #type, #item,              \
+                                offsetof(typeof(field), item),         \
+                                sizeof(field.item),                    \
+                                0, filter_type);                       \
+       if (ret)                                                        \
+               return ret;
+
 #undef __field
 #define __field(type, item)    __field_ext(type, item, FILTER_OTHER)
 
+#undef __field_struct
+#define __field_struct(type, item) __field_struct_ext(type, item, FILTER_OTHER)
+
 #undef __array
 #define __array(type, item, len)                                       \
        do {                                                            \
@@ -379,6 +403,12 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call)  \
 #undef __field_ext
 #define __field_ext(type, item, filter_type)
 
+#undef __field_struct
+#define __field_struct(type, item)
+
+#undef __field_struct_ext
+#define __field_struct_ext(type, item, filter_type)
+
 #undef __array
 #define __array(type, item, len)
 
@@ -550,6 +580,9 @@ static inline notrace int ftrace_get_offsets_##call(                        \
 #undef __field
 #define __field(type, item)
 
+#undef __field_struct
+#define __field_struct(type, item)
+
 #undef __array
 #define __array(type, item, len)
 
index fed853f..9674145 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/tracepoint.h>
 #include <linux/unistd.h>
 #include <linux/ftrace_event.h>
+#include <linux/thread_info.h>
 
 #include <asm/ptrace.h>
 
@@ -32,4 +33,18 @@ struct syscall_metadata {
        struct ftrace_event_call *exit_event;
 };
 
+#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS)
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+               set_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+       else
+               clear_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+}
+#else
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+}
+#endif
+
 #endif /* _TRACE_SYSCALL_H */
index 5312fae..9269de2 100644 (file)
@@ -705,6 +705,7 @@ enum perf_event_type {
         *      u32                             min;
         *      u64                             ino;
         *      u64                             ino_generation;
+        *      u32                             prot, flags;
         *      char                            filename[];
         *      struct sample_id                sample_id;
         * };
index 21eed48..1964026 100644 (file)
@@ -39,7 +39,7 @@
 struct snd_compressed_buffer {
        __u32 fragment_size;
        __u32 fragments;
-};
+} __attribute__((packed, aligned(4)));
 
 /**
  * struct snd_compr_params: compressed stream params
@@ -51,7 +51,7 @@ struct snd_compr_params {
        struct snd_compressed_buffer buffer;
        struct snd_codec codec;
        __u8 no_wake_mode;
-};
+} __attribute__((packed, aligned(4)));
 
 /**
  * struct snd_compr_tstamp: timestamp descriptor
@@ -70,7 +70,7 @@ struct snd_compr_tstamp {
        __u32 pcm_frames;
        __u32 pcm_io_frames;
        __u32 sampling_rate;
-};
+} __attribute__((packed, aligned(4)));
 
 /**
  * struct snd_compr_avail: avail descriptor
@@ -80,7 +80,7 @@ struct snd_compr_tstamp {
 struct snd_compr_avail {
        __u64 avail;
        struct snd_compr_tstamp tstamp;
-} __attribute__((packed));
+} __attribute__((packed, aligned(4)));
 
 enum snd_compr_direction {
        SND_COMPRESS_PLAYBACK = 0,
@@ -107,7 +107,7 @@ struct snd_compr_caps {
        __u32 max_fragments;
        __u32 codecs[MAX_NUM_CODECS];
        __u32 reserved[11];
-};
+} __attribute__((packed, aligned(4)));
 
 /**
  * struct snd_compr_codec_caps: query capability of codec
@@ -119,7 +119,7 @@ struct snd_compr_codec_caps {
        __u32 codec;
        __u32 num_descriptors;
        struct snd_codec_desc descriptor[MAX_NUM_CODEC_DESCRIPTORS];
-};
+} __attribute__((packed, aligned(4)));
 
 /**
  * @SNDRV_COMPRESS_ENCODER_PADDING: no of samples appended by the encoder at the
@@ -140,7 +140,7 @@ enum {
 struct snd_compr_metadata {
         __u32 key;
         __u32 value[8];
-};
+} __attribute__((packed, aligned(4)));
 
 /**
  * compress path ioctl definitions
index 165e705..d9bd9ca 100644 (file)
@@ -268,7 +268,7 @@ struct snd_enc_vorbis {
        __u32 max_bit_rate;
        __u32 min_bit_rate;
        __u32 downmix;
-};
+} __attribute__((packed, aligned(4)));
 
 
 /**
@@ -284,7 +284,7 @@ struct snd_enc_real {
        __u32 quant_bits;
        __u32 start_region;
        __u32 num_regions;
-};
+} __attribute__((packed, aligned(4)));
 
 /**
  * struct snd_enc_flac
@@ -308,12 +308,12 @@ struct snd_enc_real {
 struct snd_enc_flac {
        __u32 num;
        __u32 gain;
-};
+} __attribute__((packed, aligned(4)));
 
 struct snd_enc_generic {
        __u32 bw;       /* encoder bandwidth */
        __s32 reserved[15];
-};
+} __attribute__((packed, aligned(4)));
 
 union snd_codec_options {
        struct snd_enc_wma wma;
@@ -321,7 +321,7 @@ union snd_codec_options {
        struct snd_enc_real real;
        struct snd_enc_flac flac;
        struct snd_enc_generic generic;
-};
+} __attribute__((packed, aligned(4)));
 
 /** struct snd_codec_desc - description of codec capabilities
  * @max_ch: Maximum number of audio channels
@@ -358,7 +358,7 @@ struct snd_codec_desc {
        __u32 formats;
        __u32 min_buffer;
        __u32 reserved[15];
-};
+} __attribute__((packed, aligned(4)));
 
 /** struct snd_codec
  * @id: Identifies the supported audio encoder/decoder.
@@ -399,6 +399,6 @@ struct snd_codec {
        __u32 align;
        union snd_codec_options options;
        __u32 reserved[3];
-};
+} __attribute__((packed, aligned(4)));
 
 #endif
index 019d450..5664985 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/hardirq.h>
 #include <linux/export.h>
+#include <linux/kprobes.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/context_tracking.h>
@@ -104,6 +105,7 @@ void context_tracking_user_enter(void)
        }
        local_irq_restore(flags);
 }
+NOKPROBE_SYMBOL(context_tracking_user_enter);
 
 #ifdef CONFIG_PREEMPT
 /**
@@ -181,6 +183,7 @@ void context_tracking_user_exit(void)
        }
        local_irq_restore(flags);
 }
+NOKPROBE_SYMBOL(context_tracking_user_exit);
 
 /**
  * __context_tracking_task_switch - context switch the syscall callbacks
index 5fa58e4..a33d9a2 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/mm_types.h>
 #include <linux/cgroup.h>
 #include <linux/module.h>
+#include <linux/mman.h>
 
 #include "internal.h"
 
@@ -5128,6 +5129,7 @@ struct perf_mmap_event {
        int                     maj, min;
        u64                     ino;
        u64                     ino_generation;
+       u32                     prot, flags;
 
        struct {
                struct perf_event_header        header;
@@ -5169,6 +5171,8 @@ static void perf_event_mmap_output(struct perf_event *event,
                mmap_event->event_id.header.size += sizeof(mmap_event->min);
                mmap_event->event_id.header.size += sizeof(mmap_event->ino);
                mmap_event->event_id.header.size += sizeof(mmap_event->ino_generation);
+               mmap_event->event_id.header.size += sizeof(mmap_event->prot);
+               mmap_event->event_id.header.size += sizeof(mmap_event->flags);
        }
 
        perf_event_header__init_id(&mmap_event->event_id.header, &sample, event);
@@ -5187,6 +5191,8 @@ static void perf_event_mmap_output(struct perf_event *event,
                perf_output_put(&handle, mmap_event->min);
                perf_output_put(&handle, mmap_event->ino);
                perf_output_put(&handle, mmap_event->ino_generation);
+               perf_output_put(&handle, mmap_event->prot);
+               perf_output_put(&handle, mmap_event->flags);
        }
 
        __output_copy(&handle, mmap_event->file_name,
@@ -5205,6 +5211,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
        struct file *file = vma->vm_file;
        int maj = 0, min = 0;
        u64 ino = 0, gen = 0;
+       u32 prot = 0, flags = 0;
        unsigned int size;
        char tmp[16];
        char *buf = NULL;
@@ -5235,6 +5242,28 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
                gen = inode->i_generation;
                maj = MAJOR(dev);
                min = MINOR(dev);
+
+               if (vma->vm_flags & VM_READ)
+                       prot |= PROT_READ;
+               if (vma->vm_flags & VM_WRITE)
+                       prot |= PROT_WRITE;
+               if (vma->vm_flags & VM_EXEC)
+                       prot |= PROT_EXEC;
+
+               if (vma->vm_flags & VM_MAYSHARE)
+                       flags = MAP_SHARED;
+               else
+                       flags = MAP_PRIVATE;
+
+               if (vma->vm_flags & VM_DENYWRITE)
+                       flags |= MAP_DENYWRITE;
+               if (vma->vm_flags & VM_MAYEXEC)
+                       flags |= MAP_EXECUTABLE;
+               if (vma->vm_flags & VM_LOCKED)
+                       flags |= MAP_LOCKED;
+               if (vma->vm_flags & VM_HUGETLB)
+                       flags |= MAP_HUGETLB;
+
                goto got_name;
        } else {
                name = (char *)arch_vma_name(vma);
@@ -5275,6 +5304,8 @@ got_name:
        mmap_event->min = min;
        mmap_event->ino = ino;
        mmap_event->ino_generation = gen;
+       mmap_event->prot = prot;
+       mmap_event->flags = flags;
 
        if (!(vma->vm_flags & VM_EXEC))
                mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA;
@@ -5315,6 +5346,8 @@ void perf_event_mmap(struct vm_area_struct *vma)
                /* .min (attr_mmap2 only) */
                /* .ino (attr_mmap2 only) */
                /* .ino_generation (attr_mmap2 only) */
+               /* .prot (attr_mmap2 only) */
+               /* .flags (attr_mmap2 only) */
        };
 
        perf_event_mmap_event(&mmap_event);
@@ -6897,10 +6930,6 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
        if (ret)
                return -EFAULT;
 
-       /* disabled for now */
-       if (attr->mmap2)
-               return -EINVAL;
-
        if (attr->__reserved_1)
                return -EINVAL;
 
index d2799d1..6a13c46 100644 (file)
@@ -1487,7 +1487,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
        total_forks++;
        spin_unlock(&current->sighand->siglock);
+       syscall_tracepoint_update(p);
        write_unlock_irq(&tasklist_lock);
+
        proc_fork_connector(p);
        cgroup_post_fork(p);
        if (clone_flags & CLONE_THREAD)
index 6748688..369f41a 100644 (file)
@@ -1617,6 +1617,7 @@ static int __init crash_save_vmcoreinfo_init(void)
 #ifdef CONFIG_MEMORY_FAILURE
        VMCOREINFO_NUMBER(PG_hwpoison);
 #endif
+       VMCOREINFO_NUMBER(PG_head_mask);
        VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
 
        arch_crash_save_vmcoreinfo();
index 14193d5..ab29b6a 100644 (file)
@@ -31,3 +31,8 @@ static inline int debug_rt_mutex_detect_deadlock(struct rt_mutex_waiter *waiter,
 {
        return (waiter != NULL);
 }
+
+static inline void rt_mutex_print_deadlock(struct rt_mutex_waiter *w)
+{
+       debug_rt_mutex_print_deadlock(w);
+}
index a620d4d..fc60594 100644 (file)
@@ -83,6 +83,47 @@ static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
                owner = *p;
        } while (cmpxchg(p, owner, owner | RT_MUTEX_HAS_WAITERS) != owner);
 }
+
+/*
+ * Safe fastpath aware unlock:
+ * 1) Clear the waiters bit
+ * 2) Drop lock->wait_lock
+ * 3) Try to unlock the lock with cmpxchg
+ */
+static inline bool unlock_rt_mutex_safe(struct rt_mutex *lock)
+       __releases(lock->wait_lock)
+{
+       struct task_struct *owner = rt_mutex_owner(lock);
+
+       clear_rt_mutex_waiters(lock);
+       raw_spin_unlock(&lock->wait_lock);
+       /*
+        * If a new waiter comes in between the unlock and the cmpxchg
+        * we have two situations:
+        *
+        * unlock(wait_lock);
+        *                                      lock(wait_lock);
+        * cmpxchg(p, owner, 0) == owner
+        *                                      mark_rt_mutex_waiters(lock);
+        *                                      acquire(lock);
+        * or:
+        *
+        * unlock(wait_lock);
+        *                                      lock(wait_lock);
+        *                                      mark_rt_mutex_waiters(lock);
+        *
+        * cmpxchg(p, owner, 0) != owner
+        *                                      enqueue_waiter();
+        *                                      unlock(wait_lock);
+        * lock(wait_lock);
+        * wake waiter();
+        * unlock(wait_lock);
+        *                                      lock(wait_lock);
+        *                                      acquire(lock);
+        */
+       return rt_mutex_cmpxchg(lock, owner, NULL);
+}
+
 #else
 # define rt_mutex_cmpxchg(l,c,n)       (0)
 static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
@@ -90,6 +131,17 @@ static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
        lock->owner = (struct task_struct *)
                        ((unsigned long)lock->owner | RT_MUTEX_HAS_WAITERS);
 }
+
+/*
+ * Simple slow path only version: lock->owner is protected by lock->wait_lock.
+ */
+static inline bool unlock_rt_mutex_safe(struct rt_mutex *lock)
+       __releases(lock->wait_lock)
+{
+       lock->owner = NULL;
+       raw_spin_unlock(&lock->wait_lock);
+       return true;
+}
 #endif
 
 static inline int
@@ -260,27 +312,36 @@ static void rt_mutex_adjust_prio(struct task_struct *task)
  */
 int max_lock_depth = 1024;
 
+static inline struct rt_mutex *task_blocked_on_lock(struct task_struct *p)
+{
+       return p->pi_blocked_on ? p->pi_blocked_on->lock : NULL;
+}
+
 /*
  * Adjust the priority chain. Also used for deadlock detection.
  * Decreases task's usage by one - may thus free the task.
  *
- * @task: the task owning the mutex (owner) for which a chain walk is probably
- *       needed
+ * @task:      the task owning the mutex (owner) for which a chain walk is
+ *             probably needed
  * @deadlock_detect: do we have to carry out deadlock detection?
- * @orig_lock: the mutex (can be NULL if we are walking the chain to recheck
- *            things for a task that has just got its priority adjusted, and
- *            is waiting on a mutex)
+ * @orig_lock: the mutex (can be NULL if we are walking the chain to recheck
+ *             things for a task that has just got its priority adjusted, and
+ *             is waiting on a mutex)
+ * @next_lock: the mutex on which the owner of @orig_lock was blocked before
+ *             we dropped its pi_lock. Is never dereferenced, only used for
+ *             comparison to detect lock chain changes.
  * @orig_waiter: rt_mutex_waiter struct for the task that has just donated
- *              its priority to the mutex owner (can be NULL in the case
- *              depicted above or if the top waiter is gone away and we are
- *              actually deboosting the owner)
- * @top_task: the current top waiter
+ *             its priority to the mutex owner (can be NULL in the case
+ *             depicted above or if the top waiter is gone away and we are
+ *             actually deboosting the owner)
+ * @top_task:  the current top waiter
  *
  * Returns 0 or -EDEADLK.
  */
 static int rt_mutex_adjust_prio_chain(struct task_struct *task,
                                      int deadlock_detect,
                                      struct rt_mutex *orig_lock,
+                                     struct rt_mutex *next_lock,
                                      struct rt_mutex_waiter *orig_waiter,
                                      struct task_struct *top_task)
 {
@@ -314,7 +375,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
                }
                put_task_struct(task);
 
-               return deadlock_detect ? -EDEADLK : 0;
+               return -EDEADLK;
        }
  retry:
        /*
@@ -338,6 +399,18 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
        if (orig_waiter && !rt_mutex_owner(orig_lock))
                goto out_unlock_pi;
 
+       /*
+        * We dropped all locks after taking a refcount on @task, so
+        * the task might have moved on in the lock chain or even left
+        * the chain completely and blocks now on an unrelated lock or
+        * on @orig_lock.
+        *
+        * We stored the lock on which @task was blocked in @next_lock,
+        * so we can detect the chain change.
+        */
+       if (next_lock != waiter->lock)
+               goto out_unlock_pi;
+
        /*
         * Drop out, when the task has no waiters. Note,
         * top_waiter can be NULL, when we are in the deboosting
@@ -377,7 +450,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
        if (lock == orig_lock || rt_mutex_owner(lock) == top_task) {
                debug_rt_mutex_deadlock(deadlock_detect, orig_waiter, lock);
                raw_spin_unlock(&lock->wait_lock);
-               ret = deadlock_detect ? -EDEADLK : 0;
+               ret = -EDEADLK;
                goto out_unlock_pi;
        }
 
@@ -422,11 +495,26 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
                __rt_mutex_adjust_prio(task);
        }
 
+       /*
+        * Check whether the task which owns the current lock is pi
+        * blocked itself. If yes we store a pointer to the lock for
+        * the lock chain change detection above. After we dropped
+        * task->pi_lock next_lock cannot be dereferenced anymore.
+        */
+       next_lock = task_blocked_on_lock(task);
+
        raw_spin_unlock_irqrestore(&task->pi_lock, flags);
 
        top_waiter = rt_mutex_top_waiter(lock);
        raw_spin_unlock(&lock->wait_lock);
 
+       /*
+        * We reached the end of the lock chain. Stop right here. No
+        * point to go back just to figure that out.
+        */
+       if (!next_lock)
+               goto out_put_task;
+
        if (!detect_deadlock && waiter != top_waiter)
                goto out_put_task;
 
@@ -536,8 +624,9 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
 {
        struct task_struct *owner = rt_mutex_owner(lock);
        struct rt_mutex_waiter *top_waiter = waiter;
-       unsigned long flags;
+       struct rt_mutex *next_lock;
        int chain_walk = 0, res;
+       unsigned long flags;
 
        /*
         * Early deadlock detection. We really don't want the task to
@@ -548,7 +637,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
         * which is wrong, as the other waiter is not in a deadlock
         * situation.
         */
-       if (detect_deadlock && owner == task)
+       if (owner == task)
                return -EDEADLK;
 
        raw_spin_lock_irqsave(&task->pi_lock, flags);
@@ -569,20 +658,28 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
        if (!owner)
                return 0;
 
+       raw_spin_lock_irqsave(&owner->pi_lock, flags);
        if (waiter == rt_mutex_top_waiter(lock)) {
-               raw_spin_lock_irqsave(&owner->pi_lock, flags);
                rt_mutex_dequeue_pi(owner, top_waiter);
                rt_mutex_enqueue_pi(owner, waiter);
 
                __rt_mutex_adjust_prio(owner);
                if (owner->pi_blocked_on)
                        chain_walk = 1;
-               raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
-       }
-       else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock))
+       } else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
                chain_walk = 1;
+       }
 
-       if (!chain_walk)
+       /* Store the lock on which owner is blocked or NULL */
+       next_lock = task_blocked_on_lock(owner);
+
+       raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
+       /*
+        * Even if full deadlock detection is on, if the owner is not
+        * blocked itself, we can avoid finding this out in the chain
+        * walk.
+        */
+       if (!chain_walk || !next_lock)
                return 0;
 
        /*
@@ -594,8 +691,8 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
 
        raw_spin_unlock(&lock->wait_lock);
 
-       res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
-                                        task);
+       res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock,
+                                        next_lock, waiter, task);
 
        raw_spin_lock(&lock->wait_lock);
 
@@ -605,7 +702,8 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
 /*
  * Wake up the next waiter on the lock.
  *
- * Remove the top waiter from the current tasks waiter list and wake it up.
+ * Remove the top waiter from the current tasks pi waiter list and
+ * wake it up.
  *
  * Called with lock->wait_lock held.
  */
@@ -626,10 +724,23 @@ static void wakeup_next_waiter(struct rt_mutex *lock)
         */
        rt_mutex_dequeue_pi(current, waiter);
 
-       rt_mutex_set_owner(lock, NULL);
+       /*
+        * As we are waking up the top waiter, and the waiter stays
+        * queued on the lock until it gets the lock, this lock
+        * obviously has waiters. Just set the bit here and this has
+        * the added benefit of forcing all new tasks into the
+        * slow path making sure no task of lower priority than
+        * the top waiter can steal this lock.
+        */
+       lock->owner = (void *) RT_MUTEX_HAS_WAITERS;
 
        raw_spin_unlock_irqrestore(&current->pi_lock, flags);
 
+       /*
+        * It's safe to dereference waiter as it cannot go away as
+        * long as we hold lock->wait_lock. The waiter task needs to
+        * acquire it in order to dequeue the waiter.
+        */
        wake_up_process(waiter->task);
 }
 
@@ -644,8 +755,8 @@ static void remove_waiter(struct rt_mutex *lock,
 {
        int first = (waiter == rt_mutex_top_waiter(lock));
        struct task_struct *owner = rt_mutex_owner(lock);
+       struct rt_mutex *next_lock = NULL;
        unsigned long flags;
-       int chain_walk = 0;
 
        raw_spin_lock_irqsave(&current->pi_lock, flags);
        rt_mutex_dequeue(lock, waiter);
@@ -669,13 +780,13 @@ static void remove_waiter(struct rt_mutex *lock,
                }
                __rt_mutex_adjust_prio(owner);
 
-               if (owner->pi_blocked_on)
-                       chain_walk = 1;
+               /* Store the lock on which owner is blocked or NULL */
+               next_lock = task_blocked_on_lock(owner);
 
                raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
        }
 
-       if (!chain_walk)
+       if (!next_lock)
                return;
 
        /* gets dropped in rt_mutex_adjust_prio_chain()! */
@@ -683,7 +794,7 @@ static void remove_waiter(struct rt_mutex *lock,
 
        raw_spin_unlock(&lock->wait_lock);
 
-       rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
+       rt_mutex_adjust_prio_chain(owner, 0, lock, next_lock, NULL, current);
 
        raw_spin_lock(&lock->wait_lock);
 }
@@ -696,6 +807,7 @@ static void remove_waiter(struct rt_mutex *lock,
 void rt_mutex_adjust_pi(struct task_struct *task)
 {
        struct rt_mutex_waiter *waiter;
+       struct rt_mutex *next_lock;
        unsigned long flags;
 
        raw_spin_lock_irqsave(&task->pi_lock, flags);
@@ -706,12 +818,13 @@ void rt_mutex_adjust_pi(struct task_struct *task)
                raw_spin_unlock_irqrestore(&task->pi_lock, flags);
                return;
        }
-
+       next_lock = waiter->lock;
        raw_spin_unlock_irqrestore(&task->pi_lock, flags);
 
        /* gets dropped in rt_mutex_adjust_prio_chain()! */
        get_task_struct(task);
-       rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
+
+       rt_mutex_adjust_prio_chain(task, 0, NULL, next_lock, NULL, task);
 }
 
 /**
@@ -763,6 +876,26 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state,
        return ret;
 }
 
+static void rt_mutex_handle_deadlock(int res, int detect_deadlock,
+                                    struct rt_mutex_waiter *w)
+{
+       /*
+        * If the result is not -EDEADLOCK or the caller requested
+        * deadlock detection, nothing to do here.
+        */
+       if (res != -EDEADLOCK || detect_deadlock)
+               return;
+
+       /*
+        * Yell lowdly and stop the task right here.
+        */
+       rt_mutex_print_deadlock(w);
+       while (1) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule();
+       }
+}
+
 /*
  * Slow path lock function:
  */
@@ -802,8 +935,10 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state,
 
        set_current_state(TASK_RUNNING);
 
-       if (unlikely(ret))
+       if (unlikely(ret)) {
                remove_waiter(lock, &waiter);
+               rt_mutex_handle_deadlock(ret, detect_deadlock, &waiter);
+       }
 
        /*
         * try_to_take_rt_mutex() sets the waiter bit
@@ -859,12 +994,49 @@ rt_mutex_slowunlock(struct rt_mutex *lock)
 
        rt_mutex_deadlock_account_unlock(current);
 
-       if (!rt_mutex_has_waiters(lock)) {
-               lock->owner = NULL;
-               raw_spin_unlock(&lock->wait_lock);
-               return;
+       /*
+        * We must be careful here if the fast path is enabled. If we
+        * have no waiters queued we cannot set owner to NULL here
+        * because of:
+        *
+        * foo->lock->owner = NULL;
+        *                      rtmutex_lock(foo->lock);   <- fast path
+        *                      free = atomic_dec_and_test(foo->refcnt);
+        *                      rtmutex_unlock(foo->lock); <- fast path
+        *                      if (free)
+        *                              kfree(foo);
+        * raw_spin_unlock(foo->lock->wait_lock);
+        *
+        * So for the fastpath enabled kernel:
+        *
+        * Nothing can set the waiters bit as long as we hold
+        * lock->wait_lock. So we do the following sequence:
+        *
+        *      owner = rt_mutex_owner(lock);
+        *      clear_rt_mutex_waiters(lock);
+        *      raw_spin_unlock(&lock->wait_lock);
+        *      if (cmpxchg(&lock->owner, owner, 0) == owner)
+        *              return;
+        *      goto retry;
+        *
+        * The fastpath disabled variant is simple as all access to
+        * lock->owner is serialized by lock->wait_lock:
+        *
+        *      lock->owner = NULL;
+        *      raw_spin_unlock(&lock->wait_lock);
+        */
+       while (!rt_mutex_has_waiters(lock)) {
+               /* Drops lock->wait_lock ! */
+               if (unlock_rt_mutex_safe(lock) == true)
+                       return;
+               /* Relock the rtmutex and try again */
+               raw_spin_lock(&lock->wait_lock);
        }
 
+       /*
+        * The wakeup next waiter path does not suffer from the above
+        * race. See the comments there.
+        */
        wakeup_next_waiter(lock);
 
        raw_spin_unlock(&lock->wait_lock);
@@ -1112,7 +1284,8 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
                return 1;
        }
 
-       ret = task_blocks_on_rt_mutex(lock, waiter, task, detect_deadlock);
+       /* We enforce deadlock detection for futexes */
+       ret = task_blocks_on_rt_mutex(lock, waiter, task, 1);
 
        if (ret && !rt_mutex_owner(lock)) {
                /*
index a1a1dd0..f6a1f3c 100644 (file)
@@ -24,3 +24,8 @@
 #define debug_rt_mutex_print_deadlock(w)               do { } while (0)
 #define debug_rt_mutex_detect_deadlock(w,d)            (d)
 #define debug_rt_mutex_reset_waiter(w)                 do { } while (0)
+
+static inline void rt_mutex_print_deadlock(struct rt_mutex_waiter *w)
+{
+       WARN(1, "rtmutex deadlock detected\n");
+}
index 49e0a20..fcc2611 100644 (file)
@@ -35,6 +35,7 @@
 
 static int nocompress;
 static int noresume;
+static int nohibernate;
 static int resume_wait;
 static unsigned int resume_delay;
 static char resume_file[256] = CONFIG_PM_STD_PARTITION;
@@ -62,6 +63,11 @@ bool freezer_test_done;
 
 static const struct platform_hibernation_ops *hibernation_ops;
 
+bool hibernation_available(void)
+{
+       return (nohibernate == 0);
+}
+
 /**
  * hibernation_set_ops - Set the global hibernate operations.
  * @ops: Hibernation operations to use in subsequent hibernation transitions.
@@ -642,6 +648,11 @@ int hibernate(void)
 {
        int error;
 
+       if (!hibernation_available()) {
+               pr_debug("PM: Hibernation not available.\n");
+               return -EPERM;
+       }
+
        lock_system_sleep();
        /* The snapshot device should not be opened while we're running */
        if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
@@ -734,7 +745,7 @@ static int software_resume(void)
        /*
         * If the user said "noresume".. bail out early.
         */
-       if (noresume)
+       if (noresume || !hibernation_available())
                return 0;
 
        /*
@@ -900,6 +911,9 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr,
        int i;
        char *start = buf;
 
+       if (!hibernation_available())
+               return sprintf(buf, "[disabled]\n");
+
        for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
                if (!hibernation_modes[i])
                        continue;
@@ -934,6 +948,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
        char *p;
        int mode = HIBERNATION_INVALID;
 
+       if (!hibernation_available())
+               return -EPERM;
+
        p = memchr(buf, '\n', n);
        len = p ? p - buf : n;
 
@@ -1101,6 +1118,10 @@ static int __init hibernate_setup(char *str)
                noresume = 1;
        else if (!strncmp(str, "nocompress", 10))
                nocompress = 1;
+       else if (!strncmp(str, "no", 2)) {
+               noresume = 1;
+               nohibernate = 1;
+       }
        return 1;
 }
 
@@ -1125,9 +1146,23 @@ static int __init resumedelay_setup(char *str)
        return 1;
 }
 
+static int __init nohibernate_setup(char *str)
+{
+       noresume = 1;
+       nohibernate = 1;
+       return 1;
+}
+
+static int __init kaslr_nohibernate_setup(char *str)
+{
+       return nohibernate_setup(str);
+}
+
 __setup("noresume", noresume_setup);
 __setup("resume_offset=", resume_offset_setup);
 __setup("resume=", resume_setup);
 __setup("hibernate=", hibernate_setup);
 __setup("resumewait", resumewait_setup);
 __setup("resumedelay=", resumedelay_setup);
+__setup("nohibernate", nohibernate_setup);
+__setup("kaslr", kaslr_nohibernate_setup);
index 573410d..8e90f33 100644 (file)
@@ -300,13 +300,11 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
                        s += sprintf(s,"%s ", pm_states[i].label);
 
 #endif
-#ifdef CONFIG_HIBERNATION
-       s += sprintf(s, "%s\n", "disk");
-#else
+       if (hibernation_available())
+               s += sprintf(s, "disk ");
        if (s != buf)
                /* convert the last space to a newline */
                *(s-1) = '\n';
-#endif
        return (s - buf);
 }
 
index 98d3575..526e891 100644 (file)
@@ -49,6 +49,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
        struct snapshot_data *data;
        int error;
 
+       if (!hibernation_available())
+               return -EPERM;
+
        lock_system_sleep();
 
        if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
index 306f818..80c33f8 100644 (file)
@@ -29,6 +29,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data);
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct llist_head, call_single_queue);
 
+static void flush_smp_call_function_queue(bool warn_cpu_offline);
+
 static int
 hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
@@ -51,12 +53,27 @@ hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
 #ifdef CONFIG_HOTPLUG_CPU
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
+               /* Fall-through to the CPU_DEAD[_FROZEN] case. */
 
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
                free_cpumask_var(cfd->cpumask);
                free_percpu(cfd->csd);
                break;
+
+       case CPU_DYING:
+       case CPU_DYING_FROZEN:
+               /*
+                * The IPIs for the smp-call-function callbacks queued by other
+                * CPUs might arrive late, either due to hardware latencies or
+                * because this CPU disabled interrupts (inside stop-machine)
+                * before the IPIs were sent. So flush out any pending callbacks
+                * explicitly (without waiting for the IPIs to arrive), to
+                * ensure that the outgoing CPU doesn't go offline with work
+                * still pending.
+                */
+               flush_smp_call_function_queue(false);
+               break;
 #endif
        };
 
@@ -177,23 +194,47 @@ static int generic_exec_single(int cpu, struct call_single_data *csd,
        return 0;
 }
 
-/*
- * Invoked by arch to handle an IPI for call function single. Must be
- * called from the arch with interrupts disabled.
+/**
+ * generic_smp_call_function_single_interrupt - Execute SMP IPI callbacks
+ *
+ * Invoked by arch to handle an IPI for call function single.
+ * Must be called with interrupts disabled.
  */
 void generic_smp_call_function_single_interrupt(void)
 {
+       flush_smp_call_function_queue(true);
+}
+
+/**
+ * flush_smp_call_function_queue - Flush pending smp-call-function callbacks
+ *
+ * @warn_cpu_offline: If set to 'true', warn if callbacks were queued on an
+ *                   offline CPU. Skip this check if set to 'false'.
+ *
+ * Flush any pending smp-call-function callbacks queued on this CPU. This is
+ * invoked by the generic IPI handler, as well as by a CPU about to go offline,
+ * to ensure that all pending IPI callbacks are run before it goes completely
+ * offline.
+ *
+ * Loop through the call_single_queue and run all the queued callbacks.
+ * Must be called with interrupts disabled.
+ */
+static void flush_smp_call_function_queue(bool warn_cpu_offline)
+{
+       struct llist_head *head;
        struct llist_node *entry;
        struct call_single_data *csd, *csd_next;
        static bool warned;
 
-       entry = llist_del_all(&__get_cpu_var(call_single_queue));
+       WARN_ON(!irqs_disabled());
+
+       head = &__get_cpu_var(call_single_queue);
+       entry = llist_del_all(head);
        entry = llist_reverse_order(entry);
 
-       /*
-        * Shouldn't receive this interrupt on a cpu that is not yet online.
-        */
-       if (unlikely(!cpu_online(smp_processor_id()) && !warned)) {
+       /* There shouldn't be any pending callbacks on an offline CPU. */
+       if (unlikely(warn_cpu_offline && !cpu_online(smp_processor_id()) &&
+                    !warned && !llist_empty(head))) {
                warned = true;
                WARN(1, "IPI on offline CPU %d\n", smp_processor_id());
 
index ba9ed45..75b22e2 100644 (file)
@@ -136,7 +136,6 @@ static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
-static int min_percpu_pagelist_fract = 8;
 
 static int ngroups_max = NGROUPS_MAX;
 static const int cap_last_cap = CAP_LAST_CAP;
@@ -152,10 +151,6 @@ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
 #ifdef CONFIG_SPARC
 #endif
 
-#ifdef CONFIG_SPARC64
-extern int sysctl_tsb_ratio;
-#endif
-
 #ifdef __hppa__
 extern int pwrsw_enabled;
 #endif
@@ -865,6 +860,17 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &one,
        },
+#ifdef CONFIG_SMP
+       {
+               .procname       = "softlockup_all_cpu_backtrace",
+               .data           = &sysctl_softlockup_all_cpu_backtrace,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
+#endif /* CONFIG_SMP */
        {
                .procname       = "nmi_watchdog",
                .data           = &watchdog_user_enabled,
@@ -1321,7 +1327,7 @@ static struct ctl_table vm_table[] = {
                .maxlen         = sizeof(percpu_pagelist_fraction),
                .mode           = 0644,
                .proc_handler   = percpu_pagelist_fraction_sysctl_handler,
-               .extra1         = &min_percpu_pagelist_fract,
+               .extra1         = &zero,
        },
 #ifdef CONFIG_MMU
        {
index 33cbd8c..3490407 100644 (file)
@@ -492,33 +492,29 @@ static int sys_tracepoint_refcount;
 
 void syscall_regfunc(void)
 {
-       unsigned long flags;
-       struct task_struct *g, *t;
+       struct task_struct *p, *t;
 
        if (!sys_tracepoint_refcount) {
-               read_lock_irqsave(&tasklist_lock, flags);
-               do_each_thread(g, t) {
-                       /* Skip kernel threads. */
-                       if (t->mm)
-                               set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
-               } while_each_thread(g, t);
-               read_unlock_irqrestore(&tasklist_lock, flags);
+               read_lock(&tasklist_lock);
+               for_each_process_thread(p, t) {
+                       set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
+               }
+               read_unlock(&tasklist_lock);
        }
        sys_tracepoint_refcount++;
 }
 
 void syscall_unregfunc(void)
 {
-       unsigned long flags;
-       struct task_struct *g, *t;
+       struct task_struct *p, *t;
 
        sys_tracepoint_refcount--;
        if (!sys_tracepoint_refcount) {
-               read_lock_irqsave(&tasklist_lock, flags);
-               do_each_thread(g, t) {
+               read_lock(&tasklist_lock);
+               for_each_process_thread(p, t) {
                        clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
-               } while_each_thread(g, t);
-               read_unlock_irqrestore(&tasklist_lock, flags);
+               }
+               read_unlock(&tasklist_lock);
        }
 }
 #endif
index 516203e..c3319bd 100644 (file)
 
 int watchdog_user_enabled = 1;
 int __read_mostly watchdog_thresh = 10;
+#ifdef CONFIG_SMP
+int __read_mostly sysctl_softlockup_all_cpu_backtrace;
+#else
+#define sysctl_softlockup_all_cpu_backtrace 0
+#endif
+
 static int __read_mostly watchdog_running;
 static u64 __read_mostly sample_period;
 
@@ -47,6 +53,7 @@ static DEFINE_PER_CPU(bool, watchdog_nmi_touch);
 static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved);
 static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
 #endif
+static unsigned long soft_lockup_nmi_warn;
 
 /* boot commands */
 /*
@@ -95,6 +102,15 @@ static int __init nosoftlockup_setup(char *str)
 }
 __setup("nosoftlockup", nosoftlockup_setup);
 /*  */
+#ifdef CONFIG_SMP
+static int __init softlockup_all_cpu_backtrace_setup(char *str)
+{
+       sysctl_softlockup_all_cpu_backtrace =
+               !!simple_strtol(str, NULL, 0);
+       return 1;
+}
+__setup("softlockup_all_cpu_backtrace=", softlockup_all_cpu_backtrace_setup);
+#endif
 
 /*
  * Hard-lockup warnings should be triggered after just a few seconds. Soft-
@@ -271,6 +287,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
        unsigned long touch_ts = __this_cpu_read(watchdog_touch_ts);
        struct pt_regs *regs = get_irq_regs();
        int duration;
+       int softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace;
 
        /* kick the hardlockup detector */
        watchdog_interrupt_count();
@@ -317,6 +334,17 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
                if (__this_cpu_read(soft_watchdog_warn) == true)
                        return HRTIMER_RESTART;
 
+               if (softlockup_all_cpu_backtrace) {
+                       /* Prevent multiple soft-lockup reports if one cpu is already
+                        * engaged in dumping cpu back traces
+                        */
+                       if (test_and_set_bit(0, &soft_lockup_nmi_warn)) {
+                               /* Someone else will report us. Let's give up */
+                               __this_cpu_write(soft_watchdog_warn, true);
+                               return HRTIMER_RESTART;
+                       }
+               }
+
                printk(KERN_EMERG "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n",
                        smp_processor_id(), duration,
                        current->comm, task_pid_nr(current));
@@ -327,6 +355,17 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
                else
                        dump_stack();
 
+               if (softlockup_all_cpu_backtrace) {
+                       /* Avoid generating two back traces for current
+                        * given that one is already made above
+                        */
+                       trigger_allbutself_cpu_backtrace();
+
+                       clear_bit(0, &soft_lockup_nmi_warn);
+                       /* Barrier to sync with other cpus */
+                       smp_mb__after_atomic();
+               }
+
                if (softlockup_panic)
                        panic("softlockup: hung tasks");
                __this_cpu_write(soft_watchdog_warn, true);
@@ -527,10 +566,8 @@ static void update_timers_all_cpus(void)
        int cpu;
 
        get_online_cpus();
-       preempt_disable();
        for_each_online_cpu(cpu)
                update_timers(cpu);
-       preempt_enable();
        put_online_cpus();
 }
 
index 7cfcc1b..7a638aa 100644 (file)
@@ -930,7 +930,7 @@ config LOCKDEP
        bool
        depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
        select STACKTRACE
-       select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC
+       select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE
        select KALLSYMS
        select KALLSYMS_ALL
 
@@ -1408,7 +1408,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER
        depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
        depends on !X86_64
        select STACKTRACE
-       select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC
+       select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE
        help
          Provide stacktrace filter for fault-injection capabilities
 
index 454baa8..7a7c2da 100644 (file)
@@ -51,3 +51,58 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
        return 0;
 }
 EXPORT_SYMBOL(memcpy_toiovec);
+
+/*
+ *     Copy kernel to iovec. Returns -EFAULT on error.
+ */
+
+int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
+                     int offset, int len)
+{
+       int copy;
+       for (; len > 0; ++iov) {
+               /* Skip over the finished iovecs */
+               if (unlikely(offset >= iov->iov_len)) {
+                       offset -= iov->iov_len;
+                       continue;
+               }
+               copy = min_t(unsigned int, iov->iov_len - offset, len);
+               if (copy_to_user(iov->iov_base + offset, kdata, copy))
+                       return -EFAULT;
+               offset = 0;
+               kdata += copy;
+               len -= copy;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(memcpy_toiovecend);
+
+/*
+ *     Copy iovec to kernel. Returns -EFAULT on error.
+ */
+
+int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+                       int offset, int len)
+{
+       /* Skip over the finished iovecs */
+       while (offset >= iov->iov_len) {
+               offset -= iov->iov_len;
+               iov++;
+       }
+
+       while (len > 0) {
+               u8 __user *base = iov->iov_base + offset;
+               int copy = min_t(unsigned int, len, iov->iov_len - offset);
+
+               offset = 0;
+               if (copy_from_user(kdata, base, copy))
+                       return -EFAULT;
+               len -= copy;
+               kdata += copy;
+               iov++;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(memcpy_fromiovecend);
index df6839e..b74da44 100644 (file)
@@ -72,6 +72,8 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
                        len = *ip++;
                        for (; len == 255; length += 255)
                                len = *ip++;
+                       if (unlikely(length > (size_t)(length + len)))
+                               goto _output_error;
                        length += len;
                }
 
@@ -106,6 +108,8 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
                if (length == ML_MASK) {
                        for (; *ip == 255; length += 255)
                                ip++;
+                       if (unlikely(length > (size_t)(length + *ip)))
+                               goto _output_error;
                        length += *ip++;
                }
 
@@ -155,7 +159,7 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
 
        /* write overflow error detected */
 _output_error:
-       return (int) (-(((char *)ip) - source));
+       return -1;
 }
 
 static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
index 569985d..8563081 100644 (file)
 #include <linux/lzo.h>
 #include "lzodefs.h"
 
-#define HAVE_IP(x)      ((size_t)(ip_end - ip) >= (size_t)(x))
-#define HAVE_OP(x)      ((size_t)(op_end - op) >= (size_t)(x))
-#define NEED_IP(x)      if (!HAVE_IP(x)) goto input_overrun
-#define NEED_OP(x)      if (!HAVE_OP(x)) goto output_overrun
-#define TEST_LB(m_pos)  if ((m_pos) < out) goto lookbehind_overrun
+#define HAVE_IP(t, x)                                  \
+       (((size_t)(ip_end - ip) >= (size_t)(t + x)) &&  \
+        (((t + x) >= t) && ((t + x) >= x)))
+
+#define HAVE_OP(t, x)                                  \
+       (((size_t)(op_end - op) >= (size_t)(t + x)) &&  \
+        (((t + x) >= t) && ((t + x) >= x)))
+
+#define NEED_IP(t, x)                                  \
+       do {                                            \
+               if (!HAVE_IP(t, x))                     \
+                       goto input_overrun;             \
+       } while (0)
+
+#define NEED_OP(t, x)                                  \
+       do {                                            \
+               if (!HAVE_OP(t, x))                     \
+                       goto output_overrun;            \
+       } while (0)
+
+#define TEST_LB(m_pos)                                 \
+       do {                                            \
+               if ((m_pos) < out)                      \
+                       goto lookbehind_overrun;        \
+       } while (0)
 
 int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
                          unsigned char *out, size_t *out_len)
@@ -58,14 +78,14 @@ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
                                        while (unlikely(*ip == 0)) {
                                                t += 255;
                                                ip++;
-                                               NEED_IP(1);
+                                               NEED_IP(1, 0);
                                        }
                                        t += 15 + *ip++;
                                }
                                t += 3;
 copy_literal_run:
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-                               if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
+                               if (likely(HAVE_IP(t, 15) && HAVE_OP(t, 15))) {
                                        const unsigned char *ie = ip + t;
                                        unsigned char *oe = op + t;
                                        do {
@@ -81,8 +101,8 @@ copy_literal_run:
                                } else
 #endif
                                {
-                                       NEED_OP(t);
-                                       NEED_IP(t + 3);
+                                       NEED_OP(t, 0);
+                                       NEED_IP(t, 3);
                                        do {
                                                *op++ = *ip++;
                                        } while (--t > 0);
@@ -95,7 +115,7 @@ copy_literal_run:
                                m_pos -= t >> 2;
                                m_pos -= *ip++ << 2;
                                TEST_LB(m_pos);
-                               NEED_OP(2);
+                               NEED_OP(2, 0);
                                op[0] = m_pos[0];
                                op[1] = m_pos[1];
                                op += 2;
@@ -119,10 +139,10 @@ copy_literal_run:
                                while (unlikely(*ip == 0)) {
                                        t += 255;
                                        ip++;
-                                       NEED_IP(1);
+                                       NEED_IP(1, 0);
                                }
                                t += 31 + *ip++;
-                               NEED_IP(2);
+                               NEED_IP(2, 0);
                        }
                        m_pos = op - 1;
                        next = get_unaligned_le16(ip);
@@ -137,10 +157,10 @@ copy_literal_run:
                                while (unlikely(*ip == 0)) {
                                        t += 255;
                                        ip++;
-                                       NEED_IP(1);
+                                       NEED_IP(1, 0);
                                }
                                t += 7 + *ip++;
-                               NEED_IP(2);
+                               NEED_IP(2, 0);
                        }
                        next = get_unaligned_le16(ip);
                        ip += 2;
@@ -154,7 +174,7 @@ copy_literal_run:
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
                if (op - m_pos >= 8) {
                        unsigned char *oe = op + t;
-                       if (likely(HAVE_OP(t + 15))) {
+                       if (likely(HAVE_OP(t, 15))) {
                                do {
                                        COPY8(op, m_pos);
                                        op += 8;
@@ -164,7 +184,7 @@ copy_literal_run:
                                        m_pos += 8;
                                } while (op < oe);
                                op = oe;
-                               if (HAVE_IP(6)) {
+                               if (HAVE_IP(6, 0)) {
                                        state = next;
                                        COPY4(op, ip);
                                        op += next;
@@ -172,7 +192,7 @@ copy_literal_run:
                                        continue;
                                }
                        } else {
-                               NEED_OP(t);
+                               NEED_OP(t, 0);
                                do {
                                        *op++ = *m_pos++;
                                } while (op < oe);
@@ -181,7 +201,7 @@ copy_literal_run:
 #endif
                {
                        unsigned char *oe = op + t;
-                       NEED_OP(t);
+                       NEED_OP(t, 0);
                        op[0] = m_pos[0];
                        op[1] = m_pos[1];
                        op += 2;
@@ -194,15 +214,15 @@ match_next:
                state = next;
                t = next;
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-               if (likely(HAVE_IP(6) && HAVE_OP(4))) {
+               if (likely(HAVE_IP(6, 0) && HAVE_OP(4, 0))) {
                        COPY4(op, ip);
                        op += t;
                        ip += t;
                } else
 #endif
                {
-                       NEED_IP(t + 3);
-                       NEED_OP(t);
+                       NEED_IP(t, 3);
+                       NEED_OP(t, 0);
                        while (t > 0) {
                                *op++ = *ip++;
                                t--;
index 649d097..4abda07 100644 (file)
@@ -86,6 +86,7 @@ static unsigned int io_tlb_index;
  * We need to save away the original address corresponding to a mapped entry
  * for the sync operations.
  */
+#define INVALID_PHYS_ADDR (~(phys_addr_t)0)
 static phys_addr_t *io_tlb_orig_addr;
 
 /*
@@ -188,12 +189,14 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
        io_tlb_list = memblock_virt_alloc(
                                PAGE_ALIGN(io_tlb_nslabs * sizeof(int)),
                                PAGE_SIZE);
-       for (i = 0; i < io_tlb_nslabs; i++)
-               io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
-       io_tlb_index = 0;
        io_tlb_orig_addr = memblock_virt_alloc(
                                PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t)),
                                PAGE_SIZE);
+       for (i = 0; i < io_tlb_nslabs; i++) {
+               io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
+               io_tlb_orig_addr[i] = INVALID_PHYS_ADDR;
+       }
+       io_tlb_index = 0;
 
        if (verbose)
                swiotlb_print_info();
@@ -313,10 +316,6 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
        if (!io_tlb_list)
                goto cleanup3;
 
-       for (i = 0; i < io_tlb_nslabs; i++)
-               io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
-       io_tlb_index = 0;
-
        io_tlb_orig_addr = (phys_addr_t *)
                __get_free_pages(GFP_KERNEL,
                                 get_order(io_tlb_nslabs *
@@ -324,7 +323,11 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
        if (!io_tlb_orig_addr)
                goto cleanup4;
 
-       memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(phys_addr_t));
+       for (i = 0; i < io_tlb_nslabs; i++) {
+               io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
+               io_tlb_orig_addr[i] = INVALID_PHYS_ADDR;
+       }
+       io_tlb_index = 0;
 
        swiotlb_print_info();
 
@@ -556,7 +559,8 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
        /*
         * First, sync the memory before unmapping the entry
         */
-       if (orig_addr && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
+       if (orig_addr != INVALID_PHYS_ADDR &&
+           ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
                swiotlb_bounce(orig_addr, tlb_addr, size, DMA_FROM_DEVICE);
 
        /*
@@ -573,8 +577,10 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
                 * Step 1: return the slots to the free list, merging the
                 * slots with superceeding slots
                 */
-               for (i = index + nslots - 1; i >= index; i--)
+               for (i = index + nslots - 1; i >= index; i--) {
                        io_tlb_list[i] = ++count;
+                       io_tlb_orig_addr[i] = INVALID_PHYS_ADDR;
+               }
                /*
                 * Step 2: merge the returned slots with the preceding slots,
                 * if available (non zero)
@@ -593,6 +599,8 @@ void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr,
        int index = (tlb_addr - io_tlb_start) >> IO_TLB_SHIFT;
        phys_addr_t orig_addr = io_tlb_orig_addr[index];
 
+       if (orig_addr == INVALID_PHYS_ADDR)
+               return;
        orig_addr += (unsigned long)tlb_addr & ((1 << IO_TLB_SHIFT) - 1);
 
        switch (target) {
index e60837d..33514d8 100644 (file)
@@ -941,6 +941,37 @@ unlock:
        spin_unlock(ptl);
 }
 
+/*
+ * Save CONFIG_DEBUG_PAGEALLOC from faulting falsely on tail pages
+ * during copy_user_huge_page()'s copy_page_rep(): in the case when
+ * the source page gets split and a tail freed before copy completes.
+ * Called under pmd_lock of checked pmd, so safe from splitting itself.
+ */
+static void get_user_huge_page(struct page *page)
+{
+       if (IS_ENABLED(CONFIG_DEBUG_PAGEALLOC)) {
+               struct page *endpage = page + HPAGE_PMD_NR;
+
+               atomic_add(HPAGE_PMD_NR, &page->_count);
+               while (++page < endpage)
+                       get_huge_page_tail(page);
+       } else {
+               get_page(page);
+       }
+}
+
+static void put_user_huge_page(struct page *page)
+{
+       if (IS_ENABLED(CONFIG_DEBUG_PAGEALLOC)) {
+               struct page *endpage = page + HPAGE_PMD_NR;
+
+               while (page < endpage)
+                       put_page(page++);
+       } else {
+               put_page(page);
+       }
+}
+
 static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
                                        struct vm_area_struct *vma,
                                        unsigned long address,
@@ -1074,7 +1105,7 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
                ret |= VM_FAULT_WRITE;
                goto out_unlock;
        }
-       get_page(page);
+       get_user_huge_page(page);
        spin_unlock(ptl);
 alloc:
        if (transparent_hugepage_enabled(vma) &&
@@ -1095,7 +1126,7 @@ alloc:
                                split_huge_page(page);
                                ret |= VM_FAULT_FALLBACK;
                        }
-                       put_page(page);
+                       put_user_huge_page(page);
                }
                count_vm_event(THP_FAULT_FALLBACK);
                goto out;
@@ -1105,7 +1136,7 @@ alloc:
                put_page(new_page);
                if (page) {
                        split_huge_page(page);
-                       put_page(page);
+                       put_user_huge_page(page);
                } else
                        split_huge_page_pmd(vma, address, pmd);
                ret |= VM_FAULT_FALLBACK;
@@ -1127,7 +1158,7 @@ alloc:
 
        spin_lock(ptl);
        if (page)
-               put_page(page);
+               put_user_huge_page(page);
        if (unlikely(!pmd_same(*pmd, orig_pmd))) {
                spin_unlock(ptl);
                mem_cgroup_uncharge_page(new_page);
@@ -2392,8 +2423,6 @@ static void collapse_huge_page(struct mm_struct *mm,
        pmd = mm_find_pmd(mm, address);
        if (!pmd)
                goto out;
-       if (pmd_trans_huge(*pmd))
-               goto out;
 
        anon_vma_lock_write(vma->anon_vma);
 
@@ -2492,8 +2521,6 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
        pmd = mm_find_pmd(mm, address);
        if (!pmd)
                goto out;
-       if (pmd_trans_huge(*pmd))
-               goto out;
 
        memset(khugepaged_node_load, 0, sizeof(khugepaged_node_load));
        pte = pte_offset_map_lock(mm, pmd, address, &ptl);
@@ -2846,12 +2873,22 @@ void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
 static void split_huge_page_address(struct mm_struct *mm,
                                    unsigned long address)
 {
+       pgd_t *pgd;
+       pud_t *pud;
        pmd_t *pmd;
 
        VM_BUG_ON(!(address & ~HPAGE_PMD_MASK));
 
-       pmd = mm_find_pmd(mm, address);
-       if (!pmd)
+       pgd = pgd_offset(mm, address);
+       if (!pgd_present(*pgd))
+               return;
+
+       pud = pud_offset(pgd, address);
+       if (!pud_present(*pud))
+               return;
+
+       pmd = pmd_offset(pud, address);
+       if (!pmd_present(*pmd))
                return;
        /*
         * Caller holds the mmap_sem write mode, so a huge pmd cannot
index 226910c..2024bbd 100644 (file)
@@ -2520,6 +2520,31 @@ static void set_huge_ptep_writable(struct vm_area_struct *vma,
                update_mmu_cache(vma, address, ptep);
 }
 
+static int is_hugetlb_entry_migration(pte_t pte)
+{
+       swp_entry_t swp;
+
+       if (huge_pte_none(pte) || pte_present(pte))
+               return 0;
+       swp = pte_to_swp_entry(pte);
+       if (non_swap_entry(swp) && is_migration_entry(swp))
+               return 1;
+       else
+               return 0;
+}
+
+static int is_hugetlb_entry_hwpoisoned(pte_t pte)
+{
+       swp_entry_t swp;
+
+       if (huge_pte_none(pte) || pte_present(pte))
+               return 0;
+       swp = pte_to_swp_entry(pte);
+       if (non_swap_entry(swp) && is_hwpoison_entry(swp))
+               return 1;
+       else
+               return 0;
+}
 
 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
                            struct vm_area_struct *vma)
@@ -2559,10 +2584,26 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
                dst_ptl = huge_pte_lock(h, dst, dst_pte);
                src_ptl = huge_pte_lockptr(h, src, src_pte);
                spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
-               if (!huge_pte_none(huge_ptep_get(src_pte))) {
+               entry = huge_ptep_get(src_pte);
+               if (huge_pte_none(entry)) { /* skip none entry */
+                       ;
+               } else if (unlikely(is_hugetlb_entry_migration(entry) ||
+                                   is_hugetlb_entry_hwpoisoned(entry))) {
+                       swp_entry_t swp_entry = pte_to_swp_entry(entry);
+
+                       if (is_write_migration_entry(swp_entry) && cow) {
+                               /*
+                                * COW mappings require pages in both
+                                * parent and child to be set to read.
+                                */
+                               make_migration_entry_read(&swp_entry);
+                               entry = swp_entry_to_pte(swp_entry);
+                               set_huge_pte_at(src, addr, src_pte, entry);
+                       }
+                       set_huge_pte_at(dst, addr, dst_pte, entry);
+               } else {
                        if (cow)
                                huge_ptep_set_wrprotect(src, addr, src_pte);
-                       entry = huge_ptep_get(src_pte);
                        ptepage = pte_page(entry);
                        get_page(ptepage);
                        page_dup_rmap(ptepage);
@@ -2578,32 +2619,6 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
        return ret;
 }
 
-static int is_hugetlb_entry_migration(pte_t pte)
-{
-       swp_entry_t swp;
-
-       if (huge_pte_none(pte) || pte_present(pte))
-               return 0;
-       swp = pte_to_swp_entry(pte);
-       if (non_swap_entry(swp) && is_migration_entry(swp))
-               return 1;
-       else
-               return 0;
-}
-
-static int is_hugetlb_entry_hwpoisoned(pte_t pte)
-{
-       swp_entry_t swp;
-
-       if (huge_pte_none(pte) || pte_present(pte))
-               return 0;
-       swp = pte_to_swp_entry(pte);
-       if (non_swap_entry(swp) && is_hwpoison_entry(swp))
-               return 1;
-       else
-               return 0;
-}
-
 void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
                            unsigned long start, unsigned long end,
                            struct page *ref_page)
index 68710e8..346ddc9 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -945,7 +945,6 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
        pmd = mm_find_pmd(mm, addr);
        if (!pmd)
                goto out;
-       BUG_ON(pmd_trans_huge(*pmd));
 
        mmun_start = addr;
        mmun_end   = addr + PAGE_SIZE;
index 2849742..eb58de1 100644 (file)
@@ -656,19 +656,18 @@ static unsigned long change_prot_numa(struct vm_area_struct *vma,
  * @nodes and @flags,) it's isolated and queued to the pagelist which is
  * passed via @private.)
  */
-static struct vm_area_struct *
+static int
 queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end,
                const nodemask_t *nodes, unsigned long flags, void *private)
 {
-       int err;
-       struct vm_area_struct *first, *vma, *prev;
-
+       int err = 0;
+       struct vm_area_struct *vma, *prev;
 
-       first = find_vma(mm, start);
-       if (!first)
-               return ERR_PTR(-EFAULT);
+       vma = find_vma(mm, start);
+       if (!vma)
+               return -EFAULT;
        prev = NULL;
-       for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
+       for (; vma && vma->vm_start < end; vma = vma->vm_next) {
                unsigned long endvma = vma->vm_end;
 
                if (endvma > end)
@@ -678,9 +677,9 @@ queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end,
 
                if (!(flags & MPOL_MF_DISCONTIG_OK)) {
                        if (!vma->vm_next && vma->vm_end < end)
-                               return ERR_PTR(-EFAULT);
+                               return -EFAULT;
                        if (prev && prev->vm_end < vma->vm_start)
-                               return ERR_PTR(-EFAULT);
+                               return -EFAULT;
                }
 
                if (flags & MPOL_MF_LAZY) {
@@ -694,15 +693,13 @@ queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end,
 
                        err = queue_pages_pgd_range(vma, start, endvma, nodes,
                                                flags, private);
-                       if (err) {
-                               first = ERR_PTR(err);
+                       if (err)
                                break;
-                       }
                }
 next:
                prev = vma;
        }
-       return first;
+       return err;
 }
 
 /*
@@ -1156,16 +1153,17 @@ out:
 
 /*
  * Allocate a new page for page migration based on vma policy.
- * Start assuming that page is mapped by vma pointed to by @private.
+ * Start by assuming the page is mapped by the same vma as contains @start.
  * Search forward from there, if not.  N.B., this assumes that the
  * list of pages handed to migrate_pages()--which is how we get here--
  * is in virtual address order.
  */
-static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
+static struct page *new_page(struct page *page, unsigned long start, int **x)
 {
-       struct vm_area_struct *vma = (struct vm_area_struct *)private;
+       struct vm_area_struct *vma;
        unsigned long uninitialized_var(address);
 
+       vma = find_vma(current->mm, start);
        while (vma) {
                address = page_address_in_vma(page, vma);
                if (address != -EFAULT)
@@ -1195,7 +1193,7 @@ int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from,
        return -ENOSYS;
 }
 
-static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
+static struct page *new_page(struct page *page, unsigned long start, int **x)
 {
        return NULL;
 }
@@ -1205,7 +1203,6 @@ static long do_mbind(unsigned long start, unsigned long len,
                     unsigned short mode, unsigned short mode_flags,
                     nodemask_t *nmask, unsigned long flags)
 {
-       struct vm_area_struct *vma;
        struct mm_struct *mm = current->mm;
        struct mempolicy *new;
        unsigned long end;
@@ -1271,11 +1268,9 @@ static long do_mbind(unsigned long start, unsigned long len,
        if (err)
                goto mpol_out;
 
-       vma = queue_pages_range(mm, start, end, nmask,
+       err = queue_pages_range(mm, start, end, nmask,
                          flags | MPOL_MF_INVERT, &pagelist);
-
-       err = PTR_ERR(vma);     /* maybe ... */
-       if (!IS_ERR(vma))
+       if (!err)
                err = mbind_range(mm, start, end, new);
 
        if (!err) {
@@ -1283,9 +1278,8 @@ static long do_mbind(unsigned long start, unsigned long len,
 
                if (!list_empty(&pagelist)) {
                        WARN_ON_ONCE(flags & MPOL_MF_LAZY);
-                       nr_failed = migrate_pages(&pagelist, new_vma_page,
-                                       NULL, (unsigned long)vma,
-                                       MIGRATE_SYNC, MR_MEMPOLICY_MBIND);
+                       nr_failed = migrate_pages(&pagelist, new_page, NULL,
+                               start, MIGRATE_SYNC, MR_MEMPOLICY_MBIND);
                        if (nr_failed)
                                putback_movable_pages(&pagelist);
                }
index 63f0cd5..9e0beaa 100644 (file)
@@ -120,8 +120,6 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
                pmd = mm_find_pmd(mm, addr);
                if (!pmd)
                        goto out;
-               if (pmd_trans_huge(*pmd))
-                       goto out;
 
                ptep = pte_offset_map(pmd, addr);
 
index b78e3a8..4a852f6 100644 (file)
@@ -786,7 +786,7 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
        for (i = 0; i < VMACACHE_SIZE; i++) {
                /* if the vma is cached, invalidate the entire cache */
                if (curr->vmacache[i] == vma) {
-                       vmacache_invalidate(curr->mm);
+                       vmacache_invalidate(mm);
                        break;
                }
        }
index 4f59fa2..20d17f8 100644 (file)
@@ -69,6 +69,7 @@
 
 /* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */
 static DEFINE_MUTEX(pcp_batch_high_lock);
+#define MIN_PERCPU_PAGELIST_FRACTION   (8)
 
 #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
 DEFINE_PER_CPU(int, numa_node);
@@ -4145,7 +4146,7 @@ static void __meminit zone_init_free_lists(struct zone *zone)
        memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
 #endif
 
-static int __meminit zone_batchsize(struct zone *zone)
+static int zone_batchsize(struct zone *zone)
 {
 #ifdef CONFIG_MMU
        int batch;
@@ -4261,8 +4262,8 @@ static void pageset_set_high(struct per_cpu_pageset *p,
        pageset_update(&p->pcp, high, batch);
 }
 
-static void __meminit pageset_set_high_and_batch(struct zone *zone,
-               struct per_cpu_pageset *pcp)
+static void pageset_set_high_and_batch(struct zone *zone,
+                                      struct per_cpu_pageset *pcp)
 {
        if (percpu_pagelist_fraction)
                pageset_set_high(pcp,
@@ -5881,23 +5882,38 @@ int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *table, int write,
        void __user *buffer, size_t *length, loff_t *ppos)
 {
        struct zone *zone;
-       unsigned int cpu;
+       int old_percpu_pagelist_fraction;
        int ret;
 
+       mutex_lock(&pcp_batch_high_lock);
+       old_percpu_pagelist_fraction = percpu_pagelist_fraction;
+
        ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
-       if (!write || (ret < 0))
-               return ret;
+       if (!write || ret < 0)
+               goto out;
+
+       /* Sanity checking to avoid pcp imbalance */
+       if (percpu_pagelist_fraction &&
+           percpu_pagelist_fraction < MIN_PERCPU_PAGELIST_FRACTION) {
+               percpu_pagelist_fraction = old_percpu_pagelist_fraction;
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* No change? */
+       if (percpu_pagelist_fraction == old_percpu_pagelist_fraction)
+               goto out;
 
-       mutex_lock(&pcp_batch_high_lock);
        for_each_populated_zone(zone) {
-               unsigned long  high;
-               high = zone->managed_pages / percpu_pagelist_fraction;
+               unsigned int cpu;
+
                for_each_possible_cpu(cpu)
-                       pageset_set_high(per_cpu_ptr(zone->pageset, cpu),
-                                        high);
+                       pageset_set_high_and_batch(zone,
+                                       per_cpu_ptr(zone->pageset, cpu));
        }
+out:
        mutex_unlock(&pcp_batch_high_lock);
-       return 0;
+       return ret;
 }
 
 int hashdist = HASHDIST_DEFAULT;
index bf05fc8..b7e94eb 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -569,6 +569,7 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd = NULL;
+       pmd_t pmde;
 
        pgd = pgd_offset(mm, address);
        if (!pgd_present(*pgd))
@@ -579,7 +580,13 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
                goto out;
 
        pmd = pmd_offset(pud, address);
-       if (!pmd_present(*pmd))
+       /*
+        * Some THP functions use the sequence pmdp_clear_flush(), set_pmd_at()
+        * without holding anon_vma lock for write.  So when looking for a
+        * genuine pmde (in which to find pte), test present and !THP together.
+        */
+       pmde = ACCESS_ONCE(*pmd);
+       if (!pmd_present(pmde) || pmd_trans_huge(pmde))
                pmd = NULL;
 out:
        return pmd;
@@ -615,9 +622,6 @@ pte_t *__page_check_address(struct page *page, struct mm_struct *mm,
        if (!pmd)
                return NULL;
 
-       if (pmd_trans_huge(*pmd))
-               return NULL;
-
        pte = pte_offset_map(pmd, address);
        /* Make a quick check before getting the lock */
        if (!sync && !pte_present(*pte)) {
index f484c27..8f419cf 100644 (file)
@@ -80,11 +80,12 @@ static struct vfsmount *shm_mnt;
 #define SHORT_SYMLINK_LEN 128
 
 /*
- * shmem_fallocate and shmem_writepage communicate via inode->i_private
- * (with i_mutex making sure that it has only one user at a time):
- * we would prefer not to enlarge the shmem inode just for that.
+ * shmem_fallocate communicates with shmem_fault or shmem_writepage via
+ * inode->i_private (with i_mutex making sure that it has only one user at
+ * a time): we would prefer not to enlarge the shmem inode just for that.
  */
 struct shmem_falloc {
+       int     mode;           /* FALLOC_FL mode currently operating */
        pgoff_t start;          /* start of range currently being fallocated */
        pgoff_t next;           /* the next page offset to be fallocated */
        pgoff_t nr_falloced;    /* how many new pages have been fallocated */
@@ -759,6 +760,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
                        spin_lock(&inode->i_lock);
                        shmem_falloc = inode->i_private;
                        if (shmem_falloc &&
+                           !shmem_falloc->mode &&
                            index >= shmem_falloc->start &&
                            index < shmem_falloc->next)
                                shmem_falloc->nr_unswapped++;
@@ -1233,6 +1235,44 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        int error;
        int ret = VM_FAULT_LOCKED;
 
+       /*
+        * Trinity finds that probing a hole which tmpfs is punching can
+        * prevent the hole-punch from ever completing: which in turn
+        * locks writers out with its hold on i_mutex.  So refrain from
+        * faulting pages into the hole while it's being punched, and
+        * wait on i_mutex to be released if vmf->flags permits.
+        */
+       if (unlikely(inode->i_private)) {
+               struct shmem_falloc *shmem_falloc;
+
+               spin_lock(&inode->i_lock);
+               shmem_falloc = inode->i_private;
+               if (!shmem_falloc ||
+                   shmem_falloc->mode != FALLOC_FL_PUNCH_HOLE ||
+                   vmf->pgoff < shmem_falloc->start ||
+                   vmf->pgoff >= shmem_falloc->next)
+                       shmem_falloc = NULL;
+               spin_unlock(&inode->i_lock);
+               /*
+                * i_lock has protected us from taking shmem_falloc seriously
+                * once return from shmem_fallocate() went back up that stack.
+                * i_lock does not serialize with i_mutex at all, but it does
+                * not matter if sometimes we wait unnecessarily, or sometimes
+                * miss out on waiting: we just need to make those cases rare.
+                */
+               if (shmem_falloc) {
+                       if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) &&
+                          !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
+                               up_read(&vma->vm_mm->mmap_sem);
+                               mutex_lock(&inode->i_mutex);
+                               mutex_unlock(&inode->i_mutex);
+                               return VM_FAULT_RETRY;
+                       }
+                       /* cond_resched? Leave that to GUP or return to user */
+                       return VM_FAULT_NOPAGE;
+               }
+       }
+
        error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret);
        if (error)
                return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS);
@@ -1724,20 +1764,31 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
        pgoff_t start, index, end;
        int error;
 
+       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+               return -EOPNOTSUPP;
+
        mutex_lock(&inode->i_mutex);
 
+       shmem_falloc.mode = mode & ~FALLOC_FL_KEEP_SIZE;
+
        if (mode & FALLOC_FL_PUNCH_HOLE) {
                struct address_space *mapping = file->f_mapping;
                loff_t unmap_start = round_up(offset, PAGE_SIZE);
                loff_t unmap_end = round_down(offset + len, PAGE_SIZE) - 1;
 
+               shmem_falloc.start = unmap_start >> PAGE_SHIFT;
+               shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT;
+               spin_lock(&inode->i_lock);
+               inode->i_private = &shmem_falloc;
+               spin_unlock(&inode->i_lock);
+
                if ((u64)unmap_end > (u64)unmap_start)
                        unmap_mapping_range(mapping, unmap_start,
                                            1 + unmap_end - unmap_start, 0);
                shmem_truncate_range(inode, offset, offset + len - 1);
                /* No need to unmap again: hole-punching leaves COWed pages */
                error = 0;
-               goto out;
+               goto undone;
        }
 
        /* We need to check rlimit even when FALLOC_FL_KEEP_SIZE */
index 9ca3b87..3070b92 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -386,6 +386,39 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp)
 
 #endif
 
+#define OBJECT_FREE (0)
+#define OBJECT_ACTIVE (1)
+
+#ifdef CONFIG_DEBUG_SLAB_LEAK
+
+static void set_obj_status(struct page *page, int idx, int val)
+{
+       int freelist_size;
+       char *status;
+       struct kmem_cache *cachep = page->slab_cache;
+
+       freelist_size = cachep->num * sizeof(freelist_idx_t);
+       status = (char *)page->freelist + freelist_size;
+       status[idx] = val;
+}
+
+static inline unsigned int get_obj_status(struct page *page, int idx)
+{
+       int freelist_size;
+       char *status;
+       struct kmem_cache *cachep = page->slab_cache;
+
+       freelist_size = cachep->num * sizeof(freelist_idx_t);
+       status = (char *)page->freelist + freelist_size;
+
+       return status[idx];
+}
+
+#else
+static inline void set_obj_status(struct page *page, int idx, int val) {}
+
+#endif
+
 /*
  * Do not go above this order unless 0 objects fit into the slab or
  * overridden on the command line.
@@ -576,12 +609,30 @@ static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
        return cachep->array[smp_processor_id()];
 }
 
+static size_t calculate_freelist_size(int nr_objs, size_t align)
+{
+       size_t freelist_size;
+
+       freelist_size = nr_objs * sizeof(freelist_idx_t);
+       if (IS_ENABLED(CONFIG_DEBUG_SLAB_LEAK))
+               freelist_size += nr_objs * sizeof(char);
+
+       if (align)
+               freelist_size = ALIGN(freelist_size, align);
+
+       return freelist_size;
+}
+
 static int calculate_nr_objs(size_t slab_size, size_t buffer_size,
                                size_t idx_size, size_t align)
 {
        int nr_objs;
+       size_t remained_size;
        size_t freelist_size;
+       int extra_space = 0;
 
+       if (IS_ENABLED(CONFIG_DEBUG_SLAB_LEAK))
+               extra_space = sizeof(char);
        /*
         * Ignore padding for the initial guess. The padding
         * is at most @align-1 bytes, and @buffer_size is at
@@ -590,14 +641,15 @@ static int calculate_nr_objs(size_t slab_size, size_t buffer_size,
         * into the memory allocation when taking the padding
         * into account.
         */
-       nr_objs = slab_size / (buffer_size + idx_size);
+       nr_objs = slab_size / (buffer_size + idx_size + extra_space);
 
        /*
         * This calculated number will be either the right
         * amount, or one greater than what we want.
         */
-       freelist_size = slab_size - nr_objs * buffer_size;
-       if (freelist_size < ALIGN(nr_objs * idx_size, align))
+       remained_size = slab_size - nr_objs * buffer_size;
+       freelist_size = calculate_freelist_size(nr_objs, align);
+       if (remained_size < freelist_size)
                nr_objs--;
 
        return nr_objs;
@@ -635,7 +687,7 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size,
        } else {
                nr_objs = calculate_nr_objs(slab_size, buffer_size,
                                        sizeof(freelist_idx_t), align);
-               mgmt_size = ALIGN(nr_objs * sizeof(freelist_idx_t), align);
+               mgmt_size = calculate_freelist_size(nr_objs, align);
        }
        *num = nr_objs;
        *left_over = slab_size - nr_objs*buffer_size - mgmt_size;
@@ -2041,13 +2093,16 @@ static size_t calculate_slab_order(struct kmem_cache *cachep,
                        break;
 
                if (flags & CFLGS_OFF_SLAB) {
+                       size_t freelist_size_per_obj = sizeof(freelist_idx_t);
                        /*
                         * Max number of objs-per-slab for caches which
                         * use off-slab slabs. Needed to avoid a possible
                         * looping condition in cache_grow().
                         */
+                       if (IS_ENABLED(CONFIG_DEBUG_SLAB_LEAK))
+                               freelist_size_per_obj += sizeof(char);
                        offslab_limit = size;
-                       offslab_limit /= sizeof(freelist_idx_t);
+                       offslab_limit /= freelist_size_per_obj;
 
                        if (num > offslab_limit)
                                break;
@@ -2294,8 +2349,7 @@ __kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
        if (!cachep->num)
                return -E2BIG;
 
-       freelist_size =
-               ALIGN(cachep->num * sizeof(freelist_idx_t), cachep->align);
+       freelist_size = calculate_freelist_size(cachep->num, cachep->align);
 
        /*
         * If the slab has been placed off-slab, and we have enough space then
@@ -2308,7 +2362,7 @@ __kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
 
        if (flags & CFLGS_OFF_SLAB) {
                /* really off slab. No need for manual alignment */
-               freelist_size = cachep->num * sizeof(freelist_idx_t);
+               freelist_size = calculate_freelist_size(cachep->num, 0);
 
 #ifdef CONFIG_PAGE_POISONING
                /* If we're going to use the generic kernel_map_pages()
@@ -2612,6 +2666,7 @@ static void cache_init_objs(struct kmem_cache *cachep,
                if (cachep->ctor)
                        cachep->ctor(objp);
 #endif
+               set_obj_status(page, i, OBJECT_FREE);
                set_free_obj(page, i, i);
        }
 }
@@ -2820,6 +2875,7 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
        BUG_ON(objnr >= cachep->num);
        BUG_ON(objp != index_to_obj(cachep, page, objnr));
 
+       set_obj_status(page, objnr, OBJECT_FREE);
        if (cachep->flags & SLAB_POISON) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
                if ((cachep->size % PAGE_SIZE)==0 && OFF_SLAB(cachep)) {
@@ -2953,6 +3009,8 @@ static inline void cache_alloc_debugcheck_before(struct kmem_cache *cachep,
 static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
                                gfp_t flags, void *objp, unsigned long caller)
 {
+       struct page *page;
+
        if (!objp)
                return objp;
        if (cachep->flags & SLAB_POISON) {
@@ -2983,6 +3041,9 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
                *dbg_redzone1(cachep, objp) = RED_ACTIVE;
                *dbg_redzone2(cachep, objp) = RED_ACTIVE;
        }
+
+       page = virt_to_head_page(objp);
+       set_obj_status(page, obj_to_index(cachep, page, objp), OBJECT_ACTIVE);
        objp += obj_offset(cachep);
        if (cachep->ctor && cachep->flags & SLAB_POISON)
                cachep->ctor(objp);
@@ -4219,21 +4280,12 @@ static void handle_slab(unsigned long *n, struct kmem_cache *c,
                                                struct page *page)
 {
        void *p;
-       int i, j;
+       int i;
 
        if (n[0] == n[1])
                return;
        for (i = 0, p = page->s_mem; i < c->num; i++, p += c->size) {
-               bool active = true;
-
-               for (j = page->active; j < c->num; j++) {
-                       /* Skip freed item */
-                       if (get_free_obj(page, j) == i) {
-                               active = false;
-                               break;
-                       }
-               }
-               if (!active)
+               if (get_obj_status(page, i) != OBJECT_ACTIVE)
                        continue;
 
                if (!add_caller(n, (unsigned long)*dbg_userword(c, p)))
index 9012b1c..75d4277 100644 (file)
@@ -114,8 +114,11 @@ EXPORT_SYMBOL(vlan_dev_vlan_proto);
 
 static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)
 {
-       if (skb_cow(skb, skb_headroom(skb)) < 0)
+       if (skb_cow(skb, skb_headroom(skb)) < 0) {
+               kfree_skb(skb);
                return NULL;
+       }
+
        memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
        skb->mac_header += VLAN_HLEN;
        return skb;
index 8671bc7..ca01d18 100644 (file)
@@ -610,11 +610,6 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
        if (hci_update_random_address(req, false, &own_addr_type))
                return;
 
-       /* Save the address type used for this connnection attempt so we able
-        * to retrieve this information if we need it.
-        */
-       conn->src_type = own_addr_type;
-
        cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
        cp.scan_window = cpu_to_le16(hdev->le_scan_window);
        bacpy(&cp.peer_addr, &conn->dst);
@@ -894,7 +889,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
                /* If we're already encrypted set the REAUTH_PEND flag,
                 * otherwise set the ENCRYPT_PEND.
                 */
-               if (conn->key_type != 0xff)
+               if (conn->link_mode & HCI_LM_ENCRYPT)
                        set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
                else
                        set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
index 21e5913..640c54e 100644 (file)
@@ -48,6 +48,10 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
        smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
        wake_up_bit(&hdev->flags, HCI_INQUIRY);
 
+       hci_dev_lock(hdev);
+       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+       hci_dev_unlock(hdev);
+
        hci_conn_check_pending(hdev);
 }
 
@@ -3537,7 +3541,11 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
                        cp.authentication = conn->auth_type;
 
                        /* Request MITM protection if our IO caps allow it
-                        * except for the no-bonding case
+                        * except for the no-bonding case.
+                        * conn->auth_type is not updated here since
+                        * that might cause the user confirmation to be
+                        * rejected in case the remote doesn't have the
+                        * IO capabilities for MITM.
                         */
                        if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
                            cp.authentication != HCI_AT_NO_BONDING)
@@ -3628,8 +3636,11 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
 
                /* If we're not the initiators request authorization to
                 * proceed from user space (mgmt_user_confirm with
-                * confirm_hint set to 1). */
-               if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
+                * confirm_hint set to 1). The exception is if neither
+                * side had MITM in which case we do auto-accept.
+                */
+               if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
+                   (loc_mitm || rem_mitm)) {
                        BT_DBG("Confirming auto-accept as acceptor");
                        confirm_hint = 1;
                        goto confirm;
index 6eabbe0..323f23c 100644 (file)
@@ -1663,7 +1663,13 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
        kfree_skb(conn->rx_skb);
 
        skb_queue_purge(&conn->pending_rx);
-       flush_work(&conn->pending_rx_work);
+
+       /* We can not call flush_work(&conn->pending_rx_work) here since we
+        * might block if we are running on a worker from the same workqueue
+        * pending_rx_work is waiting on.
+        */
+       if (work_pending(&conn->pending_rx_work))
+               cancel_work_sync(&conn->pending_rx_work);
 
        l2cap_unregister_all_users(conn);
 
index ade3fb4..e137869 100644 (file)
@@ -787,11 +787,6 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
 
                /*change security for LE channels */
                if (chan->scid == L2CAP_CID_ATT) {
-                       if (!conn->hcon->out) {
-                               err = -EINVAL;
-                               break;
-                       }
-
                        if (smp_conn_security(conn->hcon, sec.level))
                                break;
                        sk->sk_state = BT_CONFIG;
index 0fce544..af8e0a6 100644 (file)
@@ -1047,6 +1047,43 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
        }
 }
 
+static void hci_stop_discovery(struct hci_request *req)
+{
+       struct hci_dev *hdev = req->hdev;
+       struct hci_cp_remote_name_req_cancel cp;
+       struct inquiry_entry *e;
+
+       switch (hdev->discovery.state) {
+       case DISCOVERY_FINDING:
+               if (test_bit(HCI_INQUIRY, &hdev->flags)) {
+                       hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
+               } else {
+                       cancel_delayed_work(&hdev->le_scan_disable);
+                       hci_req_add_le_scan_disable(req);
+               }
+
+               break;
+
+       case DISCOVERY_RESOLVING:
+               e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
+                                                    NAME_PENDING);
+               if (!e)
+                       return;
+
+               bacpy(&cp.bdaddr, &e->data.bdaddr);
+               hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
+                           &cp);
+
+               break;
+
+       default:
+               /* Passive scanning */
+               if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+                       hci_req_add_le_scan_disable(req);
+               break;
+       }
+}
+
 static int clean_up_hci_state(struct hci_dev *hdev)
 {
        struct hci_request req;
@@ -1063,9 +1100,7 @@ static int clean_up_hci_state(struct hci_dev *hdev)
        if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
                disable_advertising(&req);
 
-       if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
-               hci_req_add_le_scan_disable(&req);
-       }
+       hci_stop_discovery(&req);
 
        list_for_each_entry(conn, &hdev->conn_hash.list, list) {
                struct hci_cp_disconnect dc;
@@ -2996,8 +3031,13 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
        }
 
        if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
-               /* Continue with pairing via SMP */
+               /* Continue with pairing via SMP. The hdev lock must be
+                * released as SMP may try to recquire it for crypto
+                * purposes.
+                */
+               hci_dev_unlock(hdev);
                err = smp_user_confirm_reply(conn, mgmt_op, passkey);
+               hci_dev_lock(hdev);
 
                if (!err)
                        err = cmd_complete(sk, hdev->id, mgmt_op,
@@ -3574,8 +3614,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
 {
        struct mgmt_cp_stop_discovery *mgmt_cp = data;
        struct pending_cmd *cmd;
-       struct hci_cp_remote_name_req_cancel cp;
-       struct inquiry_entry *e;
        struct hci_request req;
        int err;
 
@@ -3605,52 +3643,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
 
        hci_req_init(&req, hdev);
 
-       switch (hdev->discovery.state) {
-       case DISCOVERY_FINDING:
-               if (test_bit(HCI_INQUIRY, &hdev->flags)) {
-                       hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
-               } else {
-                       cancel_delayed_work(&hdev->le_scan_disable);
-
-                       hci_req_add_le_scan_disable(&req);
-               }
-
-               break;
+       hci_stop_discovery(&req);
 
-       case DISCOVERY_RESOLVING:
-               e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
-                                                    NAME_PENDING);
-               if (!e) {
-                       mgmt_pending_remove(cmd);
-                       err = cmd_complete(sk, hdev->id,
-                                          MGMT_OP_STOP_DISCOVERY, 0,
-                                          &mgmt_cp->type,
-                                          sizeof(mgmt_cp->type));
-                       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
-                       goto unlock;
-               }
-
-               bacpy(&cp.bdaddr, &e->data.bdaddr);
-               hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
-                           &cp);
-
-               break;
-
-       default:
-               BT_DBG("unknown discovery state %u", hdev->discovery.state);
-
-               mgmt_pending_remove(cmd);
-               err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
-                                  MGMT_STATUS_FAILED, &mgmt_cp->type,
-                                  sizeof(mgmt_cp->type));
+       err = hci_req_run(&req, stop_discovery_complete);
+       if (!err) {
+               hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
                goto unlock;
        }
 
-       err = hci_req_run(&req, stop_discovery_complete);
-       if (err < 0)
-               mgmt_pending_remove(cmd);
-       else
-               hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
+       mgmt_pending_remove(cmd);
+
+       /* If no HCI commands were sent we're done */
+       if (err == -ENODATA) {
+               err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
+                                  &mgmt_cp->type, sizeof(mgmt_cp->type));
+               hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+       }
 
 unlock:
        hci_dev_unlock(hdev);
index 3d1cc16..f2829a7 100644 (file)
@@ -544,7 +544,7 @@ static u8 smp_random(struct smp_chan *smp)
                hci_le_start_enc(hcon, ediv, rand, stk);
                hcon->enc_key_size = smp->enc_key_size;
        } else {
-               u8 stk[16];
+               u8 stk[16], auth;
                __le64 rand = 0;
                __le16 ediv = 0;
 
@@ -556,8 +556,13 @@ static u8 smp_random(struct smp_chan *smp)
                memset(stk + smp->enc_key_size, 0,
                       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
 
+               if (hcon->pending_sec_level == BT_SECURITY_HIGH)
+                       auth = 1;
+               else
+                       auth = 0;
+
                hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
-                           HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
+                           HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size,
                            ediv, rand);
        }
 
index 80d6286..a028409 100644 (file)
@@ -269,6 +269,15 @@ again:
 }
 EXPORT_SYMBOL(dst_destroy);
 
+static void dst_destroy_rcu(struct rcu_head *head)
+{
+       struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head);
+
+       dst = dst_destroy(dst);
+       if (dst)
+               __dst_free(dst);
+}
+
 void dst_release(struct dst_entry *dst)
 {
        if (dst) {
@@ -276,11 +285,8 @@ void dst_release(struct dst_entry *dst)
 
                newrefcnt = atomic_dec_return(&dst->__refcnt);
                WARN_ON(newrefcnt < 0);
-               if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) {
-                       dst = dst_destroy(dst);
-                       if (dst)
-                               __dst_free(dst);
-               }
+               if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt)
+                       call_rcu(&dst->rcu_head, dst_destroy_rcu);
        }
 }
 EXPORT_SYMBOL(dst_release);
index 735fad8..1dbf646 100644 (file)
@@ -840,11 +840,11 @@ int sk_convert_filter(struct sock_filter *prog, int len,
        BUILD_BUG_ON(BPF_MEMWORDS * sizeof(u32) > MAX_BPF_STACK);
        BUILD_BUG_ON(BPF_REG_FP + 1 != MAX_BPF_REG);
 
-       if (len <= 0 || len >= BPF_MAXINSNS)
+       if (len <= 0 || len > BPF_MAXINSNS)
                return -EINVAL;
 
        if (new_prog) {
-               addrs = kzalloc(len * sizeof(*addrs), GFP_KERNEL);
+               addrs = kcalloc(len, sizeof(*addrs), GFP_KERNEL);
                if (!addrs)
                        return -ENOMEM;
        }
@@ -1101,7 +1101,7 @@ static int check_load_and_stores(struct sock_filter *filter, int flen)
 
        BUILD_BUG_ON(BPF_MEMWORDS > 16);
 
-       masks = kmalloc(flen * sizeof(*masks), GFP_KERNEL);
+       masks = kmalloc_array(flen, sizeof(*masks), GFP_KERNEL);
        if (!masks)
                return -ENOMEM;
 
@@ -1382,7 +1382,7 @@ static struct sk_filter *__sk_migrate_realloc(struct sk_filter *fp,
        fp_new = sock_kmalloc(sk, len, GFP_KERNEL);
        if (fp_new) {
                *fp_new = *fp;
-               /* As we're kepping orig_prog in fp_new along,
+               /* As we're keeping orig_prog in fp_new along,
                 * we need to make sure we're not evicting it
                 * from the old fp.
                 */
@@ -1524,8 +1524,8 @@ static struct sk_filter *__sk_prepare_filter(struct sk_filter *fp,
 
 /**
  *     sk_unattached_filter_create - create an unattached filter
- *     @fprog: the filter program
  *     @pfp: the unattached filter that is created
+ *     @fprog: the filter program
  *
  * Create a filter independent of any socket. We first run some
  * sanity checks on it to make sure it does not explode on us later.
index b618694..827dd6b 100644 (file)
@@ -74,61 +74,6 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
        return err;
 }
 
-/*
- *     Copy kernel to iovec. Returns -EFAULT on error.
- */
-
-int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
-                     int offset, int len)
-{
-       int copy;
-       for (; len > 0; ++iov) {
-               /* Skip over the finished iovecs */
-               if (unlikely(offset >= iov->iov_len)) {
-                       offset -= iov->iov_len;
-                       continue;
-               }
-               copy = min_t(unsigned int, iov->iov_len - offset, len);
-               if (copy_to_user(iov->iov_base + offset, kdata, copy))
-                       return -EFAULT;
-               offset = 0;
-               kdata += copy;
-               len -= copy;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(memcpy_toiovecend);
-
-/*
- *     Copy iovec to kernel. Returns -EFAULT on error.
- */
-
-int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
-                       int offset, int len)
-{
-       /* Skip over the finished iovecs */
-       while (offset >= iov->iov_len) {
-               offset -= iov->iov_len;
-               iov++;
-       }
-
-       while (len > 0) {
-               u8 __user *base = iov->iov_base + offset;
-               int copy = min_t(unsigned int, len, iov->iov_len - offset);
-
-               offset = 0;
-               if (copy_from_user(kdata, base, copy))
-                       return -EFAULT;
-               len -= copy;
-               kdata += copy;
-               iov++;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(memcpy_fromiovecend);
-
 /*
  *     And now for the all-in-one: copy and checksum from a user iovec
  *     directly to a datagram
index 9cd5344..c1a3303 100644 (file)
@@ -2993,7 +2993,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
                                                            skb_put(nskb, len),
                                                            len, 0);
                        SKB_GSO_CB(nskb)->csum_start =
-                           skb_headroom(nskb) + offset;
+                           skb_headroom(nskb) + doffset;
                        continue;
                }
 
index 097b3e7..54b6731 100644 (file)
@@ -73,12 +73,7 @@ static void __tunnel_dst_set(struct ip_tunnel_dst *idst,
 {
        struct dst_entry *old_dst;
 
-       if (dst) {
-               if (dst->flags & DST_NOCACHE)
-                       dst = NULL;
-               else
-                       dst_clone(dst);
-       }
+       dst_clone(dst);
        old_dst = xchg((__force struct dst_entry **)&idst->dst, dst);
        dst_release(old_dst);
 }
@@ -108,13 +103,14 @@ static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie)
 
        rcu_read_lock();
        dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst);
+       if (dst && !atomic_inc_not_zero(&dst->__refcnt))
+               dst = NULL;
        if (dst) {
                if (dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
-                       rcu_read_unlock();
                        tunnel_dst_reset(t);
-                       return NULL;
+                       dst_release(dst);
+                       dst = NULL;
                }
-               dst_hold(dst);
        }
        rcu_read_unlock();
        return (struct rtable *)dst;
index 62e48cf..9771563 100644 (file)
@@ -131,7 +131,7 @@ static bool tcp_fastopen_create_child(struct sock *sk,
                                      struct dst_entry *dst,
                                      struct request_sock *req)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
+       struct tcp_sock *tp;
        struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
        struct sock *child;
 
index 40661fc..b5c2375 100644 (file)
@@ -1162,7 +1162,7 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
                        unsigned int new_len = (pkt_len / mss) * mss;
                        if (!in_sack && new_len < pkt_len) {
                                new_len += mss;
-                               if (new_len > skb->len)
+                               if (new_len >= skb->len)
                                        return 0;
                        }
                        pkt_len = new_len;
index c42e83d..581a658 100644 (file)
@@ -3778,6 +3778,7 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
        cancel_delayed_work_sync(&ipvs->defense_work);
        cancel_work_sync(&ipvs->defense_work.work);
        unregister_net_sysctl_table(ipvs->sysctl_hdr);
+       ip_vs_stop_estimator(net, &ipvs->tot_stats);
 }
 
 #else
@@ -3840,7 +3841,6 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
        struct netns_ipvs *ipvs = net_ipvs(net);
 
        ip_vs_trash_cleanup(net);
-       ip_vs_stop_estimator(net, &ipvs->tot_stats);
        ip_vs_control_net_cleanup_sysctl(net);
        remove_proc_entry("ip_vs_stats_percpu", net->proc_net);
        remove_proc_entry("ip_vs_stats", net->proc_net);
index 5857963..300ed1e 100644 (file)
@@ -596,6 +596,9 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct)
 #endif
 #ifdef CONFIG_NF_CONNTRACK_MARK
               + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
+#endif
+#ifdef CONFIG_NF_CONNTRACK_ZONES
+              + nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
 #endif
               + ctnetlink_proto_size(ct)
               + ctnetlink_label_size(ct)
@@ -1150,7 +1153,7 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
 static int
 ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
 {
-       struct nf_conn *ct, *last = NULL;
+       struct nf_conn *ct, *last;
        struct nf_conntrack_tuple_hash *h;
        struct hlist_nulls_node *n;
        struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
@@ -1163,8 +1166,7 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
        if (cb->args[2])
                return 0;
 
-       if (cb->args[0] == nr_cpu_ids)
-               return 0;
+       last = (struct nf_conn *)cb->args[1];
 
        for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
                struct ct_pcpu *pcpu;
@@ -1174,7 +1176,6 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
 
                pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
                spin_lock_bh(&pcpu->lock);
-               last = (struct nf_conn *)cb->args[1];
                list = dying ? &pcpu->dying : &pcpu->unconfirmed;
 restart:
                hlist_nulls_for_each_entry(h, n, list, hnnode) {
@@ -1193,7 +1194,9 @@ restart:
                                                  ct);
                        rcu_read_unlock();
                        if (res < 0) {
-                               nf_conntrack_get(&ct->ct_general);
+                               if (!atomic_inc_not_zero(&ct->ct_general.use))
+                                       continue;
+                               cb->args[0] = cpu;
                                cb->args[1] = (unsigned long)ct;
                                spin_unlock_bh(&pcpu->lock);
                                goto out;
@@ -1202,10 +1205,10 @@ restart:
                if (cb->args[1]) {
                        cb->args[1] = 0;
                        goto restart;
-               } else
-                       cb->args[2] = 1;
+               }
                spin_unlock_bh(&pcpu->lock);
        }
+       cb->args[2] = 1;
 out:
        if (last)
                nf_ct_put(last);
@@ -2039,6 +2042,9 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
 #endif
 #ifdef CONFIG_NF_CONNTRACK_MARK
               + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
+#endif
+#ifdef CONFIG_NF_CONNTRACK_ZONES
+              + nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
 #endif
               + ctnetlink_proto_size(ct)
               ;
index 09096a6..a49907b 100644 (file)
@@ -525,6 +525,39 @@ static int nf_nat_proto_remove(struct nf_conn *i, void *data)
        return i->status & IPS_NAT_MASK ? 1 : 0;
 }
 
+static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
+{
+       struct nf_conn_nat *nat = nfct_nat(ct);
+
+       if (nf_nat_proto_remove(ct, data))
+               return 1;
+
+       if (!nat || !nat->ct)
+               return 0;
+
+       /* This netns is being destroyed, and conntrack has nat null binding.
+        * Remove it from bysource hash, as the table will be freed soon.
+        *
+        * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack()
+        * will delete entry from already-freed table.
+        */
+       if (!del_timer(&ct->timeout))
+               return 1;
+
+       spin_lock_bh(&nf_nat_lock);
+       hlist_del_rcu(&nat->bysource);
+       ct->status &= ~IPS_NAT_DONE_MASK;
+       nat->ct = NULL;
+       spin_unlock_bh(&nf_nat_lock);
+
+       add_timer(&ct->timeout);
+
+       /* don't delete conntrack.  Although that would make things a lot
+        * simpler, we'd end up flushing all conntracks on nat rmmod.
+        */
+       return 0;
+}
+
 static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
 {
        struct nf_nat_proto_clean clean = {
@@ -795,7 +828,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
 {
        struct nf_nat_proto_clean clean = {};
 
-       nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean, 0, 0);
+       nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean, 0, 0);
        synchronize_rcu();
        nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
 }
index 624e083..ab4566c 100644 (file)
@@ -1730,6 +1730,9 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
                if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
                        return -EINVAL;
                handle = nf_tables_alloc_handle(table);
+
+               if (chain->use == UINT_MAX)
+                       return -EOVERFLOW;
        }
 
        if (nla[NFTA_RULE_POSITION]) {
@@ -1789,14 +1792,15 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
 
        if (nlh->nlmsg_flags & NLM_F_REPLACE) {
                if (nft_rule_is_active_next(net, old_rule)) {
-                       trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE,
+                       trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
                                                   old_rule);
                        if (trans == NULL) {
                                err = -ENOMEM;
                                goto err2;
                        }
                        nft_rule_disactivate_next(net, old_rule);
-                       list_add_tail(&rule->list, &old_rule->list);
+                       chain->use--;
+                       list_add_tail_rcu(&rule->list, &old_rule->list);
                } else {
                        err = -ENOENT;
                        goto err2;
@@ -1826,6 +1830,7 @@ err3:
                list_del_rcu(&nft_trans_rule(trans)->list);
                nft_rule_clear(net, nft_trans_rule(trans));
                nft_trans_destroy(trans);
+               chain->use++;
        }
 err2:
        nf_tables_rule_destroy(&ctx, rule);
@@ -2845,7 +2850,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
                goto nla_put_failure;
 
        nfmsg = nlmsg_data(nlh);
-       nfmsg->nfgen_family = NFPROTO_UNSPEC;
+       nfmsg->nfgen_family = ctx.afi->family;
        nfmsg->version      = NFNETLINK_V0;
        nfmsg->res_id       = 0;
 
index 8a779be..1840989 100644 (file)
@@ -195,6 +195,15 @@ static void
 nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
 {
        struct xt_target *target = expr->ops->data;
+       void *info = nft_expr_priv(expr);
+       struct xt_tgdtor_param par;
+
+       par.net = ctx->net;
+       par.target = target;
+       par.targinfo = info;
+       par.family = ctx->afi->family;
+       if (par.target->destroy != NULL)
+               par.target->destroy(&par);
 
        module_put(target->me);
 }
@@ -382,6 +391,15 @@ static void
 nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
 {
        struct xt_match *match = expr->ops->data;
+       void *info = nft_expr_priv(expr);
+       struct xt_mtdtor_param par;
+
+       par.net = ctx->net;
+       par.match = match;
+       par.matchinfo = info;
+       par.family = ctx->afi->family;
+       if (par.match->destroy != NULL)
+               par.match->destroy(&par);
 
        module_put(match->me);
 }
index a0195d2..79ff58c 100644 (file)
@@ -175,12 +175,14 @@ static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr)
        if (nla_put_be32(skb,
                         NFTA_NAT_REG_ADDR_MAX, htonl(priv->sreg_addr_max)))
                goto nla_put_failure;
-       if (nla_put_be32(skb,
-                        NFTA_NAT_REG_PROTO_MIN, htonl(priv->sreg_proto_min)))
-               goto nla_put_failure;
-       if (nla_put_be32(skb,
-                        NFTA_NAT_REG_PROTO_MAX, htonl(priv->sreg_proto_max)))
-               goto nla_put_failure;
+       if (priv->sreg_proto_min) {
+               if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN,
+                                htonl(priv->sreg_proto_min)))
+                       goto nla_put_failure;
+               if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX,
+                                htonl(priv->sreg_proto_max)))
+                       goto nla_put_failure;
+       }
        return 0;
 
 nla_put_failure:
index dcb1959..12c7e01 100644 (file)
@@ -321,41 +321,40 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
                                loff_t *ppos)
 {
        struct net *net = current->nsproxy->net_ns;
-       char tmp[8];
        struct ctl_table tbl;
-       int ret;
-       int changed = 0;
+       bool changed = false;
        char *none = "none";
+       char tmp[8];
+       int ret;
 
        memset(&tbl, 0, sizeof(struct ctl_table));
 
        if (write) {
                tbl.data = tmp;
-               tbl.maxlen = 8;
+               tbl.maxlen = sizeof(tmp);
        } else {
                tbl.data = net->sctp.sctp_hmac_alg ? : none;
                tbl.maxlen = strlen(tbl.data);
        }
-               ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
 
-       if (write) {
+       ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
+       if (write && ret == 0) {
 #ifdef CONFIG_CRYPTO_MD5
                if (!strncmp(tmp, "md5", 3)) {
                        net->sctp.sctp_hmac_alg = "md5";
-                       changed = 1;
+                       changed = true;
                }
 #endif
 #ifdef CONFIG_CRYPTO_SHA1
                if (!strncmp(tmp, "sha1", 4)) {
                        net->sctp.sctp_hmac_alg = "sha1";
-                       changed = 1;
+                       changed = true;
                }
 #endif
                if (!strncmp(tmp, "none", 4)) {
                        net->sctp.sctp_hmac_alg = NULL;
-                       changed = 1;
+                       changed = true;
                }
-
                if (!changed)
                        ret = -EINVAL;
        }
@@ -368,11 +367,10 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
                                loff_t *ppos)
 {
        struct net *net = current->nsproxy->net_ns;
-       int new_value;
-       struct ctl_table tbl;
        unsigned int min = *(unsigned int *) ctl->extra1;
        unsigned int max = *(unsigned int *) ctl->extra2;
-       int ret;
+       struct ctl_table tbl;
+       int ret, new_value;
 
        memset(&tbl, 0, sizeof(struct ctl_table));
        tbl.maxlen = sizeof(unsigned int);
@@ -381,12 +379,15 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
                tbl.data = &new_value;
        else
                tbl.data = &net->sctp.rto_min;
+
        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
-       if (write) {
-               if (ret || new_value > max || new_value < min)
+       if (write && ret == 0) {
+               if (new_value > max || new_value < min)
                        return -EINVAL;
+
                net->sctp.rto_min = new_value;
        }
+
        return ret;
 }
 
@@ -395,11 +396,10 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
                                loff_t *ppos)
 {
        struct net *net = current->nsproxy->net_ns;
-       int new_value;
-       struct ctl_table tbl;
        unsigned int min = *(unsigned int *) ctl->extra1;
        unsigned int max = *(unsigned int *) ctl->extra2;
-       int ret;
+       struct ctl_table tbl;
+       int ret, new_value;
 
        memset(&tbl, 0, sizeof(struct ctl_table));
        tbl.maxlen = sizeof(unsigned int);
@@ -408,12 +408,15 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
                tbl.data = &new_value;
        else
                tbl.data = &net->sctp.rto_max;
+
        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
-       if (write) {
-               if (ret || new_value > max || new_value < min)
+       if (write && ret == 0) {
+               if (new_value > max || new_value < min)
                        return -EINVAL;
+
                net->sctp.rto_max = new_value;
        }
+
        return ret;
 }
 
@@ -444,8 +447,7 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
                tbl.data = &net->sctp.auth_enable;
 
        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
-
-       if (write) {
+       if (write && ret == 0) {
                struct sock *sk = net->sctp.ctl_sock;
 
                net->sctp.auth_enable = new_value;
index 247e973..f773667 100644 (file)
@@ -592,6 +592,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
        put_group_info(acred.group_info);
        return ret;
 }
+EXPORT_SYMBOL_GPL(rpcauth_lookupcred);
 
 void
 rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
index 6af3732..4b0113f 100644 (file)
@@ -56,7 +56,8 @@
  * struct:  This defines the way the data will be stored in the ring buffer.
  *    There are currently two types of elements. __field and __array.
  *    a __field is broken up into (type, name). Where type can be any
- *    type but an array.
+ *    primitive type (integer, long or pointer). __field_struct() can
+ *    be any static complex data value (struct, union, but not an array).
  *    For an array. there are three fields. (type, name, size). The
  *    type of elements in the array, the name of the field and the size
  *    of the array.
index 010b18e..182be0f 100755 (executable)
@@ -3476,12 +3476,17 @@ sub process {
                        }
                }
 
-# unnecessary return in a void function? (a single leading tab, then return;)
-               if ($sline =~ /^\+\treturn\s*;\s*$/ &&
-                   $prevline =~ /^\+/) {
+# unnecessary return in a void function
+# at end-of-function, with the previous line a single leading tab, then return;
+# and the line before that not a goto label target like "out:"
+               if ($sline =~ /^[ \+]}\s*$/ &&
+                   $prevline =~ /^\+\treturn\s*;\s*$/ &&
+                   $linenr >= 3 &&
+                   $lines[$linenr - 3] =~ /^[ +]/ &&
+                   $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
                        WARN("RETURN_VOID",
-                            "void function return statements are not generally useful\n" . $herecurr);
-               }
+                            "void function return statements are not generally useful\n" . $hereprev);
+               }
 
 # if statements using unnecessary parentheses - ie: if ((foo == bar))
                if ($^V && $^V ge 5.10.0 &&
index b5f08f7..35d5a58 100644 (file)
@@ -289,14 +289,16 @@ EOF
 
 fi
 
-# Build header package
-(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles")
-(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> "$objtree/debian/hdrsrcfiles")
-(cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles")
+# Build kernel header package
+(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles"
+(cd $srctree; find arch/$SRCARCH/include include scripts -type f) >> "$objtree/debian/hdrsrcfiles"
+(cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
+(cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
+(cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles"
 destdir=$kernel_headers_dir/usr/src/linux-headers-$version
 mkdir -p "$destdir"
-(cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -)
-(cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -)
+(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
+(cd $objtree; tar -c -f - -T -) < "$objtree/debian/hdrobjfiles" | (cd $destdir; tar -xf -)
 (cd $objtree; cp $KCONFIG_CONFIG $destdir/.config) # copy .config manually to be where it's expected to be
 ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build"
 rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
index 995c1ea..e046bff 100644 (file)
@@ -125,12 +125,11 @@ esac
 # Create the tarball
 #
 (
-       cd "${tmpdir}"
        opts=
        if tar --owner=root --group=root --help >/dev/null 2>&1; then
                opts="--owner=root --group=root"
        fi
-       tar cf - boot/* lib/* $opts | ${compress} > "${tarball}${file_ext}"
+       tar cf - -C "$tmpdir" boot/ lib/ $opts | ${compress} > "${tarball}${file_ext}"
 )
 
 echo "Tarball successfully created in ${tarball}${file_ext}"
index 9d1421e..49b582a 100644 (file)
@@ -163,11 +163,11 @@ static int mcount_adjust = 0;
 
 static int MIPS_is_fake_mcount(Elf_Rel const *rp)
 {
-       static Elf_Addr old_r_offset;
+       static Elf_Addr old_r_offset = ~(Elf_Addr)0;
        Elf_Addr current_r_offset = _w(rp->r_offset);
        int is_fake;
 
-       is_fake = old_r_offset &&
+       is_fake = (old_r_offset != ~(Elf_Addr)0) &&
                (current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET);
        old_r_offset = current_r_offset;
 
index f038f5a..f0b0e14 100644 (file)
@@ -288,6 +288,10 @@ static bool snd_ctl_remove_numid_conflict(struct snd_card *card,
 {
        struct snd_kcontrol *kctl;
 
+       /* Make sure that the ids assigned to the control do not wrap around */
+       if (card->last_numid >= UINT_MAX - count)
+               card->last_numid = 0;
+
        list_for_each_entry(kctl, &card->controls, list) {
                if (kctl->id.numid < card->last_numid + 1 + count &&
                    kctl->id.numid + kctl->count > card->last_numid + 1) {
@@ -330,6 +334,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
 {
        struct snd_ctl_elem_id id;
        unsigned int idx;
+       unsigned int count;
        int err = -EINVAL;
 
        if (! kcontrol)
@@ -337,6 +342,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
        if (snd_BUG_ON(!card || !kcontrol->info))
                goto error;
        id = kcontrol->id;
+       if (id.index > UINT_MAX - kcontrol->count)
+               goto error;
+
        down_write(&card->controls_rwsem);
        if (snd_ctl_find_id(card, &id)) {
                up_write(&card->controls_rwsem);
@@ -358,8 +366,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
        card->controls_count += kcontrol->count;
        kcontrol->id.numid = card->last_numid + 1;
        card->last_numid += kcontrol->count;
+       count = kcontrol->count;
        up_write(&card->controls_rwsem);
-       for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
+       for (idx = 0; idx < count; idx++, id.index++, id.numid++)
                snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
        return 0;
 
@@ -388,6 +397,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
                    bool add_on_replace)
 {
        struct snd_ctl_elem_id id;
+       unsigned int count;
        unsigned int idx;
        struct snd_kcontrol *old;
        int ret;
@@ -423,8 +433,9 @@ add:
        card->controls_count += kcontrol->count;
        kcontrol->id.numid = card->last_numid + 1;
        card->last_numid += kcontrol->count;
+       count = kcontrol->count;
        up_write(&card->controls_rwsem);
-       for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
+       for (idx = 0; idx < count; idx++, id.index++, id.numid++)
                snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
        return 0;
 
@@ -897,9 +908,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
                        result = kctl->put(kctl, control);
                }
                if (result > 0) {
+                       struct snd_ctl_elem_id id = control->id;
                        up_read(&card->controls_rwsem);
-                       snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
-                                      &control->id);
+                       snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
                        return 0;
                }
        }
@@ -991,6 +1002,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
 
 struct user_element {
        struct snd_ctl_elem_info info;
+       struct snd_card *card;
        void *elem_data;                /* element data */
        unsigned long elem_data_size;   /* size of element data in bytes */
        void *tlv_data;                 /* TLV data */
@@ -1034,7 +1046,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
 {
        struct user_element *ue = kcontrol->private_data;
 
+       mutex_lock(&ue->card->user_ctl_lock);
        memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
+       mutex_unlock(&ue->card->user_ctl_lock);
        return 0;
 }
 
@@ -1043,10 +1057,12 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
 {
        int change;
        struct user_element *ue = kcontrol->private_data;
-       
+
+       mutex_lock(&ue->card->user_ctl_lock);
        change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
        if (change)
                memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
+       mutex_unlock(&ue->card->user_ctl_lock);
        return change;
 }
 
@@ -1066,19 +1082,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
                new_data = memdup_user(tlv, size);
                if (IS_ERR(new_data))
                        return PTR_ERR(new_data);
+               mutex_lock(&ue->card->user_ctl_lock);
                change = ue->tlv_data_size != size;
                if (!change)
                        change = memcmp(ue->tlv_data, new_data, size);
                kfree(ue->tlv_data);
                ue->tlv_data = new_data;
                ue->tlv_data_size = size;
+               mutex_unlock(&ue->card->user_ctl_lock);
        } else {
-               if (! ue->tlv_data_size || ! ue->tlv_data)
-                       return -ENXIO;
-               if (size < ue->tlv_data_size)
-                       return -ENOSPC;
+               int ret = 0;
+
+               mutex_lock(&ue->card->user_ctl_lock);
+               if (!ue->tlv_data_size || !ue->tlv_data) {
+                       ret = -ENXIO;
+                       goto err_unlock;
+               }
+               if (size < ue->tlv_data_size) {
+                       ret = -ENOSPC;
+                       goto err_unlock;
+               }
                if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
-                       return -EFAULT;
+                       ret = -EFAULT;
+err_unlock:
+               mutex_unlock(&ue->card->user_ctl_lock);
+               if (ret)
+                       return ret;
        }
        return change;
 }
@@ -1136,8 +1165,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
        struct user_element *ue;
        int idx, err;
 
-       if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
-               return -ENOMEM;
        if (info->count < 1)
                return -EINVAL;
        access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
@@ -1146,21 +1173,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
                                 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
        info->id.numid = 0;
        memset(&kctl, 0, sizeof(kctl));
-       down_write(&card->controls_rwsem);
-       _kctl = snd_ctl_find_id(card, &info->id);
-       err = 0;
-       if (_kctl) {
-               if (replace)
-                       err = snd_ctl_remove(card, _kctl);
-               else
-                       err = -EBUSY;
-       } else {
-               if (replace)
-                       err = -ENOENT;
+
+       if (replace) {
+               err = snd_ctl_remove_user_ctl(file, &info->id);
+               if (err)
+                       return err;
        }
-       up_write(&card->controls_rwsem);
-       if (err < 0)
-               return err;
+
+       if (card->user_ctl_count >= MAX_USER_CONTROLS)
+               return -ENOMEM;
+
        memcpy(&kctl.id, &info->id, sizeof(info->id));
        kctl.count = info->owner ? info->owner : 1;
        access |= SNDRV_CTL_ELEM_ACCESS_USER;
@@ -1210,6 +1232,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
        ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
        if (ue == NULL)
                return -ENOMEM;
+       ue->card = card;
        ue->info = *info;
        ue->info.access = 0;
        ue->elem_data = (char *)ue + sizeof(*ue);
@@ -1321,8 +1344,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
                }
                err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
                if (err > 0) {
+                       struct snd_ctl_elem_id id = kctl->id;
                        up_read(&card->controls_rwsem);
-                       snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
+                       snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id);
                        return 0;
                }
        } else {
index 5ee8384..7bdfd19 100644 (file)
@@ -232,6 +232,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
        INIT_LIST_HEAD(&card->devices);
        init_rwsem(&card->controls_rwsem);
        rwlock_init(&card->ctl_files_rwlock);
+       mutex_init(&card->user_ctl_lock);
        INIT_LIST_HEAD(&card->controls);
        INIT_LIST_HEAD(&card->ctl_files);
        spin_lock_init(&card->files_lock);
index b684c6e..dabe419 100644 (file)
@@ -898,6 +898,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
                        if (!strcmp(codec->modelname, models->name)) {
                                codec->fixup_id = models->id;
                                codec->fixup_name = models->name;
+                               codec->fixup_list = fixlist;
                                codec->fixup_forced = 1;
                                return;
                        }
index 9d07e4e..e9e8a4a 100644 (file)
 #include <drm/i915_powerwell.h>
 #include "hda_i915.h"
 
-static void (*get_power)(void);
-static void (*put_power)(void);
+static int (*get_power)(void);
+static int (*put_power)(void);
 
-void hda_display_power(bool enable)
+int hda_display_power(bool enable)
 {
        if (!get_power || !put_power)
-               return;
+               return -ENODEV;
 
        pr_debug("HDA display power %s \n",
                        enable ? "Enable" : "Disable");
        if (enable)
-               get_power();
+               return get_power();
        else
-               put_power();
+               return put_power();
 }
 
 int hda_i915_init(void)
index 5a63da2..bfd835f 100644 (file)
 #define __SOUND_HDA_I915_H
 
 #ifdef CONFIG_SND_HDA_I915
-void hda_display_power(bool enable);
+int hda_display_power(bool enable);
 int hda_i915_init(void);
 int hda_i915_exit(void);
 #else
-static inline void hda_display_power(bool enable) {}
+static inline int hda_display_power(bool enable) { return 0; }
 static inline int hda_i915_init(void)
 {
        return -ENODEV;
index bb65a12..25753db 100644 (file)
@@ -288,6 +288,24 @@ static char *driver_short_names[] = {
        [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
 };
 
+
+/* Intel HSW/BDW display HDA controller Extended Mode registers.
+ * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display
+ * Clock) to 24MHz BCLK: BCLK = CDCLK * M / N
+ * The values will be lost when the display power well is disabled.
+ */
+#define ICH6_REG_EM4                   0x100c
+#define ICH6_REG_EM5                   0x1010
+
+struct hda_intel {
+       struct azx chip;
+
+       /* HSW/BDW display HDA controller to restore BCLK from CDCLK */
+       unsigned int bclk_m;
+       unsigned int bclk_n;
+};
+
+
 #ifdef CONFIG_X86
 static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
 {
@@ -580,6 +598,22 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
 #define azx_del_card_list(chip) /* NOP */
 #endif /* CONFIG_PM */
 
+static void haswell_save_bclk(struct azx *chip)
+{
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
+       hda->bclk_m = azx_readw(chip, EM4);
+       hda->bclk_n = azx_readw(chip, EM5);
+}
+
+static void haswell_restore_bclk(struct azx *chip)
+{
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
+       azx_writew(chip, EM4, hda->bclk_m);
+       azx_writew(chip, EM5, hda->bclk_n);
+}
+
 #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
 /*
  * power management
@@ -606,6 +640,13 @@ static int azx_suspend(struct device *dev)
                free_irq(chip->irq, chip);
                chip->irq = -1;
        }
+
+       /* Save BCLK M/N values before they become invalid in D3.
+        * Will test if display power well can be released now.
+        */
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+               haswell_save_bclk(chip);
+
        if (chip->msi)
                pci_disable_msi(chip->pci);
        pci_disable_device(pci);
@@ -625,8 +666,10 @@ static int azx_resume(struct device *dev)
        if (chip->disabled)
                return 0;
 
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
                hda_display_power(true);
+               haswell_restore_bclk(chip);
+       }
        pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
        if (pci_enable_device(pci) < 0) {
@@ -670,8 +713,10 @@ static int azx_runtime_suspend(struct device *dev)
        azx_stop_chip(chip);
        azx_enter_link_reset(chip);
        azx_clear_irq_pending(chip);
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+               haswell_save_bclk(chip);
                hda_display_power(false);
+       }
        return 0;
 }
 
@@ -689,8 +734,10 @@ static int azx_runtime_resume(struct device *dev)
        if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
                return 0;
 
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
                hda_display_power(true);
+               haswell_restore_bclk(chip);
+       }
 
        /* Read STATESTS before controller reset */
        status = azx_readw(chip, STATESTS);
@@ -883,6 +930,8 @@ static int register_vga_switcheroo(struct azx *chip)
 static int azx_free(struct azx *chip)
 {
        struct pci_dev *pci = chip->pci;
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
        int i;
 
        if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
@@ -930,7 +979,7 @@ static int azx_free(struct azx *chip)
                hda_display_power(false);
                hda_i915_exit();
        }
-       kfree(chip);
+       kfree(hda);
 
        return 0;
 }
@@ -1174,6 +1223,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
        static struct snd_device_ops ops = {
                .dev_free = azx_dev_free,
        };
+       struct hda_intel *hda;
        struct azx *chip;
        int err;
 
@@ -1183,13 +1233,14 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
        if (err < 0)
                return err;
 
-       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-       if (!chip) {
-               dev_err(card->dev, "Cannot allocate chip\n");
+       hda = kzalloc(sizeof(*hda), GFP_KERNEL);
+       if (!hda) {
+               dev_err(card->dev, "Cannot allocate hda\n");
                pci_disable_device(pci);
                return -ENOMEM;
        }
 
+       chip = &hda->chip;
        spin_lock_init(&chip->reg_lock);
        mutex_init(&chip->open_mutex);
        chip->card = card;
@@ -1656,8 +1707,13 @@ static int azx_probe_continue(struct azx *chip)
                                "Error request power-well from i915\n");
                        goto out_free;
                }
+               err = hda_display_power(true);
+               if (err < 0) {
+                       dev_err(chip->card->dev,
+                               "Cannot turn on display power on i915\n");
+                       goto out_free;
+               }
 #endif
-               hda_display_power(true);
        }
 
        err = azx_first_init(chip);
index ebd1fa6..4e2d486 100644 (file)
@@ -417,6 +417,27 @@ struct snd_hda_pin_quirk {
        int value;                      /* quirk value */
 };
 
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+
+#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
+       { .codec = _codec,\
+         .subvendor = _subvendor,\
+         .name = _name,\
+         .value = _value,\
+         .pins = (const struct hda_pintbl[]) { _pins } \
+       }
+#else
+
+#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
+       { .codec = _codec,\
+         .subvendor = _subvendor,\
+         .value = _value,\
+         .pins = (const struct hda_pintbl[]) { _pins } \
+       }
+
+#endif
+
+
 /* fixup types */
 enum {
        HDA_FIXUP_INVALID,
index 3e4417b..4fe876b 100644 (file)
@@ -2204,7 +2204,7 @@ static int generic_hdmi_resume(struct hda_codec *codec)
        struct hdmi_spec *spec = codec->spec;
        int pin_idx;
 
-       generic_hdmi_init(codec);
+       codec->patch_ops.init(codec);
        snd_hda_codec_resume_amp(codec);
        snd_hda_codec_resume_cache(codec);
 
index af76995..1c654ef 100644 (file)
@@ -4962,228 +4962,129 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
 };
 
 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
-       {
-               .codec = 0x10ec0255,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60140},
-                       {0x14, 0x90170110},
-                       {0x17, 0x40000000},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x02211020},
-               },
-               .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0255,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60160},
-                       {0x14, 0x90170120},
-                       {0x17, 0x40000000},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x02211030},
-               },
-               .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0255,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60160},
-                       {0x14, 0x90170120},
-                       {0x17, 0x90170140},
-                       {0x18, 0x40000000},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x41163b05},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x0321102f},
-               },
-               .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0255,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60160},
-                       {0x14, 0x90170130},
-                       {0x17, 0x40000000},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x02211040},
-               },
-               .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0255,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60160},
-                       {0x14, 0x90170140},
-                       {0x17, 0x40000000},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x02211050},
-               },
-               .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0255,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60170},
-                       {0x14, 0x90170120},
-                       {0x17, 0x40000000},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x02211030},
-               },
-               .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0255,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60170},
-                       {0x14, 0x90170130},
-                       {0x17, 0x40000000},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x02211040},
-               },
-               .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0283,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60130},
-                       {0x14, 0x90170110},
-                       {0x17, 0x40020008},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40e00001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x0321101f},
-               },
-               .value = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0283,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60160},
-                       {0x14, 0x90170120},
-                       {0x17, 0x40000000},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-                       {0x21, 0x02211030},
-               },
-               .value = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0292,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x90a60140},
-                       {0x13, 0x411111f0},
-                       {0x14, 0x90170110},
-                       {0x15, 0x0221401f},
-                       {0x16, 0x411111f0},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-               },
-               .value = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
-       },
-       {
-               .codec = 0x10ec0293,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x40000000},
-                       {0x13, 0x90a60140},
-                       {0x14, 0x90170110},
-                       {0x15, 0x0221401f},
-                       {0x16, 0x21014020},
-                       {0x18, 0x411111f0},
-                       {0x19, 0x21a19030},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x40700001},
-                       {0x1e, 0x411111f0},
-               },
-               .value = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
-       },
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60140},
+               {0x14, 0x90170110},
+               {0x17, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x02211020}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60160},
+               {0x14, 0x90170120},
+               {0x17, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x02211030}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60160},
+               {0x14, 0x90170120},
+               {0x17, 0x90170140},
+               {0x18, 0x40000000},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x41163b05},
+               {0x1e, 0x411111f0},
+               {0x21, 0x0321102f}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60160},
+               {0x14, 0x90170130},
+               {0x17, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x02211040}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60160},
+               {0x14, 0x90170140},
+               {0x17, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x02211050}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60170},
+               {0x14, 0x90170120},
+               {0x17, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x02211030}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60170},
+               {0x14, 0x90170130},
+               {0x17, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x02211040}),
+       SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60130},
+               {0x14, 0x90170110},
+               {0x17, 0x40020008},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40e00001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x0321101f}),
+       SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60160},
+               {0x14, 0x90170120},
+               {0x17, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0},
+               {0x21, 0x02211030}),
+       SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
+               {0x12, 0x90a60140},
+               {0x13, 0x411111f0},
+               {0x14, 0x90170110},
+               {0x15, 0x0221401f},
+               {0x16, 0x411111f0},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0}),
+       SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x40000000},
+               {0x13, 0x90a60140},
+               {0x14, 0x90170110},
+               {0x15, 0x0221401f},
+               {0x16, 0x21014020},
+               {0x18, 0x411111f0},
+               {0x19, 0x21a19030},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40700001},
+               {0x1e, 0x411111f0}),
        {}
 };
 
@@ -6039,90 +5940,66 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
 };
 
 static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
-       {
-               .codec = 0x10ec0668,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x99a30130},
-                       {0x14, 0x90170110},
-                       {0x15, 0x0321101f},
-                       {0x16, 0x03011020},
-                       {0x18, 0x40000008},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x41000001},
-                       {0x1e, 0x411111f0},
-                       {0x1f, 0x411111f0},
-               },
-               .value = ALC668_FIXUP_AUTO_MUTE,
-       },
-       {
-               .codec = 0x10ec0668,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x99a30140},
-                       {0x14, 0x90170110},
-                       {0x15, 0x0321101f},
-                       {0x16, 0x03011020},
-                       {0x18, 0x40000008},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x41000001},
-                       {0x1e, 0x411111f0},
-                       {0x1f, 0x411111f0},
-               },
-               .value = ALC668_FIXUP_AUTO_MUTE,
-       },
-       {
-               .codec = 0x10ec0668,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x99a30150},
-                       {0x14, 0x90170110},
-                       {0x15, 0x0321101f},
-                       {0x16, 0x03011020},
-                       {0x18, 0x40000008},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x41000001},
-                       {0x1e, 0x411111f0},
-                       {0x1f, 0x411111f0},
-               },
-               .value = ALC668_FIXUP_AUTO_MUTE,
-       },
-       {
-               .codec = 0x10ec0668,
-               .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-               .name = "Dell",
-#endif
-               .pins = (const struct hda_pintbl[]) {
-                       {0x12, 0x411111f0},
-                       {0x14, 0x90170110},
-                       {0x15, 0x0321101f},
-                       {0x16, 0x03011020},
-                       {0x18, 0x40000008},
-                       {0x19, 0x411111f0},
-                       {0x1a, 0x411111f0},
-                       {0x1b, 0x411111f0},
-                       {0x1d, 0x41000001},
-                       {0x1e, 0x411111f0},
-                       {0x1f, 0x411111f0},
-               },
-               .value = ALC668_FIXUP_AUTO_MUTE,
-       },
+       SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+               {0x12, 0x99a30130},
+               {0x14, 0x90170110},
+               {0x15, 0x0321101f},
+               {0x16, 0x03011020},
+               {0x18, 0x40000008},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x41000001},
+               {0x1e, 0x411111f0},
+               {0x1f, 0x411111f0}),
+       SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+               {0x12, 0x99a30140},
+               {0x14, 0x90170110},
+               {0x15, 0x0321101f},
+               {0x16, 0x03011020},
+               {0x18, 0x40000008},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x41000001},
+               {0x1e, 0x411111f0},
+               {0x1f, 0x411111f0}),
+       SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+               {0x12, 0x99a30150},
+               {0x14, 0x90170110},
+               {0x15, 0x0321101f},
+               {0x16, 0x03011020},
+               {0x18, 0x40000008},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x41000001},
+               {0x1e, 0x411111f0},
+               {0x1f, 0x411111f0}),
+       SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+               {0x12, 0x411111f0},
+               {0x14, 0x90170110},
+               {0x15, 0x0321101f},
+               {0x16, 0x03011020},
+               {0x18, 0x40000008},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x41000001},
+               {0x1e, 0x411111f0},
+               {0x1f, 0x411111f0}),
+       SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
+               {0x12, 0x90a60130},
+               {0x14, 0x90170110},
+               {0x15, 0x0321101f},
+               {0x16, 0x40000000},
+               {0x18, 0x411111f0},
+               {0x19, 0x411111f0},
+               {0x1a, 0x411111f0},
+               {0x1b, 0x411111f0},
+               {0x1d, 0x40d6832d},
+               {0x1e, 0x411111f0},
+               {0x1f, 0x411111f0}),
        {}
 };
 
index 7f40a15..3744ea4 100644 (file)
@@ -121,6 +121,12 @@ enum {
        STAC_92HD71BXX_MODELS
 };
 
+enum {
+       STAC_92HD95_HP_LED,
+       STAC_92HD95_HP_BASS,
+       STAC_92HD95_MODELS
+};
+
 enum {
        STAC_925x_REF,
        STAC_M1,
@@ -4128,6 +4134,48 @@ static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
        {} /* terminator */
 };
 
+static void stac92hd95_fixup_hp_led(struct hda_codec *codec,
+                                   const struct hda_fixup *fix, int action)
+{
+       struct sigmatel_spec *spec = codec->spec;
+
+       if (action != HDA_FIXUP_ACT_PRE_PROBE)
+               return;
+
+       if (find_mute_led_cfg(codec, spec->default_polarity))
+               codec_dbg(codec, "mute LED gpio %d polarity %d\n",
+                               spec->gpio_led,
+                               spec->gpio_led_polarity);
+}
+
+static const struct hda_fixup stac92hd95_fixups[] = {
+       [STAC_92HD95_HP_LED] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = stac92hd95_fixup_hp_led,
+       },
+       [STAC_92HD95_HP_BASS] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       {0x1a, 0x795, 0x00}, /* HPF to 100Hz */
+                       {}
+               },
+               .chained = true,
+               .chain_id = STAC_92HD95_HP_LED,
+       },
+};
+
+static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = {
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS),
+       {} /* terminator */
+};
+
+static const struct hda_model_fixup stac92hd95_models[] = {
+       { .id = STAC_92HD95_HP_LED, .name = "hp-led" },
+       { .id = STAC_92HD95_HP_BASS, .name = "hp-bass" },
+       {}
+};
+
+
 static int stac_parse_auto_config(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec = codec->spec;
@@ -4580,10 +4628,16 @@ static int patch_stac92hd95(struct hda_codec *codec)
        spec->gen.beep_nid = 0x19; /* digital beep */
        spec->pwr_nids = stac92hd95_pwr_nids;
        spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids);
-       spec->default_polarity = -1; /* no default cfg */
+       spec->default_polarity = 0;
 
        codec->patch_ops = stac_patch_ops;
 
+       snd_hda_pick_fixup(codec, stac92hd95_models, stac92hd95_fixup_tbl,
+                          stac92hd95_fixups);
+       snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
+       stac_setup_gpio(codec);
+
        err = stac_parse_auto_config(codec);
        if (err < 0) {
                stac_free(codec);
@@ -4592,6 +4646,8 @@ static int patch_stac92hd95(struct hda_codec *codec)
 
        codec->proc_widget_hook = stac92hd_proc_hook;
 
+       snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+
        return 0;
 }
 
index cbfa1e1..0b9571c 100644 (file)
@@ -225,11 +225,11 @@ config SND_SOC_ADAU1373
 config SND_SOC_ADAU1701
        tristate "Analog Devices ADAU1701 CODEC"
        depends on I2C
-       select SND_SOC_SIGMADSP
+       select SND_SOC_SIGMADSP_I2C
 
 config SND_SOC_ADAU17X1
        tristate
-       select SND_SOC_SIGMADSP
+       select SND_SOC_SIGMADSP_REGMAP
 
 config SND_SOC_ADAU1761
        tristate
@@ -476,6 +476,14 @@ config SND_SOC_SIGMADSP
        tristate
        select CRC32
 
+config SND_SOC_SIGMADSP_I2C
+       tristate
+       select SND_SOC_SIGMADSP
+
+config SND_SOC_SIGMADSP_REGMAP
+       tristate
+       select SND_SOC_SIGMADSP
+
 config SND_SOC_SIRF_AUDIO_CODEC
        tristate "SiRF SoC internal audio codec"
        select REGMAP_MMIO
index be3377b..1bd6e1c 100644 (file)
@@ -77,6 +77,8 @@ snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-alc5632-objs := alc5632.o
 snd-soc-sigmadsp-objs := sigmadsp.o
+snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
+snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
 snd-soc-si476x-objs := si476x.o
 snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
 snd-soc-sn95031-objs := sn95031.o
@@ -240,6 +242,8 @@ obj-$(CONFIG_SND_SOC_RT5651)        += snd-soc-rt5651.o
 obj-$(CONFIG_SND_SOC_RT5677)   += snd-soc-rt5677.o
 obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
+obj-$(CONFIG_SND_SOC_SIGMADSP_I2C)     += snd-soc-sigmadsp-i2c.o
+obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP)  += snd-soc-sigmadsp-regmap.o
 obj-$(CONFIG_SND_SOC_SI476X)   += snd-soc-si476x.o
 obj-$(CONFIG_SND_SOC_SN95031)  +=snd-soc-sn95031.o
 obj-$(CONFIG_SND_SOC_SPDIF)    += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
diff --git a/sound/soc/codecs/sigmadsp-i2c.c b/sound/soc/codecs/sigmadsp-i2c.c
new file mode 100644 (file)
index 0000000..246081a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Load Analog Devices SigmaStudio firmware files
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/i2c.h>
+#include <linux/export.h>
+#include <linux/module.h>
+
+#include "sigmadsp.h"
+
+static int sigma_action_write_i2c(void *control_data,
+       const struct sigma_action *sa, size_t len)
+{
+       return i2c_master_send(control_data, (const unsigned char *)&sa->addr,
+               len);
+}
+
+int process_sigma_firmware(struct i2c_client *client, const char *name)
+{
+       struct sigma_firmware ssfw;
+
+       ssfw.control_data = client;
+       ssfw.write = sigma_action_write_i2c;
+
+       return _process_sigma_firmware(&client->dev, &ssfw, name);
+}
+EXPORT_SYMBOL(process_sigma_firmware);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("SigmaDSP I2C firmware loader");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sigmadsp-regmap.c b/sound/soc/codecs/sigmadsp-regmap.c
new file mode 100644 (file)
index 0000000..f78ed8d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Load Analog Devices SigmaStudio firmware files
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/regmap.h>
+#include <linux/export.h>
+#include <linux/module.h>
+
+#include "sigmadsp.h"
+
+static int sigma_action_write_regmap(void *control_data,
+       const struct sigma_action *sa, size_t len)
+{
+       return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
+               sa->payload, len - 2);
+}
+
+int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap,
+       const char *name)
+{
+       struct sigma_firmware ssfw;
+
+       ssfw.control_data = regmap;
+       ssfw.write = sigma_action_write_regmap;
+
+       return _process_sigma_firmware(dev, &ssfw, name);
+}
+EXPORT_SYMBOL(process_sigma_firmware_regmap);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("SigmaDSP regmap firmware loader");
+MODULE_LICENSE("GPL");
index 4068f24..f2de7e0 100644 (file)
@@ -34,23 +34,6 @@ enum {
        SIGMA_ACTION_END,
 };
 
-struct sigma_action {
-       u8 instr;
-       u8 len_hi;
-       __le16 len;
-       __be16 addr;
-       unsigned char payload[];
-} __packed;
-
-struct sigma_firmware {
-       const struct firmware *fw;
-       size_t pos;
-
-       void *control_data;
-       int (*write)(void *control_data, const struct sigma_action *sa,
-                       size_t len);
-};
-
 static inline u32 sigma_action_len(struct sigma_action *sa)
 {
        return (sa->len_hi << 16) | le16_to_cpu(sa->len);
@@ -138,7 +121,7 @@ process_sigma_actions(struct sigma_firmware *ssfw)
        return 0;
 }
 
-static int _process_sigma_firmware(struct device *dev,
+int _process_sigma_firmware(struct device *dev,
        struct sigma_firmware *ssfw, const char *name)
 {
        int ret;
@@ -197,50 +180,6 @@ static int _process_sigma_firmware(struct device *dev,
 
        return ret;
 }
-
-#if IS_ENABLED(CONFIG_I2C)
-
-static int sigma_action_write_i2c(void *control_data,
-       const struct sigma_action *sa, size_t len)
-{
-       return i2c_master_send(control_data, (const unsigned char *)&sa->addr,
-               len);
-}
-
-int process_sigma_firmware(struct i2c_client *client, const char *name)
-{
-       struct sigma_firmware ssfw;
-
-       ssfw.control_data = client;
-       ssfw.write = sigma_action_write_i2c;
-
-       return _process_sigma_firmware(&client->dev, &ssfw, name);
-}
-EXPORT_SYMBOL(process_sigma_firmware);
-
-#endif
-
-#if IS_ENABLED(CONFIG_REGMAP)
-
-static int sigma_action_write_regmap(void *control_data,
-       const struct sigma_action *sa, size_t len)
-{
-       return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
-               sa->payload, len - 2);
-}
-
-int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap,
-       const char *name)
-{
-       struct sigma_firmware ssfw;
-
-       ssfw.control_data = regmap;
-       ssfw.write = sigma_action_write_regmap;
-
-       return _process_sigma_firmware(dev, &ssfw, name);
-}
-EXPORT_SYMBOL(process_sigma_firmware_regmap);
-
-#endif
+EXPORT_SYMBOL_GPL(_process_sigma_firmware);
 
 MODULE_LICENSE("GPL");
index e439cbd..c47cd23 100644 (file)
 #include <linux/device.h>
 #include <linux/regmap.h>
 
+struct sigma_action {
+       u8 instr;
+       u8 len_hi;
+       __le16 len;
+       __be16 addr;
+       unsigned char payload[];
+} __packed;
+
+struct sigma_firmware {
+       const struct firmware *fw;
+       size_t pos;
+
+       void *control_data;
+       int (*write)(void *control_data, const struct sigma_action *sa,
+                       size_t len);
+};
+
+int _process_sigma_firmware(struct device *dev,
+       struct sigma_firmware *ssfw, const char *name);
+
 struct i2c_client;
 
 extern int process_sigma_firmware(struct i2c_client *client, const char *name);
index 6bb0ea5..a609aaf 100644 (file)
@@ -923,8 +923,8 @@ static int fsl_soc_dma_probe(struct platform_device *pdev)
        dma->dai.pcm_free = fsl_dma_free_dma_buffers;
 
        /* Store the SSI-specific information that we need */
-       dma->ssi_stx_phys = res.start + offsetof(struct ccsr_ssi, stx0);
-       dma->ssi_srx_phys = res.start + offsetof(struct ccsr_ssi, srx0);
+       dma->ssi_stx_phys = res.start + CCSR_SSI_STX0;
+       dma->ssi_srx_phys = res.start + CCSR_SSI_SRX0;
 
        iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
        if (iprop)
index b912d45..d7a6061 100644 (file)
@@ -762,7 +762,7 @@ static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol,
        struct regmap *regmap = spdif_priv->regmap;
        u32 val;
 
-       val = regmap_read(regmap, REG_SPDIF_SIS, &val);
+       regmap_read(regmap, REG_SPDIF_SIS, &val);
        ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0;
        regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD);
 
@@ -1076,7 +1076,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
                                goto out;
                        } else if (arate / rate[index] == 1) {
                                /* A little bigger than expect */
-                               sub = (arate - rate[index]) * 100000;
+                               sub = (u64)(arate - rate[index]) * 100000;
                                do_div(sub, rate[index]);
                                if (sub >= savesub)
                                        continue;
@@ -1086,7 +1086,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
                                spdif_priv->txrate[index] = arate;
                        } else if (rate[index] / arate == 1) {
                                /* A little smaller than expect */
-                               sub = (rate[index] - arate) * 100000;
+                               sub = (u64)(rate[index] - arate) * 100000;
                                do_div(sub, rate[index]);
                                if (sub >= savesub)
                                        continue;
index 6acb225..2434b6d 100644 (file)
@@ -11,6 +11,7 @@ config SND_PXA2XX_SOC
 config SND_MMP_SOC
        bool "Soc Audio for Marvell MMP chips"
        depends on ARCH_MMP
+       select MMP_SRAM
        select SND_SOC_GENERIC_DMAENGINE_PCM
        select SND_ARM
        help
@@ -40,7 +41,7 @@ config SND_MMP_SOC_SSPA
 
 config SND_PXA2XX_SOC_CORGI
        tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
-       depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
+       depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx && I2C
        select SND_PXA2XX_SOC_I2S
        select SND_SOC_WM8731
        help
@@ -49,7 +50,7 @@ config SND_PXA2XX_SOC_CORGI
 
 config SND_PXA2XX_SOC_SPITZ
        tristate "SoC Audio support for Sharp Zaurus SL-Cxx00"
-       depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00
+       depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00 && I2C
        select SND_PXA2XX_SOC_I2S
        select SND_SOC_WM8750
        help
@@ -58,7 +59,7 @@ config SND_PXA2XX_SOC_SPITZ
 
 config SND_PXA2XX_SOC_Z2
        tristate "SoC Audio support for Zipit Z2"
-       depends on SND_PXA2XX_SOC && MACH_ZIPIT2
+       depends on SND_PXA2XX_SOC && MACH_ZIPIT2 && I2C
        select SND_PXA2XX_SOC_I2S
        select SND_SOC_WM8750
        help
@@ -66,7 +67,7 @@ config SND_PXA2XX_SOC_Z2
 
 config SND_PXA2XX_SOC_POODLE
        tristate "SoC Audio support for Poodle"
-       depends on SND_PXA2XX_SOC && MACH_POODLE
+       depends on SND_PXA2XX_SOC && MACH_POODLE && I2C
        select SND_PXA2XX_SOC_I2S
        select SND_SOC_WM8731
        help
@@ -181,7 +182,7 @@ config SND_PXA2XX_SOC_HX4700
 
 config SND_PXA2XX_SOC_MAGICIAN
        tristate "SoC Audio support for HTC Magician"
-       depends on SND_PXA2XX_SOC && MACH_MAGICIAN
+       depends on SND_PXA2XX_SOC && MACH_MAGICIAN && I2C
        select SND_PXA2XX_SOC_I2S
        select SND_PXA_SOC_SSP
        select SND_SOC_UDA1380
index 9188015..4e86265 100644 (file)
@@ -315,7 +315,7 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma,
                dst_mod = mod[index];
        } else {
                src_mod = mod[index];
-               dst_mod = mod[index + 1];
+               dst_mod = mod[index - 1];
        }
 
        index = 0;
index a74b9bf..cdc837e 100644 (file)
@@ -2755,7 +2755,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
        unsigned int mask = (1 << fls(max)) - 1;
        unsigned int invert = mc->invert;
        unsigned int val;
-       int connect, change;
+       int connect, change, reg_change = 0;
        struct snd_soc_dapm_update update;
        int ret = 0;
 
@@ -2773,20 +2773,23 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
        mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
 
        change = dapm_kcontrol_set_value(kcontrol, val);
-       if (change) {
-               if (reg != SND_SOC_NOPM) {
-                       mask = mask << shift;
-                       val = val << shift;
-
-                       if (snd_soc_test_bits(codec, reg, mask, val)) {
-                               update.kcontrol = kcontrol;
-                               update.reg = reg;
-                               update.mask = mask;
-                               update.val = val;
-                               card->update = &update;
-                       }
 
+       if (reg != SND_SOC_NOPM) {
+               mask = mask << shift;
+               val = val << shift;
+
+               reg_change = snd_soc_test_bits(codec, reg, mask, val);
+       }
+
+       if (change || reg_change) {
+               if (reg_change) {
+                       update.kcontrol = kcontrol;
+                       update.reg = reg;
+                       update.mask = mask;
+                       update.val = val;
+                       card->update = &update;
                }
+               change |= reg_change;
 
                ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
 
index c3b5b7d..a09e5f3 100644 (file)
@@ -307,6 +307,11 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
 
 static int snd_usb_audio_free(struct snd_usb_audio *chip)
 {
+       struct list_head *p, *n;
+
+       list_for_each_safe(p, n, &chip->ep_list)
+               snd_usb_endpoint_free(p);
+
        mutex_destroy(&chip->mutex);
        kfree(chip);
        return 0;
@@ -585,7 +590,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
                                     struct snd_usb_audio *chip)
 {
        struct snd_card *card;
-       struct list_head *p, *n;
+       struct list_head *p;
 
        if (chip == (void *)-1L)
                return;
@@ -598,14 +603,16 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
        mutex_lock(&register_mutex);
        chip->num_interfaces--;
        if (chip->num_interfaces <= 0) {
+               struct snd_usb_endpoint *ep;
+
                snd_card_disconnect(card);
                /* release the pcm resources */
                list_for_each(p, &chip->pcm_list) {
                        snd_usb_stream_disconnect(p);
                }
                /* release the endpoint resources */
-               list_for_each_safe(p, n, &chip->ep_list) {
-                       snd_usb_endpoint_free(p);
+               list_for_each_entry(ep, &chip->ep_list, list) {
+                       snd_usb_endpoint_release(ep);
                }
                /* release the midi resources */
                list_for_each(p, &chip->midi_list) {
index 289f582..114e3e7 100644 (file)
@@ -986,20 +986,31 @@ void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep)
        wait_clear_urbs(ep);
 }
 
+/**
+ * snd_usb_endpoint_release: Tear down an snd_usb_endpoint
+ *
+ * @ep: the endpoint to release
+ *
+ * This function does not care for the endpoint's use count but will tear
+ * down all the streaming URBs immediately.
+ */
+void snd_usb_endpoint_release(struct snd_usb_endpoint *ep)
+{
+       release_urbs(ep, 1);
+}
+
 /**
  * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint
  *
  * @ep: the list header of the endpoint to free
  *
- * This function does not care for the endpoint's use count but will tear
- * down all the streaming URBs immediately and free all resources.
+ * This free all resources of the given ep.
  */
 void snd_usb_endpoint_free(struct list_head *head)
 {
        struct snd_usb_endpoint *ep;
 
        ep = list_entry(head, struct snd_usb_endpoint, list);
-       release_urbs(ep, 1);
        kfree(ep);
 }
 
index 1c7e8ee..e61ee5c 100644 (file)
@@ -23,6 +23,7 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep);
 void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
 int  snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
 void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
+void snd_usb_endpoint_release(struct snd_usb_endpoint *ep);
 void snd_usb_endpoint_free(struct list_head *head);
 
 int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep);
index b83184f..93825a1 100644 (file)
@@ -765,6 +765,9 @@ static void free_arg(struct print_arg *arg)
        case PRINT_BSTRING:
                free(arg->string.string);
                break;
+       case PRINT_BITMASK:
+               free(arg->bitmask.bitmask);
+               break;
        case PRINT_DYNAMIC_ARRAY:
                free(arg->dynarray.index);
                break;
@@ -2268,6 +2271,7 @@ static int arg_num_eval(struct print_arg *arg, long long *val)
        case PRINT_FIELD ... PRINT_SYMBOL:
        case PRINT_STRING:
        case PRINT_BSTRING:
+       case PRINT_BITMASK:
        default:
                do_warning("invalid eval type %d", arg->type);
                ret = 0;
@@ -2296,6 +2300,7 @@ static char *arg_eval (struct print_arg *arg)
        case PRINT_FIELD ... PRINT_SYMBOL:
        case PRINT_STRING:
        case PRINT_BSTRING:
+       case PRINT_BITMASK:
        default:
                do_warning("invalid eval type %d", arg->type);
                break;
@@ -2683,6 +2688,35 @@ process_str(struct event_format *event __maybe_unused, struct print_arg *arg,
        return EVENT_ERROR;
 }
 
+static enum event_type
+process_bitmask(struct event_format *event __maybe_unused, struct print_arg *arg,
+           char **tok)
+{
+       enum event_type type;
+       char *token;
+
+       if (read_expect_type(EVENT_ITEM, &token) < 0)
+               goto out_free;
+
+       arg->type = PRINT_BITMASK;
+       arg->bitmask.bitmask = token;
+       arg->bitmask.offset = -1;
+
+       if (read_expected(EVENT_DELIM, ")") < 0)
+               goto out_err;
+
+       type = read_token(&token);
+       *tok = token;
+
+       return type;
+
+ out_free:
+       free_token(token);
+ out_err:
+       *tok = NULL;
+       return EVENT_ERROR;
+}
+
 static struct pevent_function_handler *
 find_func_handler(struct pevent *pevent, char *func_name)
 {
@@ -2797,6 +2831,10 @@ process_function(struct event_format *event, struct print_arg *arg,
                free_token(token);
                return process_str(event, arg, tok);
        }
+       if (strcmp(token, "__get_bitmask") == 0) {
+               free_token(token);
+               return process_bitmask(event, arg, tok);
+       }
        if (strcmp(token, "__get_dynamic_array") == 0) {
                free_token(token);
                return process_dynamic_array(event, arg, tok);
@@ -3324,6 +3362,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                return eval_type(val, arg, 0);
        case PRINT_STRING:
        case PRINT_BSTRING:
+       case PRINT_BITMASK:
                return 0;
        case PRINT_FUNC: {
                struct trace_seq s;
@@ -3556,6 +3595,60 @@ static void print_str_to_seq(struct trace_seq *s, const char *format,
                trace_seq_printf(s, format, str);
 }
 
+static void print_bitmask_to_seq(struct pevent *pevent,
+                                struct trace_seq *s, const char *format,
+                                int len_arg, const void *data, int size)
+{
+       int nr_bits = size * 8;
+       int str_size = (nr_bits + 3) / 4;
+       int len = 0;
+       char buf[3];
+       char *str;
+       int index;
+       int i;
+
+       /*
+        * The kernel likes to put in commas every 32 bits, we
+        * can do the same.
+        */
+       str_size += (nr_bits - 1) / 32;
+
+       str = malloc(str_size + 1);
+       if (!str) {
+               do_warning("%s: not enough memory!", __func__);
+               return;
+       }
+       str[str_size] = 0;
+
+       /* Start out with -2 for the two chars per byte */
+       for (i = str_size - 2; i >= 0; i -= 2) {
+               /*
+                * data points to a bit mask of size bytes.
+                * In the kernel, this is an array of long words, thus
+                * endianess is very important.
+                */
+               if (pevent->file_bigendian)
+                       index = size - (len + 1);
+               else
+                       index = len;
+
+               snprintf(buf, 3, "%02x", *((unsigned char *)data + index));
+               memcpy(str + i, buf, 2);
+               len++;
+               if (!(len & 3) && i > 0) {
+                       i--;
+                       str[i] = ',';
+               }
+       }
+
+       if (len_arg >= 0)
+               trace_seq_printf(s, format, len_arg, str);
+       else
+               trace_seq_printf(s, format, str);
+
+       free(str);
+}
+
 static void print_str_arg(struct trace_seq *s, void *data, int size,
                          struct event_format *event, const char *format,
                          int len_arg, struct print_arg *arg)
@@ -3691,6 +3784,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
        case PRINT_BSTRING:
                print_str_to_seq(s, format, len_arg, arg->string.string);
                break;
+       case PRINT_BITMASK: {
+               int bitmask_offset;
+               int bitmask_size;
+
+               if (arg->bitmask.offset == -1) {
+                       struct format_field *f;
+
+                       f = pevent_find_any_field(event, arg->bitmask.bitmask);
+                       arg->bitmask.offset = f->offset;
+               }
+               bitmask_offset = data2host4(pevent, data + arg->bitmask.offset);
+               bitmask_size = bitmask_offset >> 16;
+               bitmask_offset &= 0xffff;
+               print_bitmask_to_seq(pevent, s, format, len_arg,
+                                    data + bitmask_offset, bitmask_size);
+               break;
+       }
        case PRINT_OP:
                /*
                 * The only op for string should be ? :
@@ -4822,6 +4932,9 @@ static void print_args(struct print_arg *args)
        case PRINT_BSTRING:
                printf("__get_str(%s)", args->string.string);
                break;
+       case PRINT_BITMASK:
+               printf("__get_bitmask(%s)", args->bitmask.bitmask);
+               break;
        case PRINT_TYPE:
                printf("(%s)", args->typecast.type);
                print_args(args->typecast.item);
index feab942..7a3873f 100644 (file)
@@ -107,8 +107,8 @@ typedef int (*pevent_event_handler_func)(struct trace_seq *s,
 typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
 typedef int (*pevent_plugin_unload_func)(struct pevent *pevent);
 
-struct plugin_option {
-       struct plugin_option            *next;
+struct pevent_plugin_option {
+       struct pevent_plugin_option     *next;
        void                            *handle;
        char                            *file;
        char                            *name;
@@ -135,7 +135,7 @@ struct plugin_option {
  * PEVENT_PLUGIN_OPTIONS:  (optional)
  *   Plugin options that can be set before loading
  *
- *   struct plugin_option PEVENT_PLUGIN_OPTIONS[] = {
+ *   struct pevent_plugin_option PEVENT_PLUGIN_OPTIONS[] = {
  *     {
  *             .name = "option-name",
  *             .plugin_alias = "overide-file-name", (optional)
@@ -208,6 +208,11 @@ struct print_arg_string {
        int                     offset;
 };
 
+struct print_arg_bitmask {
+       char                    *bitmask;
+       int                     offset;
+};
+
 struct print_arg_field {
        char                    *name;
        struct format_field     *field;
@@ -274,6 +279,7 @@ enum print_arg_type {
        PRINT_DYNAMIC_ARRAY,
        PRINT_OP,
        PRINT_FUNC,
+       PRINT_BITMASK,
 };
 
 struct print_arg {
@@ -288,6 +294,7 @@ struct print_arg {
                struct print_arg_hex            hex;
                struct print_arg_func           func;
                struct print_arg_string         string;
+               struct print_arg_bitmask        bitmask;
                struct print_arg_op             op;
                struct print_arg_dynarray       dynarray;
        };
@@ -354,6 +361,8 @@ enum pevent_func_arg_type {
 
 enum pevent_flag {
        PEVENT_NSEC_OUTPUT              = 1,    /* output in NSECS */
+       PEVENT_DISABLE_SYS_PLUGINS      = 1 << 1,
+       PEVENT_DISABLE_PLUGINS          = 1 << 2,
 };
 
 #define PEVENT_ERRORS                                                        \
@@ -410,9 +419,19 @@ enum pevent_errno {
 
 struct plugin_list;
 
+#define INVALID_PLUGIN_LIST_OPTION     ((char **)((unsigned long)-1))
+
 struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
 void traceevent_unload_plugins(struct plugin_list *plugin_list,
                               struct pevent *pevent);
+char **traceevent_plugin_list_options(void);
+void traceevent_plugin_free_options_list(char **list);
+int traceevent_plugin_add_options(const char *name,
+                                 struct pevent_plugin_option *options);
+void traceevent_plugin_remove_options(struct pevent_plugin_option *options);
+void traceevent_print_plugins(struct trace_seq *s,
+                             const char *prefix, const char *suffix,
+                             const struct plugin_list *list);
 
 struct cmdline;
 struct cmdline_list;
index 0c8bf67..136162c 100644 (file)
@@ -18,6 +18,7 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+#include <stdio.h>
 #include <string.h>
 #include <dlfcn.h>
 #include <stdlib.h>
 
 #define LOCAL_PLUGIN_DIR ".traceevent/plugins"
 
+static struct registered_plugin_options {
+       struct registered_plugin_options        *next;
+       struct pevent_plugin_option             *options;
+} *registered_options;
+
+static struct trace_plugin_options {
+       struct trace_plugin_options     *next;
+       char                            *plugin;
+       char                            *option;
+       char                            *value;
+} *trace_plugin_options;
+
 struct plugin_list {
        struct plugin_list      *next;
        char                    *name;
        void                    *handle;
 };
 
+/**
+ * traceevent_plugin_list_options - get list of plugin options
+ *
+ * Returns an array of char strings that list the currently registered
+ * plugin options in the format of <plugin>:<option>. This list can be
+ * used by toggling the option.
+ *
+ * Returns NULL if there's no options registered. On error it returns
+ * INVALID_PLUGIN_LIST_OPTION
+ *
+ * Must be freed with traceevent_plugin_free_options_list().
+ */
+char **traceevent_plugin_list_options(void)
+{
+       struct registered_plugin_options *reg;
+       struct pevent_plugin_option *op;
+       char **list = NULL;
+       char *name;
+       int count = 0;
+
+       for (reg = registered_options; reg; reg = reg->next) {
+               for (op = reg->options; op->name; op++) {
+                       char *alias = op->plugin_alias ? op->plugin_alias : op->file;
+                       char **temp = list;
+
+                       name = malloc(strlen(op->name) + strlen(alias) + 2);
+                       if (!name)
+                               goto err;
+
+                       sprintf(name, "%s:%s", alias, op->name);
+                       list = realloc(list, count + 2);
+                       if (!list) {
+                               list = temp;
+                               free(name);
+                               goto err;
+                       }
+                       list[count++] = name;
+                       list[count] = NULL;
+               }
+       }
+       return list;
+
+ err:
+       while (--count >= 0)
+               free(list[count]);
+       free(list);
+
+       return INVALID_PLUGIN_LIST_OPTION;
+}
+
+void traceevent_plugin_free_options_list(char **list)
+{
+       int i;
+
+       if (!list)
+               return;
+
+       if (list == INVALID_PLUGIN_LIST_OPTION)
+               return;
+
+       for (i = 0; list[i]; i++)
+               free(list[i]);
+
+       free(list);
+}
+
+static int
+update_option(const char *file, struct pevent_plugin_option *option)
+{
+       struct trace_plugin_options *op;
+       char *plugin;
+
+       if (option->plugin_alias) {
+               plugin = strdup(option->plugin_alias);
+               if (!plugin)
+                       return -1;
+       } else {
+               char *p;
+               plugin = strdup(file);
+               if (!plugin)
+                       return -1;
+               p = strstr(plugin, ".");
+               if (p)
+                       *p = '\0';
+       }
+
+       /* first look for named options */
+       for (op = trace_plugin_options; op; op = op->next) {
+               if (!op->plugin)
+                       continue;
+               if (strcmp(op->plugin, plugin) != 0)
+                       continue;
+               if (strcmp(op->option, option->name) != 0)
+                       continue;
+
+               option->value = op->value;
+               option->set ^= 1;
+               goto out;
+       }
+
+       /* first look for unnamed options */
+       for (op = trace_plugin_options; op; op = op->next) {
+               if (op->plugin)
+                       continue;
+               if (strcmp(op->option, option->name) != 0)
+                       continue;
+
+               option->value = op->value;
+               option->set ^= 1;
+               break;
+       }
+
+ out:
+       free(plugin);
+       return 0;
+}
+
+/**
+ * traceevent_plugin_add_options - Add a set of options by a plugin
+ * @name: The name of the plugin adding the options
+ * @options: The set of options being loaded
+ *
+ * Sets the options with the values that have been added by user.
+ */
+int traceevent_plugin_add_options(const char *name,
+                                 struct pevent_plugin_option *options)
+{
+       struct registered_plugin_options *reg;
+
+       reg = malloc(sizeof(*reg));
+       if (!reg)
+               return -1;
+       reg->next = registered_options;
+       reg->options = options;
+       registered_options = reg;
+
+       while (options->name) {
+               update_option(name, options);
+               options++;
+       }
+       return 0;
+}
+
+/**
+ * traceevent_plugin_remove_options - remove plugin options that were registered
+ * @options: Options to removed that were registered with traceevent_plugin_add_options
+ */
+void traceevent_plugin_remove_options(struct pevent_plugin_option *options)
+{
+       struct registered_plugin_options **last;
+       struct registered_plugin_options *reg;
+
+       for (last = &registered_options; *last; last = &(*last)->next) {
+               if ((*last)->options == options) {
+                       reg = *last;
+                       *last = reg->next;
+                       free(reg);
+                       return;
+               }
+       }
+}
+
+/**
+ * traceevent_print_plugins - print out the list of plugins loaded
+ * @s: the trace_seq descripter to write to
+ * @prefix: The prefix string to add before listing the option name
+ * @suffix: The suffix string ot append after the option name
+ * @list: The list of plugins (usually returned by traceevent_load_plugins()
+ *
+ * Writes to the trace_seq @s the list of plugins (files) that is
+ * returned by traceevent_load_plugins(). Use @prefix and @suffix for formating:
+ * @prefix = "  ", @suffix = "\n".
+ */
+void traceevent_print_plugins(struct trace_seq *s,
+                             const char *prefix, const char *suffix,
+                             const struct plugin_list *list)
+{
+       while (list) {
+               trace_seq_printf(s, "%s%s%s", prefix, list->name, suffix);
+               list = list->next;
+       }
+}
+
 static void
 load_plugin(struct pevent *pevent, const char *path,
            const char *file, void *data)
@@ -148,12 +344,17 @@ load_plugins(struct pevent *pevent, const char *suffix,
        char *path;
        char *envdir;
 
+       if (pevent->flags & PEVENT_DISABLE_PLUGINS)
+               return;
+
        /*
         * If a system plugin directory was defined,
         * check that first.
         */
 #ifdef PLUGIN_DIR
-       load_plugins_dir(pevent, suffix, PLUGIN_DIR, load_plugin, data);
+       if (!(pevent->flags & PEVENT_DISABLE_SYS_PLUGINS))
+               load_plugins_dir(pevent, suffix, PLUGIN_DIR,
+                                load_plugin, data);
 #endif
 
        /*
index 80ba4ff..a00ec19 100644 (file)
@@ -33,6 +33,29 @@ static int cpus = -1;
 
 #define STK_BLK 10
 
+struct pevent_plugin_option plugin_options[] =
+{
+       {
+               .name = "parent",
+               .plugin_alias = "ftrace",
+               .description =
+               "Print parent of functions for function events",
+       },
+       {
+               .name = "indent",
+               .plugin_alias = "ftrace",
+               .description =
+               "Try to show function call indents, based on parents",
+               .set = 1,
+       },
+       {
+               .name = NULL,
+       }
+};
+
+static struct pevent_plugin_option *ftrace_parent = &plugin_options[0];
+static struct pevent_plugin_option *ftrace_indent = &plugin_options[1];
+
 static void add_child(struct func_stack *stack, const char *child, int pos)
 {
        int i;
@@ -119,7 +142,8 @@ static int function_handler(struct trace_seq *s, struct pevent_record *record,
 
        parent = pevent_find_function(pevent, pfunction);
 
-       index = add_and_get_index(parent, func, record->cpu);
+       if (parent && ftrace_indent->set)
+               index = add_and_get_index(parent, func, record->cpu);
 
        trace_seq_printf(s, "%*s", index*3, "");
 
@@ -128,11 +152,13 @@ static int function_handler(struct trace_seq *s, struct pevent_record *record,
        else
                trace_seq_printf(s, "0x%llx", function);
 
-       trace_seq_printf(s, " <-- ");
-       if (parent)
-               trace_seq_printf(s, "%s", parent);
-       else
-               trace_seq_printf(s, "0x%llx", pfunction);
+       if (ftrace_parent->set) {
+               trace_seq_printf(s, " <-- ");
+               if (parent)
+                       trace_seq_printf(s, "%s", parent);
+               else
+                       trace_seq_printf(s, "0x%llx", pfunction);
+       }
 
        return 0;
 }
@@ -141,6 +167,9 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
 {
        pevent_register_event_handler(pevent, -1, "ftrace", "function",
                                      function_handler, NULL);
+
+       traceevent_plugin_add_options("ftrace", plugin_options);
+
        return 0;
 }
 
@@ -157,6 +186,8 @@ void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
                free(fstack[i].stack);
        }
 
+       traceevent_plugin_remove_options(plugin_options);
+
        free(fstack);
        fstack = NULL;
        cpus = -1;
index cefdf43..d2b59af 100644 (file)
@@ -117,6 +117,22 @@ OPTIONS
        By default, every sort keys not specified in -F will be appended
        automatically.
 
+       If --mem-mode option is used, following sort keys are also available
+       (incompatible with --branch-stack):
+       symbol_daddr, dso_daddr, locked, tlb, mem, snoop, dcacheline.
+
+       - symbol_daddr: name of data symbol being executed on at the time of sample
+       - dso_daddr: name of library or module containing the data being executed
+       on at the time of sample
+       - locked: whether the bus was locked at the time of sample
+       - tlb: type of tlb access for the data at the time of sample
+       - mem: type of memory access for the data at the time of sample
+       - snoop: type of snoop (if any) for the data at the time of sample
+       - dcacheline: the cacheline the data address is on at the time of sample
+
+       And default sort keys are changed to local_weight, mem, sym, dso,
+       symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
+
 -p::
 --parent=<regex>::
         A regex filter to identify parent. The parent is a caller of this
@@ -260,6 +276,13 @@ OPTIONS
        Demangle symbol names to human readable form. It's enabled by default,
        disable with --no-demangle.
 
+--mem-mode::
+       Use the data addresses of samples in addition to instruction addresses
+       to build the histograms.  To generate meaningful output, the perf.data
+       file must have been obtained using perf record -d -W and using a
+       special event -e cpu/mem-loads/ or -e cpu/mem-stores/. See
+       'perf mem' for simpler access.
+
 --percent-limit::
        Do not show entries which have an overhead under that percent.
        (Default: 0).
index bc5990c..5e0f986 100644 (file)
@@ -43,27 +43,6 @@ TIMECHART OPTIONS
 
 --symfs=<directory>::
         Look for files with symbols relative to this directory.
-
-EXAMPLES
---------
-
-$ perf timechart record git pull
-
-  [ perf record: Woken up 13 times to write data ]
-  [ perf record: Captured and wrote 4.253 MB perf.data (~185801 samples) ]
-
-$ perf timechart
-
-  Written 10.2 seconds of trace to output.svg.
-
-Record system-wide timechart:
-
-  $ perf timechart record
-
-  then generate timechart and highlight 'gcc' tasks:
-
-  $ perf timechart --highlight gcc
-
 -n::
 --proc-num::
         Print task info for at least given number of tasks.
@@ -88,6 +67,26 @@ RECORD OPTIONS
 --callchain::
         Do call-graph (stack chain/backtrace) recording
 
+EXAMPLES
+--------
+
+$ perf timechart record git pull
+
+  [ perf record: Woken up 13 times to write data ]
+  [ perf record: Captured and wrote 4.253 MB perf.data (~185801 samples) ]
+
+$ perf timechart
+
+  Written 10.2 seconds of trace to output.svg.
+
+Record system-wide timechart:
+
+  $ perf timechart record
+
+  then generate timechart and highlight 'gcc' tasks:
+
+  $ perf timechart --highlight gcc
+
 SEE ALSO
 --------
 linkperf:perf-record[1]
index ae20edf..9670a16 100644 (file)
@@ -819,15 +819,15 @@ TAG_FOLDERS= . ../lib/traceevent ../lib/api ../lib/symbol
 TAG_FILES= ../../include/uapi/linux/perf_event.h
 
 TAGS:
-       $(RM) TAGS
+       $(QUIET_GEN)$(RM) TAGS; \
        $(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs etags -a $(TAG_FILES)
 
 tags:
-       $(RM) tags
+       $(QUIET_GEN)$(RM) tags; \
        $(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs ctags -a $(TAG_FILES)
 
 cscope:
-       $(RM) cscope*
+       $(QUIET_GEN)$(RM) cscope*; \
        $(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs cscope -b $(TAG_FILES)
 
 ### Detect prefix changes
index 6a3af00..16c7c11 100644 (file)
@@ -72,7 +72,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool,
        if (ret)
                return ret;
 
-       if (&inject->output.is_pipe)
+       if (!inject->output.is_pipe)
                return 0;
 
        return perf_event__repipe_synth(tool, event);
index cdcd4eb..c63fa29 100644 (file)
@@ -288,6 +288,13 @@ static void cleanup_params(void)
        memset(&params, 0, sizeof(params));
 }
 
+static void pr_err_with_code(const char *msg, int err)
+{
+       pr_err("%s", msg);
+       pr_debug(" Reason: %s (Code: %d)", strerror(-err), err);
+       pr_err("\n");
+}
+
 static int
 __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 {
@@ -379,7 +386,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                }
                ret = parse_probe_event_argv(argc, argv);
                if (ret < 0) {
-                       pr_err("  Error: Parse Error.  (%d)\n", ret);
+                       pr_err_with_code("  Error: Command Parse Error.", ret);
                        return ret;
                }
        }
@@ -419,8 +426,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                }
                ret = show_perf_probe_events();
                if (ret < 0)
-                       pr_err("  Error: Failed to show event list. (%d)\n",
-                              ret);
+                       pr_err_with_code("  Error: Failed to show event list.", ret);
                return ret;
        }
        if (params.show_funcs) {
@@ -445,8 +451,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                strfilter__delete(params.filter);
                params.filter = NULL;
                if (ret < 0)
-                       pr_err("  Error: Failed to show functions."
-                              " (%d)\n", ret);
+                       pr_err_with_code("  Error: Failed to show functions.", ret);
                return ret;
        }
 
@@ -464,7 +469,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 
                ret = show_line_range(&params.line_range, params.target);
                if (ret < 0)
-                       pr_err("  Error: Failed to show lines. (%d)\n", ret);
+                       pr_err_with_code("  Error: Failed to show lines.", ret);
                return ret;
        }
        if (params.show_vars) {
@@ -485,7 +490,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                strfilter__delete(params.filter);
                params.filter = NULL;
                if (ret < 0)
-                       pr_err("  Error: Failed to show vars. (%d)\n", ret);
+                       pr_err_with_code("  Error: Failed to show vars.", ret);
                return ret;
        }
 #endif
@@ -493,7 +498,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
        if (params.dellist) {
                ret = del_perf_probe_events(params.dellist);
                if (ret < 0) {
-                       pr_err("  Error: Failed to delete events. (%d)\n", ret);
+                       pr_err_with_code("  Error: Failed to delete events.", ret);
                        return ret;
                }
        }
@@ -504,7 +509,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                                            params.target,
                                            params.force_add);
                if (ret < 0) {
-                       pr_err("  Error: Failed to add events. (%d)\n", ret);
+                       pr_err_with_code("  Error: Failed to add events.", ret);
                        return ret;
                }
        }
index 4f100b5..f30ac5e 100644 (file)
@@ -299,7 +299,11 @@ else
       NO_LIBUNWIND := 1
       NO_LIBDW_DWARF_UNWIND := 1
     else
-      msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
+      ifneq ($(filter s% -static%,$(LDFLAGS),),)
+        msg := $(error No static glibc found, please install glibc-static);
+      else
+        msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]);
+      endif
     endif
   else
     ifndef NO_LIBDW_DWARF_UNWIND
index 78f7b92..95c58fc 100644 (file)
@@ -458,6 +458,7 @@ int main(int argc, const char **argv)
 
        /* The page_size is placed in util object. */
        page_size = sysconf(_SC_PAGE_SIZE);
+       cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
 
        cmd = perf_extract_argv0_path(argv[0]);
        if (!cmd)
index 802e3cd..6f8b01b 100644 (file)
@@ -3,6 +3,8 @@
  *
  * Builtin regression testing command: ever growing number of sanity tests
  */
+#include <unistd.h>
+#include <string.h>
 #include "builtin.h"
 #include "intlist.h"
 #include "tests.h"
@@ -50,9 +52,17 @@ static struct test {
                .func = test__pmu,
        },
        {
-               .desc = "Test dso data interface",
+               .desc = "Test dso data read",
                .func = test__dso_data,
        },
+       {
+               .desc = "Test dso data cache",
+               .func = test__dso_data_cache,
+       },
+       {
+               .desc = "Test dso data reopen",
+               .func = test__dso_data_reopen,
+       },
        {
                .desc = "roundtrip evsel->name check",
                .func = test__perf_evsel__roundtrip_name_test,
@@ -172,6 +182,34 @@ static bool perf_test__matches(int curr, int argc, const char *argv[])
        return false;
 }
 
+static int run_test(struct test *test)
+{
+       int status, err = -1, child = fork();
+
+       if (child < 0) {
+               pr_err("failed to fork test: %s\n", strerror(errno));
+               return -1;
+       }
+
+       if (!child) {
+               pr_debug("test child forked, pid %d\n", getpid());
+               err = test->func();
+               exit(err);
+       }
+
+       wait(&status);
+
+       if (WIFEXITED(status)) {
+               err = WEXITSTATUS(status);
+               pr_debug("test child finished with %d\n", err);
+       } else if (WIFSIGNALED(status)) {
+               err = -1;
+               pr_debug("test child interrupted\n");
+       }
+
+       return err;
+}
+
 static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
 {
        int i = 0;
@@ -200,7 +238,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
                }
 
                pr_debug("\n--- start ---\n");
-               err = tests[curr].func();
+               err = run_test(&tests[curr]);
                pr_debug("---- end ----\n%s:", tests[curr].desc);
 
                switch (err) {
index 3e6cb17..630808c 100644 (file)
@@ -1,22 +1,27 @@
-#include "util.h"
-
 #include <stdlib.h>
 #include <linux/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <string.h>
-
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <api/fs/fs.h>
+#include "util.h"
 #include "machine.h"
 #include "symbol.h"
 #include "tests.h"
 
 static char *test_file(int size)
 {
-       static char buf_templ[] = "/tmp/test-XXXXXX";
+#define TEMPL "/tmp/perf-test-XXXXXX"
+       static char buf_templ[sizeof(TEMPL)];
        char *templ = buf_templ;
        int fd, i;
        unsigned char *buf;
 
+       strcpy(buf_templ, TEMPL);
+#undef TEMPL
+
        fd = mkstemp(templ);
        if (fd < 0) {
                perror("mkstemp failed");
@@ -150,3 +155,204 @@ int test__dso_data(void)
        unlink(file);
        return 0;
 }
+
+static long open_files_cnt(void)
+{
+       char path[PATH_MAX];
+       struct dirent *dent;
+       DIR *dir;
+       long nr = 0;
+
+       scnprintf(path, PATH_MAX, "%s/self/fd", procfs__mountpoint());
+       pr_debug("fd path: %s\n", path);
+
+       dir = opendir(path);
+       TEST_ASSERT_VAL("failed to open fd directory", dir);
+
+       while ((dent = readdir(dir)) != NULL) {
+               if (!strcmp(dent->d_name, ".") ||
+                   !strcmp(dent->d_name, ".."))
+                       continue;
+
+               nr++;
+       }
+
+       closedir(dir);
+       return nr - 1;
+}
+
+static struct dso **dsos;
+
+static int dsos__create(int cnt, int size)
+{
+       int i;
+
+       dsos = malloc(sizeof(dsos) * cnt);
+       TEST_ASSERT_VAL("failed to alloc dsos array", dsos);
+
+       for (i = 0; i < cnt; i++) {
+               char *file;
+
+               file = test_file(size);
+               TEST_ASSERT_VAL("failed to get dso file", file);
+
+               dsos[i] = dso__new(file);
+               TEST_ASSERT_VAL("failed to get dso", dsos[i]);
+       }
+
+       return 0;
+}
+
+static void dsos__delete(int cnt)
+{
+       int i;
+
+       for (i = 0; i < cnt; i++) {
+               struct dso *dso = dsos[i];
+
+               unlink(dso->name);
+               dso__delete(dso);
+       }
+
+       free(dsos);
+}
+
+static int set_fd_limit(int n)
+{
+       struct rlimit rlim;
+
+       if (getrlimit(RLIMIT_NOFILE, &rlim))
+               return -1;
+
+       pr_debug("file limit %ld, new %d\n", (long) rlim.rlim_cur, n);
+
+       rlim.rlim_cur = n;
+       return setrlimit(RLIMIT_NOFILE, &rlim);
+}
+
+int test__dso_data_cache(void)
+{
+       struct machine machine;
+       long nr_end, nr = open_files_cnt();
+       int dso_cnt, limit, i, fd;
+
+       memset(&machine, 0, sizeof(machine));
+
+       /* set as system limit */
+       limit = nr * 4;
+       TEST_ASSERT_VAL("failed to set file limit", !set_fd_limit(limit));
+
+       /* and this is now our dso open FDs limit + 1 extra */
+       dso_cnt = limit / 2 + 1;
+       TEST_ASSERT_VAL("failed to create dsos\n",
+               !dsos__create(dso_cnt, TEST_FILE_SIZE));
+
+       for (i = 0; i < (dso_cnt - 1); i++) {
+               struct dso *dso = dsos[i];
+
+               /*
+                * Open dsos via dso__data_fd or dso__data_read_offset.
+                * Both opens the data file and keep it open.
+                */
+               if (i % 2) {
+                       fd = dso__data_fd(dso, &machine);
+                       TEST_ASSERT_VAL("failed to get fd", fd > 0);
+               } else {
+                       #define BUFSIZE 10
+                       u8 buf[BUFSIZE];
+                       ssize_t n;
+
+                       n = dso__data_read_offset(dso, &machine, 0, buf, BUFSIZE);
+                       TEST_ASSERT_VAL("failed to read dso", n == BUFSIZE);
+               }
+       }
+
+       /* open +1 dso over the allowed limit */
+       fd = dso__data_fd(dsos[i], &machine);
+       TEST_ASSERT_VAL("failed to get fd", fd > 0);
+
+       /* should force the first one to be closed */
+       TEST_ASSERT_VAL("failed to close dsos[0]", dsos[0]->data.fd == -1);
+
+       /* cleanup everything */
+       dsos__delete(dso_cnt);
+
+       /* Make sure we did not leak any file descriptor. */
+       nr_end = open_files_cnt();
+       pr_debug("nr start %ld, nr stop %ld\n", nr, nr_end);
+       TEST_ASSERT_VAL("failed leadking files", nr == nr_end);
+       return 0;
+}
+
+int test__dso_data_reopen(void)
+{
+       struct machine machine;
+       long nr_end, nr = open_files_cnt();
+       int fd, fd_extra;
+
+#define dso_0 (dsos[0])
+#define dso_1 (dsos[1])
+#define dso_2 (dsos[2])
+
+       memset(&machine, 0, sizeof(machine));
+
+       /*
+        * Test scenario:
+        * - create 3 dso objects
+        * - set process file descriptor limit to current
+        *   files count + 3
+        * - test that the first dso gets closed when we
+        *   reach the files count limit
+        */
+
+       /* Make sure we are able to open 3 fds anyway */
+       TEST_ASSERT_VAL("failed to set file limit",
+                       !set_fd_limit((nr + 3)));
+
+       TEST_ASSERT_VAL("failed to create dsos\n", !dsos__create(3, TEST_FILE_SIZE));
+
+       /* open dso_0 */
+       fd = dso__data_fd(dso_0, &machine);
+       TEST_ASSERT_VAL("failed to get fd", fd > 0);
+
+       /* open dso_1 */
+       fd = dso__data_fd(dso_1, &machine);
+       TEST_ASSERT_VAL("failed to get fd", fd > 0);
+
+       /*
+        * open extra file descriptor and we just
+        * reached the files count limit
+        */
+       fd_extra = open("/dev/null", O_RDONLY);
+       TEST_ASSERT_VAL("failed to open extra fd", fd_extra > 0);
+
+       /* open dso_2 */
+       fd = dso__data_fd(dso_2, &machine);
+       TEST_ASSERT_VAL("failed to get fd", fd > 0);
+
+       /*
+        * dso_0 should get closed, because we reached
+        * the file descriptor limit
+        */
+       TEST_ASSERT_VAL("failed to close dso_0", dso_0->data.fd == -1);
+
+       /* open dso_0 */
+       fd = dso__data_fd(dso_0, &machine);
+       TEST_ASSERT_VAL("failed to get fd", fd > 0);
+
+       /*
+        * dso_1 should get closed, because we reached
+        * the file descriptor limit
+        */
+       TEST_ASSERT_VAL("failed to close dso_1", dso_1->data.fd == -1);
+
+       /* cleanup everything */
+       close(fd_extra);
+       dsos__delete(3);
+
+       /* Make sure we did not leak any file descriptor. */
+       nr_end = open_files_cnt();
+       pr_debug("nr start %ld, nr stop %ld\n", nr, nr_end);
+       TEST_ASSERT_VAL("failed leadking files", nr == nr_end);
+       return 0;
+}
index 108f0cd..96adb73 100644 (file)
@@ -15,7 +15,7 @@ static int mmap_handler(struct perf_tool *tool __maybe_unused,
                        struct perf_sample *sample __maybe_unused,
                        struct machine *machine)
 {
-       return machine__process_mmap_event(machine, event, NULL);
+       return machine__process_mmap2_event(machine, event, NULL);
 }
 
 static int init_live_machine(struct machine *machine)
index 2f92d6e..69a71ff 100644 (file)
@@ -205,8 +205,7 @@ $(run):
        ( eval $$cmd ) >> $@ 2>&1; \
        echo "  test: $(call test,$@)" >> $@ 2>&1; \
        $(call test,$@) && \
-       rm -f $@ \
-       rm -rf $$TMP_DEST
+       rm -rf $@ $$TMP_DEST || (cat $@ ; false)
 
 $(run_O):
        $(call clean)
@@ -217,9 +216,7 @@ $(run_O):
        ( eval $$cmd ) >> $@ 2>&1 && \
        echo "  test: $(call test_O,$@)" >> $@ 2>&1; \
        $(call test_O,$@) && \
-       rm -f $@ && \
-       rm -rf $$TMP_O \
-       rm -rf $$TMP_DEST
+       rm -rf $@ $$TMP_O $$TMP_DEST || (cat $@ ; false)
 
 tarpkg:
        @cmd="$(PERF)/tests/perf-targz-src-pkg $(PERF)"; \
index 022bb68..ed64790 100644 (file)
@@ -28,6 +28,8 @@ int test__syscall_open_tp_fields(void);
 int test__pmu(void);
 int test__attr(void);
 int test__dso_data(void);
+int test__dso_data_cache(void);
+int test__dso_data_reopen(void);
 int test__parse_events(void);
 int test__hists_link(void);
 int test__python_use(void);
index 64453d6..819f104 100644 (file)
@@ -1,3 +1,6 @@
+#include <asm/bug.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include "symbol.h"
 #include "dso.h"
 #include "machine.h"
@@ -136,7 +139,48 @@ int dso__read_binary_type_filename(const struct dso *dso,
        return ret;
 }
 
-static int open_dso(struct dso *dso, struct machine *machine)
+/*
+ * Global list of open DSOs and the counter.
+ */
+static LIST_HEAD(dso__data_open);
+static long dso__data_open_cnt;
+
+static void dso__list_add(struct dso *dso)
+{
+       list_add_tail(&dso->data.open_entry, &dso__data_open);
+       dso__data_open_cnt++;
+}
+
+static void dso__list_del(struct dso *dso)
+{
+       list_del(&dso->data.open_entry);
+       WARN_ONCE(dso__data_open_cnt <= 0,
+                 "DSO data fd counter out of bounds.");
+       dso__data_open_cnt--;
+}
+
+static void close_first_dso(void);
+
+static int do_open(char *name)
+{
+       int fd;
+
+       do {
+               fd = open(name, O_RDONLY);
+               if (fd >= 0)
+                       return fd;
+
+               pr_debug("dso open failed, mmap: %s\n", strerror(errno));
+               if (!dso__data_open_cnt || errno != EMFILE)
+                       break;
+
+               close_first_dso();
+       } while (1);
+
+       return -1;
+}
+
+static int __open_dso(struct dso *dso, struct machine *machine)
 {
        int fd;
        char *root_dir = (char *)"";
@@ -154,11 +198,130 @@ static int open_dso(struct dso *dso, struct machine *machine)
                return -EINVAL;
        }
 
-       fd = open(name, O_RDONLY);
+       fd = do_open(name);
        free(name);
        return fd;
 }
 
+static void check_data_close(void);
+
+/**
+ * dso_close - Open DSO data file
+ * @dso: dso object
+ *
+ * Open @dso's data file descriptor and updates
+ * list/count of open DSO objects.
+ */
+static int open_dso(struct dso *dso, struct machine *machine)
+{
+       int fd = __open_dso(dso, machine);
+
+       if (fd > 0) {
+               dso__list_add(dso);
+               /*
+                * Check if we crossed the allowed number
+                * of opened DSOs and close one if needed.
+                */
+               check_data_close();
+       }
+
+       return fd;
+}
+
+static void close_data_fd(struct dso *dso)
+{
+       if (dso->data.fd >= 0) {
+               close(dso->data.fd);
+               dso->data.fd = -1;
+               dso->data.file_size = 0;
+               dso__list_del(dso);
+       }
+}
+
+/**
+ * dso_close - Close DSO data file
+ * @dso: dso object
+ *
+ * Close @dso's data file descriptor and updates
+ * list/count of open DSO objects.
+ */
+static void close_dso(struct dso *dso)
+{
+       close_data_fd(dso);
+}
+
+static void close_first_dso(void)
+{
+       struct dso *dso;
+
+       dso = list_first_entry(&dso__data_open, struct dso, data.open_entry);
+       close_dso(dso);
+}
+
+static rlim_t get_fd_limit(void)
+{
+       struct rlimit l;
+       rlim_t limit = 0;
+
+       /* Allow half of the current open fd limit. */
+       if (getrlimit(RLIMIT_NOFILE, &l) == 0) {
+               if (l.rlim_cur == RLIM_INFINITY)
+                       limit = l.rlim_cur;
+               else
+                       limit = l.rlim_cur / 2;
+       } else {
+               pr_err("failed to get fd limit\n");
+               limit = 1;
+       }
+
+       return limit;
+}
+
+static bool may_cache_fd(void)
+{
+       static rlim_t limit;
+
+       if (!limit)
+               limit = get_fd_limit();
+
+       if (limit == RLIM_INFINITY)
+               return true;
+
+       return limit > (rlim_t) dso__data_open_cnt;
+}
+
+/*
+ * Check and close LRU dso if we crossed allowed limit
+ * for opened dso file descriptors. The limit is half
+ * of the RLIMIT_NOFILE files opened.
+*/
+static void check_data_close(void)
+{
+       bool cache_fd = may_cache_fd();
+
+       if (!cache_fd)
+               close_first_dso();
+}
+
+/**
+ * dso__data_close - Close DSO data file
+ * @dso: dso object
+ *
+ * External interface to close @dso's data file descriptor.
+ */
+void dso__data_close(struct dso *dso)
+{
+       close_dso(dso);
+}
+
+/**
+ * dso__data_fd - Get dso's data file descriptor
+ * @dso: dso object
+ * @machine: machine object
+ *
+ * External interface to find dso's file, open it and
+ * returns file descriptor.
+ */
 int dso__data_fd(struct dso *dso, struct machine *machine)
 {
        enum dso_binary_type binary_type_data[] = {
@@ -168,8 +331,13 @@ int dso__data_fd(struct dso *dso, struct machine *machine)
        };
        int i = 0;
 
-       if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND)
-               return open_dso(dso, machine);
+       if (dso->data.fd >= 0)
+               return dso->data.fd;
+
+       if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) {
+               dso->data.fd = open_dso(dso, machine);
+               return dso->data.fd;
+       }
 
        do {
                int fd;
@@ -178,7 +346,7 @@ int dso__data_fd(struct dso *dso, struct machine *machine)
 
                fd = open_dso(dso, machine);
                if (fd >= 0)
-                       return fd;
+                       return dso->data.fd = fd;
 
        } while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
 
@@ -260,16 +428,10 @@ dso_cache__memcpy(struct dso_cache *cache, u64 offset,
 }
 
 static ssize_t
-dso_cache__read(struct dso *dso, struct machine *machine,
-                u64 offset, u8 *data, ssize_t size)
+dso_cache__read(struct dso *dso, u64 offset, u8 *data, ssize_t size)
 {
        struct dso_cache *cache;
        ssize_t ret;
-       int fd;
-
-       fd = dso__data_fd(dso, machine);
-       if (fd < 0)
-               return -1;
 
        do {
                u64 cache_offset;
@@ -283,16 +445,16 @@ dso_cache__read(struct dso *dso, struct machine *machine,
                cache_offset = offset & DSO__DATA_CACHE_MASK;
                ret = -EINVAL;
 
-               if (-1 == lseek(fd, cache_offset, SEEK_SET))
+               if (-1 == lseek(dso->data.fd, cache_offset, SEEK_SET))
                        break;
 
-               ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
+               ret = read(dso->data.fd, cache->data, DSO__DATA_CACHE_SIZE);
                if (ret <= 0)
                        break;
 
                cache->offset = cache_offset;
                cache->size   = ret;
-               dso_cache__insert(&dso->cache, cache);
+               dso_cache__insert(&dso->data.cache, cache);
 
                ret = dso_cache__memcpy(cache, offset, data, size);
 
@@ -301,24 +463,27 @@ dso_cache__read(struct dso *dso, struct machine *machine,
        if (ret <= 0)
                free(cache);
 
-       close(fd);
        return ret;
 }
 
-static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
-                             u64 offset, u8 *data, ssize_t size)
+static ssize_t dso_cache_read(struct dso *dso, u64 offset,
+                             u8 *data, ssize_t size)
 {
        struct dso_cache *cache;
 
-       cache = dso_cache__find(&dso->cache, offset);
+       cache = dso_cache__find(&dso->data.cache, offset);
        if (cache)
                return dso_cache__memcpy(cache, offset, data, size);
        else
-               return dso_cache__read(dso, machine, offset, data, size);
+               return dso_cache__read(dso, offset, data, size);
 }
 
-ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
-                             u64 offset, u8 *data, ssize_t size)
+/*
+ * Reads and caches dso data DSO__DATA_CACHE_SIZE size chunks
+ * in the rb_tree. Any read to already cached data is served
+ * by cached data.
+ */
+static ssize_t cached_read(struct dso *dso, u64 offset, u8 *data, ssize_t size)
 {
        ssize_t r = 0;
        u8 *p = data;
@@ -326,7 +491,7 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
        do {
                ssize_t ret;
 
-               ret = dso_cache_read(dso, machine, offset, p, size);
+               ret = dso_cache_read(dso, offset, p, size);
                if (ret < 0)
                        return ret;
 
@@ -346,6 +511,67 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
        return r;
 }
 
+static int data_file_size(struct dso *dso)
+{
+       struct stat st;
+
+       if (!dso->data.file_size) {
+               if (fstat(dso->data.fd, &st)) {
+                       pr_err("dso mmap failed, fstat: %s\n", strerror(errno));
+                       return -1;
+               }
+               dso->data.file_size = st.st_size;
+       }
+
+       return 0;
+}
+
+static ssize_t data_read_offset(struct dso *dso, u64 offset,
+                               u8 *data, ssize_t size)
+{
+       if (data_file_size(dso))
+               return -1;
+
+       /* Check the offset sanity. */
+       if (offset > dso->data.file_size)
+               return -1;
+
+       if (offset + size < offset)
+               return -1;
+
+       return cached_read(dso, offset, data, size);
+}
+
+/**
+ * dso__data_read_offset - Read data from dso file offset
+ * @dso: dso object
+ * @machine: machine object
+ * @offset: file offset
+ * @data: buffer to store data
+ * @size: size of the @data buffer
+ *
+ * External interface to read data from dso file offset. Open
+ * dso data file and use cached_read to get the data.
+ */
+ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
+                             u64 offset, u8 *data, ssize_t size)
+{
+       if (dso__data_fd(dso, machine) < 0)
+               return -1;
+
+       return data_read_offset(dso, offset, data, size);
+}
+
+/**
+ * dso__data_read_addr - Read data from dso address
+ * @dso: dso object
+ * @machine: machine object
+ * @add: virtual memory address
+ * @data: buffer to store data
+ * @size: size of the @data buffer
+ *
+ * External interface to read data from dso address.
+ */
 ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
                            struct machine *machine, u64 addr,
                            u8 *data, ssize_t size)
@@ -473,7 +699,8 @@ struct dso *dso__new(const char *name)
                dso__set_short_name(dso, dso->name, false);
                for (i = 0; i < MAP__NR_TYPES; ++i)
                        dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
-               dso->cache = RB_ROOT;
+               dso->data.cache = RB_ROOT;
+               dso->data.fd = -1;
                dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
                dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
                dso->loaded = 0;
@@ -485,6 +712,7 @@ struct dso *dso__new(const char *name)
                dso->kernel = DSO_TYPE_USER;
                dso->needs_swap = DSO_SWAP__UNSET;
                INIT_LIST_HEAD(&dso->node);
+               INIT_LIST_HEAD(&dso->data.open_entry);
        }
 
        return dso;
@@ -506,7 +734,8 @@ void dso__delete(struct dso *dso)
                dso->long_name_allocated = false;
        }
 
-       dso_cache__free(&dso->cache);
+       dso__data_close(dso);
+       dso_cache__free(&dso->data.cache);
        dso__free_a2l(dso);
        zfree(&dso->symsrc_filename);
        free(dso);
index 38efe95..ad553ba 100644 (file)
@@ -76,7 +76,6 @@ struct dso {
        struct list_head node;
        struct rb_root   symbols[MAP__NR_TYPES];
        struct rb_root   symbol_names[MAP__NR_TYPES];
-       struct rb_root   cache;
        void             *a2l;
        char             *symsrc_filename;
        unsigned int     a2l_fails;
@@ -99,6 +98,15 @@ struct dso {
        const char       *long_name;
        u16              long_name_len;
        u16              short_name_len;
+
+       /* dso data file */
+       struct {
+               struct rb_root   cache;
+               int              fd;
+               size_t           file_size;
+               struct list_head open_entry;
+       } data;
+
        char             name[0];
 };
 
@@ -141,7 +149,47 @@ char dso__symtab_origin(const struct dso *dso);
 int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type,
                                   char *root_dir, char *filename, size_t size);
 
+/*
+ * The dso__data_* external interface provides following functions:
+ *   dso__data_fd
+ *   dso__data_close
+ *   dso__data_read_offset
+ *   dso__data_read_addr
+ *
+ * Please refer to the dso.c object code for each function and
+ * arguments documentation. Following text tries to explain the
+ * dso file descriptor caching.
+ *
+ * The dso__data* interface allows caching of opened file descriptors
+ * to speed up the dso data accesses. The idea is to leave the file
+ * descriptor opened ideally for the whole life of the dso object.
+ *
+ * The current usage of the dso__data_* interface is as follows:
+ *
+ * Get DSO's fd:
+ *   int fd = dso__data_fd(dso, machine);
+ *   USE 'fd' SOMEHOW
+ *
+ * Read DSO's data:
+ *   n = dso__data_read_offset(dso_0, &machine, 0, buf, BUFSIZE);
+ *   n = dso__data_read_addr(dso_0, &machine, 0, buf, BUFSIZE);
+ *
+ * Eventually close DSO's fd:
+ *   dso__data_close(dso);
+ *
+ * It is not necessary to close the DSO object data file. Each time new
+ * DSO data file is opened, the limit (RLIMIT_NOFILE/2) is checked. Once
+ * it is crossed, the oldest opened DSO object is closed.
+ *
+ * The dso__delete function calls close_dso function to ensure the
+ * data file descriptor gets closed/unmapped before the dso object
+ * is freed.
+ *
+ * TODO
+*/
 int dso__data_fd(struct dso *dso, struct machine *machine);
+void dso__data_close(struct dso *dso);
+
 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
                              u64 offset, u8 *data, ssize_t size);
 ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
index 65795b8..d0281bd 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/types.h>
+#include <sys/mman.h>
 #include "event.h"
 #include "debug.h"
 #include "hist.h"
@@ -178,13 +179,14 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
                return -1;
        }
 
-       event->header.type = PERF_RECORD_MMAP;
+       event->header.type = PERF_RECORD_MMAP2;
 
        while (1) {
                char bf[BUFSIZ];
                char prot[5];
                char execname[PATH_MAX];
                char anonstr[] = "//anon";
+               unsigned int ino;
                size_t size;
                ssize_t n;
 
@@ -195,15 +197,20 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
                strcpy(execname, "");
 
                /* 00400000-0040c000 r-xp 00000000 fd:01 41038  /bin/cat */
-               n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n",
-                      &event->mmap.start, &event->mmap.len, prot,
-                      &event->mmap.pgoff,
-                      execname);
+               n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n",
+                      &event->mmap2.start, &event->mmap2.len, prot,
+                      &event->mmap2.pgoff, &event->mmap2.maj,
+                      &event->mmap2.min,
+                      &ino, execname);
+
                /*
                 * Anon maps don't have the execname.
                 */
-               if (n < 4)
+               if (n < 7)
                        continue;
+
+               event->mmap2.ino = (u64)ino;
+
                /*
                 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
                 */
@@ -212,6 +219,21 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
                else
                        event->header.misc = PERF_RECORD_MISC_GUEST_USER;
 
+               /* map protection and flags bits */
+               event->mmap2.prot = 0;
+               event->mmap2.flags = 0;
+               if (prot[0] == 'r')
+                       event->mmap2.prot |= PROT_READ;
+               if (prot[1] == 'w')
+                       event->mmap2.prot |= PROT_WRITE;
+               if (prot[2] == 'x')
+                       event->mmap2.prot |= PROT_EXEC;
+
+               if (prot[3] == 's')
+                       event->mmap2.flags |= MAP_SHARED;
+               else
+                       event->mmap2.flags |= MAP_PRIVATE;
+
                if (prot[2] != 'x') {
                        if (!mmap_data || prot[0] != 'r')
                                continue;
@@ -223,15 +245,15 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
                        strcpy(execname, anonstr);
 
                size = strlen(execname) + 1;
-               memcpy(event->mmap.filename, execname, size);
+               memcpy(event->mmap2.filename, execname, size);
                size = PERF_ALIGN(size, sizeof(u64));
-               event->mmap.len -= event->mmap.start;
-               event->mmap.header.size = (sizeof(event->mmap) -
-                                       (sizeof(event->mmap.filename) - size));
-               memset(event->mmap.filename + size, 0, machine->id_hdr_size);
-               event->mmap.header.size += machine->id_hdr_size;
-               event->mmap.pid = tgid;
-               event->mmap.tid = pid;
+               event->mmap2.len -= event->mmap.start;
+               event->mmap2.header.size = (sizeof(event->mmap2) -
+                                       (sizeof(event->mmap2.filename) - size));
+               memset(event->mmap2.filename + size, 0, machine->id_hdr_size);
+               event->mmap2.header.size += machine->id_hdr_size;
+               event->mmap2.pid = tgid;
+               event->mmap2.tid = pid;
 
                if (process(tool, event, &synth_sample, machine) != 0) {
                        rc = -1;
@@ -612,12 +634,15 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
 size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
 {
        return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64
-                          " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n",
+                          " %02x:%02x %"PRIu64" %"PRIu64"]: %c%c%c%c %s\n",
                       event->mmap2.pid, event->mmap2.tid, event->mmap2.start,
                       event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj,
                       event->mmap2.min, event->mmap2.ino,
                       event->mmap2.ino_generation,
-                      (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
+                      (event->mmap2.prot & PROT_READ) ? 'r' : '-',
+                      (event->mmap2.prot & PROT_WRITE) ? 'w' : '-',
+                      (event->mmap2.prot & PROT_EXEC) ? 'x' : '-',
+                      (event->mmap2.flags & MAP_SHARED) ? 's' : 'p',
                       event->mmap2.filename);
 }
 
index d970232..e5dd40a 100644 (file)
@@ -7,6 +7,7 @@
 #include "../perf.h"
 #include "map.h"
 #include "build-id.h"
+#include "perf_regs.h"
 
 struct mmap_event {
        struct perf_event_header header;
@@ -27,6 +28,8 @@ struct mmap2_event {
        u32 min;
        u64 ino;
        u64 ino_generation;
+       u32 prot;
+       u32 flags;
        char filename[PATH_MAX];
 };
 
@@ -87,6 +90,10 @@ struct regs_dump {
        u64 abi;
        u64 mask;
        u64 *regs;
+
+       /* Cached values/mask filled by first register access. */
+       u64 cache_regs[PERF_REGS_MAX];
+       u64 cache_mask;
 };
 
 struct stack_dump {
index 5c28d82..8606175 100644 (file)
@@ -589,10 +589,10 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
        }
 
        /*
-        * We default some events to a 1 default interval. But keep
+        * We default some events to have a default interval. But keep
         * it a weak assumption overridable by the user.
         */
-       if (!attr->sample_period || (opts->user_freq != UINT_MAX &&
+       if (!attr->sample_period || (opts->user_freq != UINT_MAX ||
                                     opts->user_interval != ULLONG_MAX)) {
                if (opts->freq) {
                        perf_evsel__set_sample_bit(evsel, PERIOD);
@@ -659,6 +659,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
                perf_evsel__set_sample_bit(evsel, WEIGHT);
 
        attr->mmap  = track;
+       attr->mmap2 = track && !perf_missing_features.mmap2;
        attr->comm  = track;
 
        if (opts->sample_transaction)
index 5a0a4b2..30df618 100644 (file)
@@ -128,6 +128,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
                               + unresolved_col_width + 2;
                        hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
                                           symlen);
+                       hists__new_col_len(hists, HISTC_MEM_DCACHELINE,
+                                          symlen + 1);
                } else {
                        symlen = unresolved_col_width + 4 + 2;
                        hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
@@ -439,9 +441,10 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
                        .map    = al->map,
                        .sym    = al->sym,
                },
-               .cpu    = al->cpu,
-               .ip     = al->addr,
-               .level  = al->level,
+               .cpu     = al->cpu,
+               .cpumode = al->cpumode,
+               .ip      = al->addr,
+               .level   = al->level,
                .stat = {
                        .nr_events = 1,
                        .period = period,
index d2bf035..742f49a 100644 (file)
@@ -72,6 +72,7 @@ enum hist_column {
        HISTC_MEM_TLB,
        HISTC_MEM_LVL,
        HISTC_MEM_SNOOP,
+       HISTC_MEM_DCACHELINE,
        HISTC_TRANSACTION,
        HISTC_NR_COLS, /* Last entry */
 };
index 7409ac8..0e5fea9 100644 (file)
@@ -1060,6 +1060,8 @@ int machine__process_mmap2_event(struct machine *machine,
                        event->mmap2.pid, event->mmap2.maj,
                        event->mmap2.min, event->mmap2.ino,
                        event->mmap2.ino_generation,
+                       event->mmap2.prot,
+                       event->mmap2.flags,
                        event->mmap2.filename, type);
 
        if (map == NULL)
@@ -1105,7 +1107,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
 
        map = map__new(&machine->user_dsos, event->mmap.start,
                        event->mmap.len, event->mmap.pgoff,
-                       event->mmap.pid, 0, 0, 0, 0,
+                       event->mmap.pid, 0, 0, 0, 0, 0, 0,
                        event->mmap.filename,
                        type);
 
index 8ccbb32..25c571f 100644 (file)
@@ -138,7 +138,7 @@ void map__init(struct map *map, enum map_type type,
 
 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                     u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
-                    u64 ino_gen, char *filename,
+                    u64 ino_gen, u32 prot, u32 flags, char *filename,
                     enum map_type type)
 {
        struct map *map = malloc(sizeof(*map));
@@ -157,6 +157,8 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                map->min = d_min;
                map->ino = ino;
                map->ino_generation = ino_gen;
+               map->prot = prot;
+               map->flags = flags;
 
                if ((anon || no_dso) && type == MAP__FUNCTION) {
                        snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
index ae2d451..7758c72 100644 (file)
@@ -35,6 +35,8 @@ struct map {
        bool                    referenced;
        bool                    erange_warned;
        u32                     priv;
+       u32                     prot;
+       u32                     flags;
        u64                     pgoff;
        u64                     reloc;
        u32                     maj, min; /* only valid for MMAP2 record */
@@ -118,7 +120,7 @@ void map__init(struct map *map, enum map_type type,
               u64 start, u64 end, u64 pgoff, struct dso *dso);
 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                     u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
-                    u64 ino_gen,
+                    u64 ino_gen, u32 prot, u32 flags,
                     char *filename, enum map_type type);
 struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
 void map__delete(struct map *map);
index a3539ef..43168fb 100644 (file)
@@ -1,11 +1,15 @@
 #include <errno.h>
 #include "perf_regs.h"
+#include "event.h"
 
 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
 {
        int i, idx = 0;
        u64 mask = regs->mask;
 
+       if (regs->cache_mask & (1 << id))
+               goto out;
+
        if (!(mask & (1 << id)))
                return -EINVAL;
 
@@ -14,6 +18,10 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
                        idx++;
        }
 
-       *valp = regs->regs[idx];
+       regs->cache_mask |= (1 << id);
+       regs->cache_regs[id] = regs->regs[idx];
+
+out:
+       *valp = regs->cache_regs[id];
        return 0;
 }
index 79c78f7..980dbf7 100644 (file)
@@ -2,7 +2,8 @@
 #define __PERF_REGS_H
 
 #include <linux/types.h>
-#include "event.h"
+
+struct regs_dump;
 
 #ifdef HAVE_PERF_REGS_SUPPORT
 #include <perf_regs.h>
@@ -11,6 +12,7 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);
 
 #else
 #define PERF_REGS_MASK 0
+#define PERF_REGS_MAX  0
 
 static inline const char *perf_reg_name(int id __maybe_unused)
 {
index 0d1542f..9a0a183 100644 (file)
@@ -628,11 +628,11 @@ static int __show_line_range(struct line_range *lr, const char *module)
 
        ret = debuginfo__find_line_range(dinfo, lr);
        debuginfo__delete(dinfo);
-       if (ret == 0) {
+       if (ret == 0 || ret == -ENOENT) {
                pr_warning("Specified source line is not found.\n");
                return -ENOENT;
        } else if (ret < 0) {
-               pr_warning("Debuginfo analysis failed. (%d)\n", ret);
+               pr_warning("Debuginfo analysis failed.\n");
                return ret;
        }
 
@@ -641,7 +641,7 @@ static int __show_line_range(struct line_range *lr, const char *module)
        ret = get_real_path(tmp, lr->comp_dir, &lr->path);
        free(tmp);      /* Free old path */
        if (ret < 0) {
-               pr_warning("Failed to find source file. (%d)\n", ret);
+               pr_warning("Failed to find source file path.\n");
                return ret;
        }
 
@@ -721,9 +721,14 @@ static int show_available_vars_at(struct debuginfo *dinfo,
        ret = debuginfo__find_available_vars_at(dinfo, pev, &vls,
                                                max_vls, externs);
        if (ret <= 0) {
-               pr_err("Failed to find variables at %s (%d)\n", buf, ret);
+               if (ret == 0 || ret == -ENOENT) {
+                       pr_err("Failed to find the address of %s\n", buf);
+                       ret = -ENOENT;
+               } else
+                       pr_warning("Debuginfo analysis failed.\n");
                goto end;
        }
+
        /* Some variables are found */
        fprintf(stdout, "Available variables at %s\n", buf);
        for (i = 0; i < ret; i++) {
index 9d8eb26..98e3047 100644 (file)
@@ -573,14 +573,13 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
        if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
                /* Search again in global variables */
                if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
+                       pr_warning("Failed to find '%s' in this function.\n",
+                                  pf->pvar->var);
                        ret = -ENOENT;
        }
        if (ret >= 0)
                ret = convert_variable(&vr_die, pf);
 
-       if (ret < 0)
-               pr_warning("Failed to find '%s' in this function.\n",
-                          pf->pvar->var);
        return ret;
 }
 
@@ -1281,7 +1280,11 @@ out:
        return ret;
 }
 
-/* Find available variables at given probe point */
+/*
+ * Find available variables at given probe point
+ * Return the number of found probe points. Return 0 if there is no
+ * matched probe point. Return <0 if an error occurs.
+ */
 int debuginfo__find_available_vars_at(struct debuginfo *dbg,
                                      struct perf_probe_event *pev,
                                      struct variable_list **vls,
index e108207..af7da56 100644 (file)
@@ -215,6 +215,7 @@ static void define_event_symbols(struct event_format *event,
        case PRINT_BSTRING:
        case PRINT_DYNAMIC_ARRAY:
        case PRINT_STRING:
+       case PRINT_BITMASK:
                break;
        case PRINT_TYPE:
                define_event_symbols(event, ev_name, args->typecast.item);
index cd9774d..1c41932 100644 (file)
@@ -197,6 +197,7 @@ static void define_event_symbols(struct event_format *event,
        case PRINT_BSTRING:
        case PRINT_DYNAMIC_ARRAY:
        case PRINT_FUNC:
+       case PRINT_BITMASK:
                /* we should warn... */
                return;
        }
@@ -622,6 +623,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
                        fprintf(ofp, "%s=", f->name);
                        if (f->flags & FIELD_IS_STRING ||
                            f->flags & FIELD_IS_FLAG ||
+                           f->flags & FIELD_IS_ARRAY ||
                            f->flags & FIELD_IS_SYMBOLIC)
                                fprintf(ofp, "%%s");
                        else if (f->flags & FIELD_IS_SIGNED)
index 45512ba..1ec57dd 100644 (file)
@@ -1,3 +1,4 @@
+#include <sys/mman.h>
 #include "sort.h"
 #include "hist.h"
 #include "comm.h"
@@ -784,6 +785,104 @@ static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
        return repsep_snprintf(bf, size, "%-*s", width, out);
 }
 
+static inline  u64 cl_address(u64 address)
+{
+       /* return the cacheline of the address */
+       return (address & ~(cacheline_size - 1));
+}
+
+static int64_t
+sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+       u64 l, r;
+       struct map *l_map, *r_map;
+
+       if (!left->mem_info)  return -1;
+       if (!right->mem_info) return 1;
+
+       /* group event types together */
+       if (left->cpumode > right->cpumode) return -1;
+       if (left->cpumode < right->cpumode) return 1;
+
+       l_map = left->mem_info->daddr.map;
+       r_map = right->mem_info->daddr.map;
+
+       /* if both are NULL, jump to sort on al_addr instead */
+       if (!l_map && !r_map)
+               goto addr;
+
+       if (!l_map) return -1;
+       if (!r_map) return 1;
+
+       if (l_map->maj > r_map->maj) return -1;
+       if (l_map->maj < r_map->maj) return 1;
+
+       if (l_map->min > r_map->min) return -1;
+       if (l_map->min < r_map->min) return 1;
+
+       if (l_map->ino > r_map->ino) return -1;
+       if (l_map->ino < r_map->ino) return 1;
+
+       if (l_map->ino_generation > r_map->ino_generation) return -1;
+       if (l_map->ino_generation < r_map->ino_generation) return 1;
+
+       /*
+        * Addresses with no major/minor numbers are assumed to be
+        * anonymous in userspace.  Sort those on pid then address.
+        *
+        * The kernel and non-zero major/minor mapped areas are
+        * assumed to be unity mapped.  Sort those on address.
+        */
+
+       if ((left->cpumode != PERF_RECORD_MISC_KERNEL) &&
+           (!(l_map->flags & MAP_SHARED)) &&
+           !l_map->maj && !l_map->min && !l_map->ino &&
+           !l_map->ino_generation) {
+               /* userspace anonymous */
+
+               if (left->thread->pid_ > right->thread->pid_) return -1;
+               if (left->thread->pid_ < right->thread->pid_) return 1;
+       }
+
+addr:
+       /* al_addr does all the right addr - start + offset calculations */
+       l = cl_address(left->mem_info->daddr.al_addr);
+       r = cl_address(right->mem_info->daddr.al_addr);
+
+       if (l > r) return -1;
+       if (l < r) return 1;
+
+       return 0;
+}
+
+static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
+                                         size_t size, unsigned int width)
+{
+
+       uint64_t addr = 0;
+       struct map *map = NULL;
+       struct symbol *sym = NULL;
+       char level = he->level;
+
+       if (he->mem_info) {
+               addr = cl_address(he->mem_info->daddr.al_addr);
+               map = he->mem_info->daddr.map;
+               sym = he->mem_info->daddr.sym;
+
+               /* print [s] for shared data mmaps */
+               if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
+                    map && (map->type == MAP__VARIABLE) &&
+                   (map->flags & MAP_SHARED) &&
+                   (map->maj || map->min || map->ino ||
+                    map->ino_generation))
+                       level = 's';
+               else if (!map)
+                       level = 'X';
+       }
+       return _hist_entry__sym_snprintf(map, sym, addr, level, bf, size,
+                                        width);
+}
+
 struct sort_entry sort_mispredict = {
        .se_header      = "Branch Mispredicted",
        .se_cmp         = sort__mispredict_cmp,
@@ -876,6 +975,13 @@ struct sort_entry sort_mem_snoop = {
        .se_width_idx   = HISTC_MEM_SNOOP,
 };
 
+struct sort_entry sort_mem_dcacheline = {
+       .se_header      = "Data Cacheline",
+       .se_cmp         = sort__dcacheline_cmp,
+       .se_snprintf    = hist_entry__dcacheline_snprintf,
+       .se_width_idx   = HISTC_MEM_DCACHELINE,
+};
+
 static int64_t
 sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
 {
@@ -1043,6 +1149,7 @@ static struct sort_dimension memory_sort_dimensions[] = {
        DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
        DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
        DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
+       DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline),
 };
 
 #undef DIM
index 5bf0098..041f0c9 100644 (file)
@@ -89,6 +89,7 @@ struct hist_entry {
        u64                     ip;
        u64                     transaction;
        s32                     cpu;
+       u8                      cpumode;
 
        struct hist_entry_diff  diff;
 
@@ -185,6 +186,7 @@ enum sort_type {
        SORT_MEM_TLB,
        SORT_MEM_LVL,
        SORT_MEM_SNOOP,
+       SORT_MEM_DCACHELINE,
 };
 
 /*
index bd5768d..25578b9 100644 (file)
@@ -250,7 +250,6 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
 
        /* Check the .eh_frame section for unwinding info */
        offset = elf_section_offset(fd, ".eh_frame_hdr");
-       close(fd);
 
        if (offset)
                ret = unwind_spec_ehframe(dso, machine, offset,
@@ -271,7 +270,6 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
 
        /* Check the .debug_frame section for unwinding info */
        *offset = elf_section_offset(fd, ".debug_frame");
-       close(fd);
 
        if (*offset)
                return 0;
index 7fff6be..95aefa7 100644 (file)
@@ -17,6 +17,7 @@
  * XXX We need to find a better place for these things...
  */
 unsigned int page_size;
+int cacheline_size;
 
 bool test_attr__enabled;
 
index b03da44..6686436 100644 (file)
@@ -304,6 +304,7 @@ char *rtrim(char *s);
 void dump_stack(void);
 
 extern unsigned int page_size;
+extern int cacheline_size;
 
 void get_term_dimensions(struct winsize *ws);
 
index 51267f4..2cede23 100644 (file)
@@ -2,7 +2,7 @@ PROGS := tm-resched-dscr
 
 all: $(PROGS)
 
-$(PROGS):
+$(PROGS): ../harness.c
 
 run_tests: all
        @-for PROG in $(PROGS); do \
index ee98e38..42d4c8c 100644 (file)
@@ -28,6 +28,8 @@
 #include <assert.h>
 #include <asm/tm.h>
 
+#include "utils.h"
+
 #define TBEGIN          ".long 0x7C00051D ;"
 #define TEND            ".long 0x7C00055D ;"
 #define TCHECK          ".long 0x7C00059C ;"
@@ -36,7 +38,8 @@
 #define SPRN_TEXASR     0x82
 #define SPRN_DSCR       0x03
 
-int main(void) {
+int test_body(void)
+{
        uint64_t rv, dscr1 = 1, dscr2, texasr;
 
        printf("Check DSCR TM context switch: ");
@@ -81,10 +84,15 @@ int main(void) {
                }
                if (dscr2 != dscr1) {
                        printf(" FAIL\n");
-                       exit(EXIT_FAILURE);
+                       return 1;
                } else {
                        printf(" OK\n");
-                       exit(EXIT_SUCCESS);
+                       return 0;
                }
        }
 }
+
+int main(void)
+{
+       return test_harness(test_body, "tm_resched_dscr");
+}