]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge tag 'tegra-for-3.7-drivers-i2c' of git://git.kernel.org/pub/scm/linux/kernel...
authorOlof Johansson <olof@lixom.net>
Mon, 17 Sep 2012 01:31:37 +0000 (18:31 -0700)
committerOlof Johansson <olof@lixom.net>
Mon, 17 Sep 2012 01:31:37 +0000 (18:31 -0700)
From Stephen Warren:

ARM: tegra: i2c driver enhancements mostly related to clocking

This branch contains a number of fixes and cleanups to the Tegra I2C
driver related to clocks. These are based on the common clock conversion
in order to avoid duplicating the clock driver changes before and after
the conversion. Finally, a bug-fix related to I2C_M_NOSTART is included.

This branch is based on previous pull request tegra-for-3.7-common-clk.

* tag 'tegra-for-3.7-drivers-i2c' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
  i2c: tegra: dynamically control fast clk
  i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20
  ARM: tegra: clock: remove unused clock entry for i2c
  ARM: tegra: clock: add connection name in i2c clock entry
  i2c: tegra: pass proper name for getting clock
  ARM: tegra: clock: add i2c fast clock entry in clock table
  ARM: Tegra: Add smp_twd clock for Tegra20
  ARM: tegra: cpu-tegra: explicitly manage re-parenting
  ARM: tegra: fix overflow in tegra20_pll_clk_round_rate()
  ARM: tegra: Fix data type for io address
  ARM: tegra: remove tegra_timer from tegra_list_clks
  ARM: tegra30: clocks: fix the wrong tegra_audio_sync_clk_ops name
  ARM: tegra: clocks: separate tegra_clk_32k_ops from Tegra20 and Tegra30
  ARM: tegra: Remove duplicate code
  ARM: tegra: Port tegra to generic clock framework
  ARM: tegra: Add clk_tegra structure and helper functions
  ARM: tegra: Rename tegra20 clock file
  ARM: tegra20: Separate out clk ops and clk data
  ARM: tegra30: Separate out clk ops and clk data
  ARM: tegra: fix U16 divider range check
  ...
  + sync to v3.6-rc4

Resolved remove/modify conflict in arch/arm/mach-sa1100/leds-hackkit.c
caused by the sync with v3.6-rc4.

Signed-off-by: Olof Johansson <olof@lixom.net>
1076 files changed:
Documentation/ABI/testing/sysfs-platform-ideapad-laptop
Documentation/DocBook/filesystems.tmpl
Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
Documentation/block/00-INDEX
Documentation/block/cfq-iosched.txt
Documentation/block/queue-sysfs.txt
Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
Documentation/devicetree/bindings/regulator/tps6586x.txt
Documentation/filesystems/Locking
Documentation/filesystems/porting
Documentation/filesystems/vfat.txt
Documentation/filesystems/vfs.txt
Documentation/laptops/laptop-mode.txt
Documentation/networking/netconsole.txt
Documentation/pinctrl.txt
Documentation/security/Yama.txt
Documentation/sysctl/vm.txt
Documentation/vm/hugetlbpage.txt
Documentation/w1/slaves/w1_therm
Documentation/watchdog/src/watchdog-test.c
MAINTAINERS
Makefile
arch/alpha/Kconfig
arch/alpha/include/asm/atomic.h
arch/alpha/include/asm/fpu.h
arch/alpha/include/asm/ptrace.h
arch/alpha/include/asm/socket.h
arch/alpha/include/asm/uaccess.h
arch/alpha/include/asm/unistd.h
arch/alpha/include/asm/word-at-a-time.h [new file with mode: 0644]
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/process.c
arch/alpha/kernel/systbls.S
arch/alpha/lib/Makefile
arch/alpha/lib/ev6-strncpy_from_user.S [deleted file]
arch/alpha/lib/ev67-strlen_user.S [deleted file]
arch/alpha/lib/strlen_user.S [deleted file]
arch/alpha/lib/strncpy_from_user.S [deleted file]
arch/alpha/mm/fault.c
arch/alpha/oprofile/common.c
arch/arm/Kconfig
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx27-3ds.dts
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53-ard.dts
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/imx6q-sabrelite.dts
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/kirkwood-iconnect.dts
arch/arm/boot/dts/twl6030.dtsi
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/mxs_defconfig
arch/arm/configs/tct_hammer_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/sched_clock.h
arch/arm/kernel/sched_clock.c
arch/arm/kernel/topology.c
arch/arm/lib/Makefile
arch/arm/lib/io-readsw-armv3.S [new file with mode: 0644]
arch/arm/lib/io-writesw-armv3.S [new file with mode: 0644]
arch/arm/lib/uaccess.S [new file with mode: 0644]
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-dove/common.c
arch/arm/mach-exynos/mach-origen.c
arch/arm/mach-exynos/mach-smdkv310.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/clk-imx27.c
arch/arm/mach-imx/clk-imx31.c
arch/arm/mach-imx/clk-imx51-imx53.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/headsmp.S [moved from arch/arm/mach-imx/head-v7.S with 100% similarity]
arch/arm/mach-imx/hotplug.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-kirkwood/Makefile.boot
arch/arm/mach-kirkwood/common.c
arch/arm/mach-mmp/sram.c
arch/arm/mach-mv78xx0/addr-map.c
arch/arm/mach-mv78xx0/common.c
arch/arm/mach-mxs/Kconfig
arch/arm/mach-mxs/Makefile
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/common-board-devices.c
arch/arm/mach-omap2/common-board-devices.h
arch/arm/mach-omap2/cpuidle44xx.c
arch/arm/mach-omap2/mux.h
arch/arm/mach-omap2/opp4xxx_data.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/sleep44xx.S
arch/arm/mach-omap2/twl-common.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-s3c24xx/Kconfig
arch/arm/mach-s3c24xx/include/mach/dma.h
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-harmony-power.c
arch/arm/mach-tegra/clock.c
arch/arm/mach-tegra/clock.h
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/cpu-tegra.c
arch/arm/mach-tegra/include/mach/clk.h
arch/arm/mach-tegra/tegra20_clocks.c [new file with mode: 0644]
arch/arm/mach-tegra/tegra20_clocks.h [new file with mode: 0644]
arch/arm/mach-tegra/tegra20_clocks_data.c [new file with mode: 0644]
arch/arm/mach-tegra/tegra2_clocks.c [deleted file]
arch/arm/mach-tegra/tegra30_clocks.c
arch/arm/mach-tegra/tegra30_clocks.h [new file with mode: 0644]
arch/arm/mach-tegra/tegra30_clocks_data.c [new file with mode: 0644]
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/board-mop500-msp.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/flush.c
arch/arm/mm/tlb-v7.S
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/include/plat/cpu.h
arch/arm/plat-omap/include/plat/multi.h
arch/arm/plat-omap/include/plat/uncompress.h
arch/arm/plat-orion/common.c
arch/arm/plat-orion/include/plat/common.h
arch/arm/plat-s3c24xx/dma.c
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/include/plat/hdmi.h [new file with mode: 0644]
arch/arm/plat-samsung/pm.c
arch/arm/vfp/vfpmodule.c
arch/blackfin/kernel/setup.c
arch/c6x/Kconfig
arch/c6x/include/asm/cache.h
arch/ia64/configs/generic_defconfig
arch/ia64/configs/gensparse_defconfig
arch/ia64/kernel/acpi.c
arch/m68k/Kconfig
arch/m68k/Kconfig.cpu
arch/m68k/apollo/config.c
arch/m68k/include/asm/Kbuild
arch/m68k/include/asm/MC68332.h [deleted file]
arch/m68k/include/asm/apollodma.h [deleted file]
arch/m68k/include/asm/apollohw.h
arch/m68k/include/asm/bitsperlong.h [deleted file]
arch/m68k/include/asm/cputime.h [deleted file]
arch/m68k/include/asm/delay.h
arch/m68k/include/asm/device.h [deleted file]
arch/m68k/include/asm/emergency-restart.h [deleted file]
arch/m68k/include/asm/errno.h [deleted file]
arch/m68k/include/asm/futex.h [deleted file]
arch/m68k/include/asm/ioctl.h [deleted file]
arch/m68k/include/asm/ipcbuf.h [deleted file]
arch/m68k/include/asm/irq_regs.h [deleted file]
arch/m68k/include/asm/kdebug.h [deleted file]
arch/m68k/include/asm/kmap_types.h [deleted file]
arch/m68k/include/asm/kvm_para.h [deleted file]
arch/m68k/include/asm/local.h [deleted file]
arch/m68k/include/asm/local64.h [deleted file]
arch/m68k/include/asm/mac_mouse.h [deleted file]
arch/m68k/include/asm/mcfmbus.h [deleted file]
arch/m68k/include/asm/mman.h [deleted file]
arch/m68k/include/asm/mutex.h [deleted file]
arch/m68k/include/asm/percpu.h [deleted file]
arch/m68k/include/asm/resource.h [deleted file]
arch/m68k/include/asm/sbus.h [deleted file]
arch/m68k/include/asm/scatterlist.h [deleted file]
arch/m68k/include/asm/sections.h [deleted file]
arch/m68k/include/asm/shm.h [deleted file]
arch/m68k/include/asm/siginfo.h [deleted file]
arch/m68k/include/asm/statfs.h [deleted file]
arch/m68k/include/asm/topology.h [deleted file]
arch/m68k/include/asm/types.h [deleted file]
arch/m68k/include/asm/unaligned.h
arch/m68k/include/asm/xor.h [deleted file]
arch/m68k/kernel/setup_no.c
arch/m68k/kernel/sys_m68k.c
arch/m68k/kernel/vmlinux-nommu.lds
arch/m68k/kernel/vmlinux-std.lds
arch/m68k/kernel/vmlinux-sun3.lds
arch/m68k/lib/muldi3.c
arch/m68k/mm/init_mm.c
arch/m68k/mm/init_no.c
arch/m68k/platform/68328/head-de2.S
arch/m68k/platform/68328/head-pilot.S
arch/m68k/platform/68328/head-ram.S
arch/m68k/platform/68328/head-rom.S
arch/m68k/platform/68360/head-ram.S
arch/m68k/platform/68360/head-rom.S
arch/m68k/platform/coldfire/head.S
arch/m68k/sun3/prom/init.c
arch/microblaze/include/asm/sections.h
arch/microblaze/kernel/microblaze_ksyms.c
arch/microblaze/kernel/setup.c
arch/microblaze/kernel/vmlinux.lds.S
arch/mips/Kconfig
arch/mips/alchemy/board-mtx1.c
arch/mips/ath79/dev-usb.c
arch/mips/ath79/gpio.c
arch/mips/bcm63xx/dev-spi.c
arch/mips/cavium-octeon/octeon-irq.c
arch/mips/include/asm/mach-ath79/ar71xx_regs.h
arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
arch/mips/include/asm/mach-cavium-octeon/irq.h
arch/mips/include/asm/module.h
arch/mips/include/asm/r4k-timer.h
arch/mips/kernel/module.c
arch/mips/kernel/smp.c
arch/mips/kernel/sync-r4k.c
arch/mips/mti-malta/malta-pci.c
arch/mips/pci/pci-ar724x.c
arch/parisc/include/asm/atomic.h
arch/parisc/kernel/process.c
arch/parisc/kernel/sys_parisc.c
arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
arch/powerpc/configs/85xx/p1023rds_defconfig
arch/powerpc/configs/corenet32_smp_defconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/configs/g5_defconfig
arch/powerpc/configs/mpc83xx_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/include/asm/mpic_msgr.h
arch/powerpc/kernel/dma-iommu.c
arch/powerpc/kernel/hw_breakpoint.c
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/syscalls.c
arch/powerpc/kvm/book3s_32_mmu_host.c
arch/powerpc/kvm/book3s_64_mmu_host.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/e500_tlb.c
arch/powerpc/lib/copyuser_power7.S
arch/powerpc/lib/memcpy_power7.S
arch/powerpc/mm/mem.c
arch/powerpc/perf/core-book3s.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/mpic_msgr.c
arch/powerpc/xmon/xmon.c
arch/s390/Kconfig
arch/s390/include/asm/elf.h
arch/s390/include/asm/posix_types.h
arch/s390/include/asm/smp.h
arch/s390/include/asm/sparsemem.h
arch/s390/include/asm/syscall.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/ptrace.c
arch/s390/kernel/sys_s390.c
arch/sh/drivers/dma/dma-sh.c
arch/sh/include/asm/sections.h
arch/sh/include/cpu-sh2a/cpu/sh7269.h
arch/sh/kernel/cpu/sh2a/pinmux-sh7269.c
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms_32.c
arch/sh/kernel/vmlinux.lds.S
arch/sh/lib/mcount.S
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/mm/init_64.c
arch/x86/Kconfig
arch/x86/Makefile
arch/x86/boot/Makefile
arch/x86/include/asm/mce.h
arch/x86/include/asm/perf_event.h
arch/x86/include/asm/spinlock.h
arch/x86/kernel/acpi/sleep.c
arch/x86/kernel/acpi/sleep.h
arch/x86/kernel/acpi/wakeup_32.S
arch/x86/kernel/acpi/wakeup_64.S
arch/x86/kernel/alternative.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/mcheck/mce-severity.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event.h
arch/x86/kernel/cpu/perf_event_amd_ibs.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/cpu/perf_event_intel_uncore.c
arch/x86/kernel/cpu/perf_event_intel_uncore.h
arch/x86/kernel/irq.c
arch/x86/kernel/kdebugfs.c
arch/x86/kernel/microcode_amd.c
arch/x86/kvm/emulate.c
arch/x86/kvm/i8259.c
arch/x86/kvm/mmu.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/hugetlbpage.c
arch/x86/mm/pageattr.c
arch/x86/mm/srat.c
arch/x86/platform/efi/efi.c
arch/x86/realmode/rm/Makefile
arch/x86/syscalls/syscall_64.tbl
arch/x86/xen/enlighten.c
arch/x86/xen/p2m.c
arch/x86/xen/setup.c
arch/x86/xen/suspend.c
arch/x86/xen/xen-ops.h
block/blk-lib.c
block/blk-merge.c
block/genhd.c
drivers/acpi/ac.c
drivers/acpi/acpica/achware.h
drivers/acpi/acpica/hwesleep.c
drivers/acpi/acpica/hwsleep.c
drivers/acpi/acpica/hwxfsleep.c
drivers/acpi/acpica/tbxface.c
drivers/acpi/battery.c
drivers/acpi/button.c
drivers/acpi/fan.c
drivers/acpi/numa.c
drivers/acpi/pci_root.c
drivers/acpi/power.c
drivers/acpi/processor_driver.c
drivers/acpi/sbs.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/acpi/thermal.c
drivers/ata/Kconfig
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ata_piix.c
drivers/ata/libahci.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/pata_atiixp.c
drivers/atm/iphase.c
drivers/base/core.c
drivers/base/power/clock_ops.c
drivers/base/power/common.c
drivers/base/power/runtime.c
drivers/bcma/host_pci.c
drivers/bcma/sprom.c
drivers/block/cciss_scsi.c
drivers/block/drbd/drbd_bitmap.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_req.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/char/agp/intel-agp.h
drivers/char/agp/intel-gtt.c
drivers/char/hw_random/omap-rng.c
drivers/char/tpm/tpm_tis.c
drivers/clocksource/cs5535-clockevt.c
drivers/cpufreq/omap-cpufreq.c
drivers/cpufreq/pcc-cpufreq.c
drivers/cpuidle/coupled.c
drivers/crypto/caam/jr.c
drivers/crypto/hifn_795x.c
drivers/dma/imx-dma.c
drivers/dma/tegra20-apb-dma.c
drivers/extcon/extcon_gpio.c
drivers/gpio/gpio-em.c
drivers/gpio/gpio-langwell.c
drivers/gpio/gpio-msic.c
drivers/gpio/gpio-mxc.c
drivers/gpio/gpio-pxa.c
drivers/gpio/gpio-samsung.c
drivers/gpio/gpio-sch.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_edid_load.c
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/drm_proc.c
drivers/gpu/drm/gma500/psb_intel_display.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_sysfs.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_modes.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/gpu/drm/nouveau/nouveau_i2c.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv84_fifo.c
drivers/gpu/drm/nouveau/nvc0_pm.c
drivers/gpu/drm/nouveau/nvd0_display.c
drivers/gpu/drm/nouveau/nve0_fifo.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_atpx_handler.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_cursor.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_gart.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/reg_srcs/r600
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/radeon/sid.h
drivers/gpu/drm/udl/Kconfig
drivers/gpu/drm/udl/udl_gem.c
drivers/gpu/drm/udl/udl_modeset.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/vga/vga_switcheroo.c
drivers/hid/hid-core.c
drivers/hwmon/asus_atk0110.c
drivers/hwmon/coretemp.c
drivers/hwmon/w83627hf.c
drivers/i2c/busses/i2c-diolan-u2c.c
drivers/i2c/busses/i2c-nomadik.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-tegra.c
drivers/ide/ide-pm.c
drivers/idle/intel_idle.c
drivers/iio/frequency/adf4350.c
drivers/iio/light/adjd_s311.c
drivers/iio/light/lm3533-als.c
drivers/infiniband/core/ucma.c
drivers/infiniband/hw/amso1100/c2_rnic.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/mlx4/mad.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/ocrdma/ocrdma_main.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/qib/qib_sd7220.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/input/touchscreen/eeti_ts.c
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/exynos-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel_irq_remapping.c
drivers/iommu/tegra-smmu.c
drivers/isdn/isdnloop/isdnloop.c
drivers/isdn/mISDN/layer2.c
drivers/leds/led-triggers.c
drivers/leds/leds-lp8788.c
drivers/leds/leds-renesas-tpu.c
drivers/md/md.c
drivers/md/raid10.c
drivers/md/raid10.h
drivers/media/dvb/siano/smsusb.c
drivers/media/radio/radio-shark.c
drivers/media/radio/radio-shark2.c
drivers/media/radio/si470x/radio-si470x-common.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/radio/si470x/radio-si470x-usb.c
drivers/media/rc/Kconfig
drivers/media/video/gspca/jl2005bcd.c
drivers/media/video/gspca/spca506.c
drivers/media/video/mem2mem_testdev.c
drivers/media/video/mx1_camera.c
drivers/media/video/mx2_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/soc_camera.c
drivers/media/video/soc_mediabus.c
drivers/media/video/uvc/uvc_queue.c
drivers/media/video/v4l2-ioctl.c
drivers/mfd/Kconfig
drivers/mfd/asic3.c
drivers/mfd/ezx-pcap.c
drivers/misc/mei/interrupt.c
drivers/misc/mei/main.c
drivers/misc/sgi-xp/xpc_uv.c
drivers/misc/ti-st/st_ll.c
drivers/mtd/maps/uclinux.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/omap2.c
drivers/net/appletalk/cops.c
drivers/net/appletalk/ltpc.c
drivers/net/bonding/bond_main.c
drivers/net/cris/eth_v10.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
drivers/net/ethernet/freescale/fs_enet/mii-fec.c
drivers/net/ethernet/intel/e1000e/82571.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/igb/e1000_82575.c
drivers/net/ethernet/intel/igb/e1000_regs.h
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/icm.c
drivers/net/ethernet/mellanox/mlx4/icm.h
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx4/profile.c
drivers/net/ethernet/mellanox/mlx4/sense.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/renesas/Kconfig
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx.h
drivers/net/ethernet/sfc/ethtool.c
drivers/net/ethernet/sfc/tx.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ethernet/ti/davinci_cpdma.c
drivers/net/ethernet/xscale/ixp4xx_eth.c
drivers/net/hyperv/netvsc.c
drivers/net/hyperv/rndis_filter.c
drivers/net/irda/bfin_sir.c
drivers/net/irda/ks959-sir.c
drivers/net/irda/ksdazzle-sir.c
drivers/net/macvtap.c
drivers/net/netconsole.c
drivers/net/phy/mdio-mux-gpio.c
drivers/net/phy/mdio-mux.c
drivers/net/ppp/pptp.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/usb/cdc-phonet.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/sierra_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/wan/dscc4.c
drivers/net/wimax/i2400m/fw.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/mac.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/brcm80211/brcmsmac/channel.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/iwlwifi/dvm/rs.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/of/base.c
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pinctrl/core.c
drivers/pinctrl/pinctrl-imx23.c
drivers/pinctrl/pinctrl-imx28.c
drivers/pinctrl/pinctrl-imx51.c
drivers/pinctrl/pinctrl-nomadik-db8500.c
drivers/pinctrl/pinctrl-nomadik.c
drivers/pinctrl/pinctrl-sirf.c
drivers/pinctrl/pinctrl-u300.c
drivers/platform/x86/Kconfig
drivers/platform/x86/apple-gmux.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/asus-wmi.h
drivers/platform/x86/classmate-laptop.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/fujitsu-tablet.c
drivers/platform/x86/hdaps.c
drivers/platform/x86/hp_accel.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/msi-laptop.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/toshiba_bluetooth.c
drivers/platform/x86/xo15-ebook.c
drivers/pwm/Kconfig
drivers/pwm/core.c
drivers/pwm/pwm-samsung.c
drivers/pwm/pwm-tegra.c
drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/pwm-vt8500.c
drivers/rapidio/devices/tsi721.c
drivers/regulator/ab3100.c
drivers/regulator/anatop-regulator.c
drivers/regulator/core.c
drivers/regulator/gpio-regulator.c
drivers/regulator/palmas-regulator.c
drivers/regulator/tps6586x-regulator.c
drivers/regulator/twl-regulator.c
drivers/rtc/interface.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-pcf2123.c
drivers/rtc/rtc-rs5c348.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_ioctl.c
drivers/s390/char/sclp_sdias.c
drivers/sh/intc/core.c
drivers/spi/spi-bcm63xx.c
drivers/spi/spi-coldfire-qspi.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-pl022.c
drivers/spi/spi-s3c64xx.c
drivers/staging/comedi/drivers.c
drivers/staging/comedi/drivers/adv_pci1710.c
drivers/staging/comedi/drivers/adv_pci1723.c
drivers/staging/comedi/drivers/adv_pci_dio.c
drivers/staging/comedi/drivers/daqboard2000.c
drivers/staging/comedi/drivers/dt3000.c
drivers/staging/comedi/drivers/rtd520.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxfast.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/csr/Kconfig
drivers/staging/iio/adc/ad7192.c
drivers/staging/iio/adc/ad7298_ring.c
drivers/staging/iio/adc/ad7780.c
drivers/staging/iio/adc/ad7793.c
drivers/staging/vt6656/main_usb.c
drivers/staging/winbond/wbusb.c
drivers/target/target_core_pscsi.c
drivers/target/target_core_transport.c
drivers/target/tcm_fc/tcm_fc.h
drivers/target/tcm_fc/tfc_cmd.c
drivers/target/tcm_fc/tfc_sess.c
drivers/tty/serial/Kconfig
drivers/tty/serial/ifx6x60.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/pmac_zilog.c
drivers/usb/Kconfig
drivers/usb/chipidea/Kconfig
drivers/usb/class/cdc-acm.c
drivers/usb/early/ehci-dbgp.c
drivers/usb/gadget/u_ether.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-sead3.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/pci-quirks.h
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/emi62.c
drivers/usb/musb/Kconfig
drivers/usb/musb/musb_dsps.c
drivers/usb/renesas_usbhs/common.c
drivers/usb/renesas_usbhs/mod_host.c
drivers/usb/serial/bus.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/ipw.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/serial/usb-wwan.h
drivers/usb/serial/usb_wwan.c
drivers/vfio/vfio.c
drivers/vhost/Kconfig
drivers/vhost/Kconfig.tcm [new file with mode: 0644]
drivers/vhost/Makefile
drivers/vhost/tcm_vhost.c [new file with mode: 0644]
drivers/vhost/tcm_vhost.h [new file with mode: 0644]
drivers/video/console/fbcon.c
drivers/w1/slaves/w1_therm.c
drivers/w1/w1_family.h
drivers/watchdog/booke_wdt.c
drivers/watchdog/da9052_wdt.c
drivers/xen/platform-pci.c
drivers/zorro/zorro.c
fs/autofs4/expire.c
fs/bio.c
fs/block_dev.c
fs/btrfs/backref.c
fs/btrfs/compression.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/delayed-ref.c
fs/btrfs/delayed-ref.h
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/file-item.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/locking.c
fs/btrfs/ordered-data.c
fs/btrfs/qgroup.c
fs/btrfs/root-tree.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/buffer.c
fs/ceph/debugfs.c
fs/ceph/inode.c
fs/ceph/ioctl.c
fs/compat.c
fs/direct-io.c
fs/eventpoll.c
fs/exofs/inode.c
fs/exofs/ore.c
fs/exofs/super.c
fs/ext3/inode.c
fs/ext3/super.c
fs/ext4/balloc.c
fs/ext4/bitmap.c
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/super.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/gfs2/meta_io.c
fs/hfs/mdb.c
fs/jbd/journal.c
fs/jbd2/journal.c
fs/logfs/dev_bdev.c
fs/logfs/inode.c
fs/logfs/journal.c
fs/logfs/readwrite.c
fs/logfs/segment.c
fs/namei.c
fs/nfs/Makefile
fs/nfs/client.c
fs/nfs/idmap.c
fs/nfs/nfs3proc.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4super.c
fs/nfs/nfs4xdr.c
fs/nfs/objlayout/objio_osd.c
fs/nfs/pagelist.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/nfs4callback.c
fs/nfsd/state.h
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.h
fs/open.c
fs/quota/dquot.c
fs/reiserfs/bitmap.c
fs/reiserfs/inode.c
fs/super.c
fs/ubifs/debug.h
fs/ubifs/file.c
fs/ubifs/lpt.c
fs/ubifs/recovery.c
fs/ubifs/replay.c
fs/ubifs/super.c
fs/udf/inode.c
fs/udf/super.c
fs/xfs/xfs_discard.c
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_rtalloc.c
include/acpi/acpixf.h
include/acpi/actypes.h
include/asm-generic/mutex-xchg.h
include/drm/drm_crtc.h
include/drm/drm_mode.h
include/drm/drm_pciids.h
include/drm/radeon_drm.h
include/linux/Kbuild
include/linux/acpi.h
include/linux/backing-dev.h
include/linux/bcma/bcma_driver_chipcommon.h
include/linux/blkdev.h
include/linux/can.h
include/linux/compaction.h
include/linux/cpuidle.h
include/linux/efi.h
include/linux/fs.h
include/linux/ftrace_event.h
include/linux/fuse.h
include/linux/hardirq.h
include/linux/if_team.h
include/linux/iio/frequency/adf4350.h
include/linux/input/eeti_ts.h
include/linux/iommu.h
include/linux/ipv6.h
include/linux/irq.h
include/linux/jbd2.h
include/linux/jiffies.h
include/linux/kdb.h
include/linux/kref.h
include/linux/ktime.h
include/linux/mfd/ezx-pcap.h
include/linux/mv643xx_eth.h
include/linux/netdevice.h
include/linux/netfilter/nf_conntrack_sip.h
include/linux/netpoll.h
include/linux/nfs_page.h
include/linux/nfs_xdr.h
include/linux/of.h
include/linux/perf_event.h
include/linux/pinctrl/consumer.h
include/linux/sched.h
include/linux/security.h
include/linux/string.h
include/linux/time.h
include/linux/timex.h
include/linux/topology.h
include/linux/writeback.h
include/net/cfg80211.h
include/net/codel.h
include/net/dst.h
include/net/inet_connection_sock.h
include/net/inet_sock.h
include/net/ip.h
include/net/llc.h
include/net/scm.h
include/net/sock.h
include/net/tcp.h
include/net/xfrm.h
include/sound/pcm.h
include/target/target_core_base.h
include/trace/events/sched.h
include/trace/ftrace.h
include/xen/events.h
init/main.c
ipc/mqueue.c
kernel/audit_tree.c
kernel/debug/kdb/kdb_debugger.c
kernel/debug/kdb/kdb_io.c
kernel/debug/kdb/kdb_main.c
kernel/events/callchain.c
kernel/events/core.c
kernel/events/internal.h
kernel/fork.c
kernel/futex.c
kernel/irq/manage.c
kernel/power/suspend.c
kernel/printk.c
kernel/sched/core.c
kernel/sched/cpupri.c
kernel/sched/fair.c
kernel/sched/rt.c
kernel/sched/sched.h
kernel/sched/stop_task.c
kernel/task_work.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/timekeeping.c
kernel/timer.c
kernel/trace/trace_event_perf.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_syscalls.c
kernel/trace/trace_uprobe.c
kernel/watchdog.c
mm/backing-dev.c
mm/compaction.c
mm/filemap.c
mm/internal.h
mm/mmap.c
mm/page-writeback.c
mm/page_alloc.c
mm/slab.c
net/8021q/vlan_dev.c
net/atm/common.c
net/atm/pvc.c
net/batman-adv/gateway_client.c
net/batman-adv/translation-table.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sock.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/tty.c
net/bluetooth/sco.c
net/bluetooth/smp.c
net/bridge/br_device.c
net/bridge/br_forward.c
net/bridge/br_if.c
net/bridge/br_private.h
net/caif/chnl_net.c
net/ceph/ceph_common.c
net/ceph/debugfs.c
net/ceph/messenger.c
net/ceph/mon_client.c
net/core/dev.c
net/core/dst.c
net/core/netpoll.c
net/core/netprio_cgroup.c
net/core/scm.c
net/core/sock.c
net/dccp/ccid.h
net/dccp/ccids/ccid3.c
net/ipv4/fib_trie.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_output.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_metrics.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/proc.c
net/ipv6/tcp_ipv6.c
net/ipv6/xfrm6_policy.c
net/l2tp/l2tp_ip6.c
net/llc/af_llc.c
net/llc/llc_input.c
net/llc/llc_station.c
net/mac80211/mesh.c
net/mac80211/mlme.c
net/mac80211/scan.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_sip.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/sched/act_gact.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_pedit.c
net/sched/act_simple.c
net/sched/sch_qfq.c
net/socket.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcsock.c
net/unix/af_unix.c
net/wireless/core.c
net/wireless/core.h
net/wireless/reg.c
net/wireless/util.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
scripts/checkpatch.pl
scripts/decodecode
scripts/kernel-doc
security/yama/yama_lsm.c
sound/arm/pxa2xx-ac97.c
sound/atmel/abdac.c
sound/atmel/ac97c.c
sound/core/sgbuf.c
sound/drivers/aloop.c
sound/drivers/dummy.c
sound/drivers/pcsp/pcsp.c
sound/isa/als100.c
sound/oss/sb_audio.c
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/ctxfi/ctatc.c
sound/pci/emu10k1/memory.c
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_beep.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_proc.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/lx6464es/lx6464es.c
sound/pci/rme9652/hdspm.c
sound/pci/sis7019.c
sound/ppc/powermac.c
sound/ppc/snd_ps3.c
sound/soc/blackfin/bf6xx-sport.c
sound/soc/codecs/ab8500-codec.c
sound/soc/codecs/ad1980.c
sound/soc/codecs/mc13783.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9713.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/imx-ssi.c
sound/soc/mxs/Kconfig
sound/soc/mxs/mxs-saif.c
sound/soc/omap/mcbsp.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-pcm.c
sound/soc/samsung/pcm.c
sound/soc/soc-core.c
sound/soc/soc-jack.c
sound/soc/tegra/tegra_alc5632.c
sound/soc/tegra/tegra_wm8903.c
sound/soc/ux500/ux500_msp_dai.c
sound/soc/ux500/ux500_msp_i2s.c
sound/soc/ux500/ux500_msp_i2s.h
sound/usb/endpoint.c
sound/usb/pcm.c
tools/perf/Makefile
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-test.c
tools/perf/builtin-top.c
tools/perf/util/event.h
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/header.c
tools/perf/util/intlist.c [new file with mode: 0644]
tools/perf/util/intlist.h [new file with mode: 0644]
tools/perf/util/parse-events-test.c
tools/perf/util/parse-options.c
tools/perf/util/python-ext-sources
tools/perf/util/python.c
tools/perf/util/rblist.c [new file with mode: 0644]
tools/perf/util/rblist.h [new file with mode: 0644]
tools/perf/util/session.c
tools/perf/util/session.h
tools/perf/util/strlist.c
tools/perf/util/strlist.h
tools/perf/util/symbol.c
tools/perf/util/target.c
virt/kvm/kvm_main.c

index 814b01354c414caf71337d115b41fc92c89769b8..b31e782bd9850628f77f683ba0f87a5ab6d169ae 100644 (file)
@@ -5,4 +5,15 @@ Contact:       "Ike Panhc <ike.pan@canonical.com>"
 Description:
                Control the power of camera module. 1 means on, 0 means off.
 
+What:          /sys/devices/platform/ideapad/fan_mode
+Date:          June 2012
+KernelVersion: 3.6
+Contact:       "Maxim Mikityanskiy <maxtram95@gmail.com>"
+Description:
+               Change fan mode
+               There are four available modes:
+                       * 0 -> Super Silent Mode
+                       * 1 -> Standard Mode
+                       * 2 -> Dust Cleaning
+                       * 4 -> Efficient Thermal Dissipation Mode
 
index 3fca32c41927130dae636a93504d7d8aacdee90e..25b58efd955dd2bebf2d716aea851fe283f792c1 100644 (file)
@@ -224,8 +224,8 @@ all your transactions.
 </para>
 
 <para>
-Then at umount time , in your put_super() (2.4) or write_super() (2.5)
-you can then call journal_destroy() to clean up your in-core journal object.
+Then at umount time , in your put_super() you can then call journal_destroy()
+to clean up your in-core journal object.
 </para>
 
 <para>
index 720395127904574b69db6dd2b042f46b3d14901b..701138f1209de10ae439aff4da056803fbb79713 100644 (file)
@@ -125,7 +125,7 @@ the structure refers to a radio tuner the
 <constant>V4L2_TUNER_CAP_NORM</constant> flags can't be used.</para>
 <para>If multiple frequency bands are supported, then
 <structfield>capability</structfield> is the union of all
-<structfield>capability></structfield> fields of each &v4l2-frequency-band;.
+<structfield>capability</structfield> fields of each &v4l2-frequency-band;.
 </para></entry>
          </row>
          <row>
index d111e3b23db0bbc0bdf23d81c27e74158ccd9a66..d18ecd827c408d0fb42a8d8a7fc669ce88c95fc2 100644 (file)
@@ -3,15 +3,21 @@
 biodoc.txt
        - Notes on the Generic Block Layer Rewrite in Linux 2.5
 capability.txt
-       - Generic Block Device Capability (/sys/block/<disk>/capability)
+       - Generic Block Device Capability (/sys/block/<device>/capability)
+cfq-iosched.txt
+       - CFQ IO scheduler tunables
+data-integrity.txt
+       - Block data integrity
 deadline-iosched.txt
        - Deadline IO scheduler tunables
 ioprio.txt
        - Block io priorities (in CFQ scheduler)
+queue-sysfs.txt
+       - Queue's sysfs entries
 request.txt
        - The members of struct request (in include/linux/blkdev.h)
 stat.txt
-       - Block layer statistics in /sys/block/<dev>/stat
+       - Block layer statistics in /sys/block/<device>/stat
 switching-sched.txt
        - Switching I/O schedulers at runtime
 writeback_cache_control.txt
index 6d670f570451a14c1ce4f8c2eb1c69d52736ee01..d89b4fe724d75393a003b33c22bf531252c29672 100644 (file)
@@ -1,3 +1,14 @@
+CFQ (Complete Fairness Queueing)
+===============================
+
+The main aim of CFQ scheduler is to provide a fair allocation of the disk
+I/O bandwidth for all the processes which requests an I/O operation.
+
+CFQ maintains the per process queue for the processes which request I/O
+operation(syncronous requests). In case of asynchronous requests, all the
+requests from all the processes are batched together according to their
+process's I/O priority.
+
 CFQ ioscheduler tunables
 ========================
 
@@ -25,6 +36,72 @@ there are multiple spindles behind single LUN (Host based hardware RAID
 controller or for storage arrays), setting slice_idle=0 might end up in better
 throughput and acceptable latencies.
 
+back_seek_max
+-------------
+This specifies, given in Kbytes, the maximum "distance" for backward seeking.
+The distance is the amount of space from the current head location to the
+sectors that are backward in terms of distance.
+
+This parameter allows the scheduler to anticipate requests in the "backward"
+direction and consider them as being the "next" if they are within this
+distance from the current head location.
+
+back_seek_penalty
+-----------------
+This parameter is used to compute the cost of backward seeking. If the
+backward distance of request is just 1/back_seek_penalty from a "front"
+request, then the seeking cost of two requests is considered equivalent.
+
+So scheduler will not bias toward one or the other request (otherwise scheduler
+will bias toward front request). Default value of back_seek_penalty is 2.
+
+fifo_expire_async
+-----------------
+This parameter is used to set the timeout of asynchronous requests. Default
+value of this is 248ms.
+
+fifo_expire_sync
+----------------
+This parameter is used to set the timeout of synchronous requests. Default
+value of this is 124ms. In case to favor synchronous requests over asynchronous
+one, this value should be decreased relative to fifo_expire_async.
+
+slice_async
+-----------
+This parameter is same as of slice_sync but for asynchronous queue. The
+default value is 40ms.
+
+slice_async_rq
+--------------
+This parameter is used to limit the dispatching of asynchronous request to
+device request queue in queue's slice time. The maximum number of request that
+are allowed to be dispatched also depends upon the io priority. Default value
+for this is 2.
+
+slice_sync
+----------
+When a queue is selected for execution, the queues IO requests are only
+executed for a certain amount of time(time_slice) before switching to another
+queue. This parameter is used to calculate the time slice of synchronous
+queue.
+
+time_slice is computed using the below equation:-
+time_slice = slice_sync + (slice_sync/5 * (4 - prio)). To increase the
+time_slice of synchronous queue, increase the value of slice_sync. Default
+value is 100ms.
+
+quantum
+-------
+This specifies the number of request dispatched to the device queue. In a
+queue's time slice, a request will not be dispatched if the number of request
+in the device exceeds this parameter. This parameter is used for synchronous
+request.
+
+In case of storage with several disk, this setting can limit the parallel
+processing of request. Therefore, increasing the value can imporve the
+performace although this can cause the latency of some I/O to increase due
+to more number of requests.
+
 CFQ IOPS Mode for group scheduling
 ===================================
 Basic CFQ design is to provide priority based time slices. Higher priority
index 6518a55273e7094f62f84a5d83467fd96b26fd26..e54ac1d53403094c59e019b1f5e5397e8f4f637d 100644 (file)
@@ -9,20 +9,71 @@ These files are the ones found in the /sys/block/xxx/queue/ directory.
 Files denoted with a RO postfix are readonly and the RW postfix means
 read-write.
 
+add_random (RW)
+----------------
+This file allows to trun off the disk entropy contribution. Default
+value of this file is '1'(on).
+
+discard_granularity (RO)
+-----------------------
+This shows the size of internal allocation of the device in bytes, if
+reported by the device. A value of '0' means device does not support
+the discard functionality.
+
+discard_max_bytes (RO)
+----------------------
+Devices that support discard functionality may have internal limits on
+the number of bytes that can be trimmed or unmapped in a single operation.
+The discard_max_bytes parameter is set by the device driver to the maximum
+number of bytes that can be discarded in a single operation. Discard
+requests issued to the device must not exceed this limit. A discard_max_bytes
+value of 0 means that the device does not support discard functionality.
+
+discard_zeroes_data (RO)
+------------------------
+When read, this file will show if the discarded block are zeroed by the
+device or not. If its value is '1' the blocks are zeroed otherwise not.
+
 hw_sector_size (RO)
 -------------------
 This is the hardware sector size of the device, in bytes.
 
+iostats (RW)
+-------------
+This file is used to control (on/off) the iostats accounting of the
+disk.
+
+logical_block_size (RO)
+-----------------------
+This is the logcal block size of the device, in bytes.
+
 max_hw_sectors_kb (RO)
 ----------------------
 This is the maximum number of kilobytes supported in a single data transfer.
 
+max_integrity_segments (RO)
+---------------------------
+When read, this file shows the max limit of integrity segments as
+set by block layer which a hardware controller can handle.
+
 max_sectors_kb (RW)
 -------------------
 This is the maximum number of kilobytes that the block layer will allow
 for a filesystem request. Must be smaller than or equal to the maximum
 size allowed by the hardware.
 
+max_segments (RO)
+-----------------
+Maximum number of segments of the device.
+
+max_segment_size (RO)
+---------------------
+Maximum segment size of the device.
+
+minimum_io_size (RO)
+--------------------
+This is the smallest preferred io size reported by the device.
+
 nomerges (RW)
 -------------
 This enables the user to disable the lookup logic involved with IO
@@ -45,11 +96,24 @@ per-block-cgroup request pool.  IOW, if there are N block cgroups,
 each request queue may have upto N request pools, each independently
 regulated by nr_requests.
 
+optimal_io_size (RO)
+--------------------
+This is the optimal io size reported by the device.
+
+physical_block_size (RO)
+------------------------
+This is the physical block size of device, in bytes.
+
 read_ahead_kb (RW)
 ------------------
 Maximum number of kilobytes to read-ahead for filesystems on this block
 device.
 
+rotational (RW)
+---------------
+This file is used to stat if the device is of rotational type or
+non-rotational type.
+
 rq_affinity (RW)
 ----------------
 If this option is '1', the block layer will migrate request completions to the
index 70cd49b1caa8c07e71b7d0855a9469fc989cb7f6..1dd622546d06b711bf262358b387b4bb9af3f68a 100644 (file)
@@ -10,8 +10,8 @@ Required properties:
 - compatible : Should be "fsl,<chip>-esdhc"
 
 Optional properties:
-- fsl,cd-internal : Indicate to use controller internal card detection
-- fsl,wp-internal : Indicate to use controller internal write protection
+- fsl,cd-controller : Indicate to use controller internal card detection
+- fsl,wp-controller : Indicate to use controller internal write protection
 
 Examples:
 
@@ -19,8 +19,8 @@ esdhc@70004000 {
        compatible = "fsl,imx51-esdhc";
        reg = <0x70004000 0x4000>;
        interrupts = <1>;
-       fsl,cd-internal;
-       fsl,wp-internal;
+       fsl,cd-controller;
+       fsl,wp-controller;
 };
 
 esdhc@70008000 {
index d156e1b5db1233c5ffdb2c0f54e1f5bd6234da34..da80c2ae0915e338af82e995ad64d78fdce82add 100644 (file)
@@ -9,9 +9,9 @@ Required properties:
 - regulators: list of regulators provided by this controller, must have
   property "regulator-compatible" to match their hardware counterparts:
   sm[0-2], ldo[0-9] and ldo_rtc
-- sm0-supply: The input supply for the SM0.
-- sm1-supply: The input supply for the SM1.
-- sm2-supply: The input supply for the SM2.
+- vin-sm0-supply: The input supply for the SM0.
+- vin-sm1-supply: The input supply for the SM1.
+- vin-sm2-supply: The input supply for the SM2.
 - vinldo01-supply: The input supply for the LDO1 and LDO2
 - vinldo23-supply: The input supply for the LDO2 and LDO3
 - vinldo4-supply: The input supply for the LDO4
@@ -30,9 +30,9 @@ Example:
                #gpio-cells = <2>;
                gpio-controller;
 
-               sm0-supply = <&some_reg>;
-               sm1-supply = <&some_reg>;
-               sm2-supply = <&some_reg>;
+               vin-sm0-supply = <&some_reg>;
+               vin-sm1-supply = <&some_reg>;
+               vin-sm2-supply = <&some_reg>;
                vinldo01-supply = <...>;
                vinldo23-supply = <...>;
                vinldo4-supply = <...>;
index 0f103e39b4f6a025cb486cbdfb21126c78992738..e540a24e5d069d4f6372adaabfa792ff11897ca9 100644 (file)
@@ -114,7 +114,6 @@ prototypes:
        int (*drop_inode) (struct inode *);
        void (*evict_inode) (struct inode *);
        void (*put_super) (struct super_block *);
-       void (*write_super) (struct super_block *);
        int (*sync_fs)(struct super_block *sb, int wait);
        int (*freeze_fs) (struct super_block *);
        int (*unfreeze_fs) (struct super_block *);
@@ -136,7 +135,6 @@ write_inode:
 drop_inode:                            !!!inode->i_lock!!!
 evict_inode:
 put_super:             write
-write_super:           read
 sync_fs:               read
 freeze_fs:             write
 unfreeze_fs:           write
index 2bef2b3843d1d4e09ead99fed121de4b2ab92db2..0742feebc6e221f9d79e400adab5feaba23098de 100644 (file)
@@ -94,9 +94,8 @@ protected.
 ---
 [mandatory]
 
-BKL is also moved from around sb operations.  ->write_super() Is now called 
-without BKL held.  BKL should have been shifted into individual fs sb_op
-functions.  If you don't need it, remove it.  
+BKL is also moved from around sb operations. BKL should have been shifted into
+individual fs sb_op functions.  If you don't need it, remove it.
 
 ---
 [informational]
index ead764b2728f8a20731ece907475b1966a35ce86..de1e6c4dccff047766f1bfc1801319ef28cdf0d1 100644 (file)
@@ -137,6 +137,17 @@ errors=panic|continue|remount-ro
                 without doing anything or remount the partition in
                 read-only mode (default behavior).
 
+discard       -- If set, issues discard/TRIM commands to the block
+                device when blocks are freed. This is useful for SSD devices
+                and sparse/thinly-provisoned LUNs.
+
+nfs           -- This option maintains an index (cache) of directory
+                inodes by i_logstart which is used by the nfs-related code to
+                improve look-ups.
+
+                Enable this only if you want to export the FAT filesystem
+                over NFS
+
 <bool>: 0,1,yes,no,true,false
 
 TODO
index 065aa2dc083538dcf05a9e2863e8b14fddb9b514..2ee133e030c3f51521321afd62d5dd3b1d1650fb 100644 (file)
@@ -216,7 +216,6 @@ struct super_operations {
         void (*drop_inode) (struct inode *);
         void (*delete_inode) (struct inode *);
         void (*put_super) (struct super_block *);
-        void (*write_super) (struct super_block *);
         int (*sync_fs)(struct super_block *sb, int wait);
         int (*freeze_fs) (struct super_block *);
         int (*unfreeze_fs) (struct super_block *);
@@ -273,9 +272,6 @@ or bottom half).
   put_super: called when the VFS wishes to free the superblock
        (i.e. unmount). This is called with the superblock lock held
 
-  write_super: called when the VFS superblock needs to be written to
-       disc. This method is optional
-
   sync_fs: called when VFS is writing out all dirty data associated with
        a superblock. The second parameter indicates whether the method
        should wait until the write out has been completed. Optional.
index 0bf25eebce948b4a330fe8868db387e742108278..4ebbfc3f1c6ea803b1cb7b5b71c1e98c6d8e3f17 100644 (file)
@@ -262,9 +262,9 @@ MINIMUM_BATTERY_MINUTES=10
 
 #
 # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
-# exceeded, the kernel will wake pdflush which will then reduce the amount
-# of dirty memory to dirty_background_ratio.  Set this nice and low, so once
-# some writeout has commenced, we do a lot of it.
+# exceeded, the kernel will wake flusher threads which will then reduce the
+# amount of dirty memory to dirty_background_ratio.  Set this nice and low,
+# so once some writeout has commenced, we do a lot of it.
 #
 #DIRTY_BACKGROUND_RATIO=5
 
@@ -384,9 +384,9 @@ CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'}
 
 #
 # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
-# exceeded, the kernel will wake pdflush which will then reduce the amount
-# of dirty memory to dirty_background_ratio.  Set this nice and low, so once
-# some writeout has commenced, we do a lot of it.
+# exceeded, the kernel will wake flusher threads which will then reduce the
+# amount of dirty memory to dirty_background_ratio.  Set this nice and low,
+# so once some writeout has commenced, we do a lot of it.
 #
 DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'}
 
index 8d022073e3ef53933898c6756c3abf6d50104a79..2e9e0ae2cd453dc3ac0a605c1a40baf1096cf42f 100644 (file)
@@ -51,8 +51,23 @@ Built-in netconsole starts immediately after the TCP stack is
 initialized and attempts to bring up the supplied dev at the supplied
 address.
 
-The remote host can run either 'netcat -u -l -p <port>',
-'nc -l -u <port>' or syslogd.
+The remote host has several options to receive the kernel messages,
+for example:
+
+1) syslogd
+
+2) netcat
+
+   On distributions using a BSD-based netcat version (e.g. Fedora,
+   openSUSE and Ubuntu) the listening port must be specified without
+   the -p switch:
+
+   'nc -u -l -p <port>' / 'nc -u -l <port>' or
+   'netcat -u -l -p <port>' / 'netcat -u -l <port>'
+
+3) socat
+
+   'socat udp-recv:<port> -'
 
 Dynamic reconfiguration:
 ========================
index e40f4b4e1977c73d1f6984c705c1065878ad4ad4..1479aca2374441976c14668b7bc7e523fbb2211f 100644 (file)
@@ -840,9 +840,9 @@ static unsigned long i2c_pin_configs[] = {
 
 static struct pinctrl_map __initdata mapping[] = {
        PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "i2c0"),
-       PIN_MAP_MUX_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs),
-       PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs),
-       PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs),
+       PIN_MAP_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs),
+       PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs),
+       PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs),
 };
 
 Finally, some devices expect the mapping table to contain certain specific
index e369de2d48cdf2f24c96a8373b8506d10800f28f..dd908cf64ecfcb7a809685a7eb2beb508cb30815 100644 (file)
@@ -46,14 +46,13 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)
 so that any otherwise allowed process (even those in external pid namespaces)
 may attach.
 
-These restrictions do not change how ptrace via PTRACE_TRACEME operates.
-
-The sysctl settings are:
+The sysctl settings (writable only with CAP_SYS_PTRACE) are:
 
 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other
     process running under the same uid, as long as it is dumpable (i.e.
     did not transition uids, start privileged, or have called
-    prctl(PR_SET_DUMPABLE...) already).
+    prctl(PR_SET_DUMPABLE...) already). Similarly, PTRACE_TRACEME is
+    unchanged.
 
 1 - restricted ptrace: a process must have a predefined relationship
     with the inferior it wants to call PTRACE_ATTACH on. By default,
@@ -61,12 +60,13 @@ The sysctl settings are:
     classic criteria is also met. To change the relationship, an
     inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
     an allowed debugger PID to call PTRACE_ATTACH on the inferior.
+    Using PTRACE_TRACEME is unchanged.
 
 2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace
-    with PTRACE_ATTACH.
+    with PTRACE_ATTACH, or through children calling PTRACE_TRACEME.
 
-3 - no attach: no processes may use ptrace with PTRACE_ATTACH. Once set,
-    this sysctl cannot be changed to a lower value.
+3 - no attach: no processes may use ptrace with PTRACE_ATTACH nor via
+    PTRACE_TRACEME. Once set, this sysctl value cannot be changed.
 
 The original children-only logic was based on the restrictions in grsecurity.
 
index dcc2a94ae34e7d4a976c8fd2f5613236c05968f3..078701fdbd4dd936dd485737abe7b5b60e554604 100644 (file)
@@ -76,8 +76,8 @@ huge pages although processes will also directly compact memory as required.
 
 dirty_background_bytes
 
-Contains the amount of dirty memory at which the pdflush background writeback
-daemon will start writeback.
+Contains the amount of dirty memory at which the background kernel
+flusher threads will start writeback.
 
 Note: dirty_background_bytes is the counterpart of dirty_background_ratio. Only
 one of them may be specified at a time. When one sysctl is written it is
@@ -89,7 +89,7 @@ other appears as 0 when read.
 dirty_background_ratio
 
 Contains, as a percentage of total system memory, the number of pages at which
-the pdflush background writeback daemon will start writing out dirty data.
+the background kernel flusher threads will start writing out dirty data.
 
 ==============================================================
 
@@ -112,9 +112,9 @@ retained.
 dirty_expire_centisecs
 
 This tunable is used to define when dirty data is old enough to be eligible
-for writeout by the pdflush daemons.  It is expressed in 100'ths of a second.
-Data which has been dirty in-memory for longer than this interval will be
-written out next time a pdflush daemon wakes up.
+for writeout by the kernel flusher threads.  It is expressed in 100'ths
+of a second.  Data which has been dirty in-memory for longer than this
+interval will be written out next time a flusher thread wakes up.
 
 ==============================================================
 
@@ -128,7 +128,7 @@ data.
 
 dirty_writeback_centisecs
 
-The pdflush writeback daemons will periodically wake up and write `old' data
+The kernel flusher threads will periodically wake up and write `old' data
 out to disk.  This tunable expresses the interval between those wakeups, in
 100'ths of a second.
 
index f8551b3879f8442350a94b9f88377961ed8e8abd..4ac359b7aa176d1d1b61a100bc196332d842029b 100644 (file)
@@ -299,11 +299,17 @@ map_hugetlb.c.
 *******************************************************************
 
 /*
- * hugepage-shm:  see Documentation/vm/hugepage-shm.c
+ * map_hugetlb: see tools/testing/selftests/vm/map_hugetlb.c
  */
 
 *******************************************************************
 
 /*
- * hugepage-mmap:  see Documentation/vm/hugepage-mmap.c
+ * hugepage-shm:  see tools/testing/selftests/vm/hugepage-shm.c
+ */
+
+*******************************************************************
+
+/*
+ * hugepage-mmap:  see tools/testing/selftests/vm/hugepage-mmap.c
  */
index 0403aaaba878edd18473ef7a536b38cfac4784c5..874a8ca93feb95c9783d9a41b3f89136b7485516 100644 (file)
@@ -3,6 +3,7 @@ Kernel driver w1_therm
 
 Supported chips:
   * Maxim ds18*20 based temperature sensors.
+  * Maxim ds1825 based temperature sensors.
 
 Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
 
@@ -15,6 +16,7 @@ supported family codes:
 W1_THERM_DS18S20       0x10
 W1_THERM_DS1822                0x22
 W1_THERM_DS18B20       0x28
+W1_THERM_DS1825                0x3B
 
 Support is provided through the sysfs w1_slave file.  Each open and
 read sequence will initiate a temperature conversion then provide two
index 73ff5cc93e05db4c93321464cb8ae948571a18fe..3da822967ee0e13d1a2dbcd88d2d75f5a4aca370 100644 (file)
@@ -31,7 +31,7 @@ static void keep_alive(void)
  * or "-e" to enable the card.
  */
 
-void term(int sig)
+static void term(int sig)
 {
     close(fd);
     fprintf(stderr, "Stopping watchdog ticks...\n");
index 94b823f71e944d1f8805815c2b16b5bca437d3b7..fdc0119963e70f12c4f9e1eae3a613447e7d8781 100644 (file)
@@ -827,24 +827,24 @@ F:        arch/arm/mach-pxa/colibri-pxa270-income.c
 
 ARM/INTEL IOP32X ARM ARCHITECTURE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
-M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dan Williams <djbw@fb.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
 ARM/INTEL IOP33X ARM ARCHITECTURE
-M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dan Williams <djbw@fb.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
 ARM/INTEL IOP13XX ARM ARCHITECTURE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
-M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dan Williams <djbw@fb.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
 ARM/INTEL IQ81342EX MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
-M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dan Williams <djbw@fb.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
@@ -869,7 +869,7 @@ F:  drivers/pcmcia/pxa2xx_stargate2.c
 
 ARM/INTEL XSC3 (MANZANO) ARM CORE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
-M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dan Williams <djbw@fb.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
@@ -925,14 +925,14 @@ S:        Maintained
 
 ARM/NOMADIK ARCHITECTURE
 M:     Alessandro Rubini <rubini@unipv.it>
-M:     Linus Walleij <linus.walleij@stericsson.com>
+M:     Linus Walleij <linus.walleij@linaro.org>
 M:     STEricsson <STEricsson_nomadik_linux@list.st.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-nomadik/
 F:     arch/arm/plat-nomadik/
 F:     drivers/i2c/busses/i2c-nomadik.c
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
 
 ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
 M:     Nelson Castillo <arhuaco@freaks-unidos.net>
@@ -1146,7 +1146,7 @@ F:        drivers/usb/host/ehci-w90x900.c
 F:     drivers/video/nuc900fb.c
 
 ARM/U300 MACHINE SUPPORT
-M:     Linus Walleij <linus.walleij@stericsson.com>
+M:     Linus Walleij <linus.walleij@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 F:     arch/arm/mach-u300/
@@ -1161,15 +1161,20 @@ T:      git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
 
 ARM/Ux500 ARM ARCHITECTURE
 M:     Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
-M:     Linus Walleij <linus.walleij@stericsson.com>
+M:     Linus Walleij <linus.walleij@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-ux500/
+F:     drivers/clocksource/clksrc-dbx500-prcmu.c
 F:     drivers/dma/ste_dma40*
+F:     drivers/hwspinlock/u8500_hsem.c
 F:     drivers/mfd/abx500*
 F:     drivers/mfd/ab8500*
-F:     drivers/mfd/stmpe*
+F:     drivers/mfd/dbx500*
+F:     drivers/mfd/db8500*
+F:     drivers/pinctrl/pinctrl-nomadik*
 F:     drivers/rtc/rtc-ab8500.c
+F:     drivers/rtc/rtc-pl031.c
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
 
 ARM/VFP SUPPORT
@@ -1227,9 +1232,9 @@ S:        Maintained
 F:     drivers/hwmon/asb100.c
 
 ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API
-M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dan Williams <djbw@fb.com>
 W:     http://sourceforge.net/projects/xscaleiop
-S:     Supported
+S:     Maintained
 F:     Documentation/crypto/async-tx-api.txt
 F:     crypto/async_tx/
 F:     drivers/dma/
@@ -2212,7 +2217,7 @@ S:        Maintained
 F:     drivers/scsi/tmscsim.*
 
 DC395x SCSI driver
-M:     Oliver Neukum <oliver@neukum.name>
+M:     Oliver Neukum <oliver@neukum.org>
 M:     Ali Akcaagac <aliakc@web.de>
 M:     Jamie Lenehan <lenehan@twibble.org>
 W:     http://twibble.org/dist/dc395x/
@@ -2359,7 +2364,7 @@ T:        git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git
 
 DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
 M:     Vinod Koul <vinod.koul@intel.com>
-M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dan Williams <djbw@fb.com>
 S:     Supported
 F:     drivers/dma/
 F:     include/linux/dma*
@@ -3094,7 +3099,7 @@ F:        include/linux/gigaset_dev.h
 
 GPIO SUBSYSTEM
 M:     Grant Likely <grant.likely@secretlab.ca>
-M:     Linus Walleij <linus.walleij@stericsson.com>
+M:     Linus Walleij <linus.walleij@linaro.org>
 S:     Maintained
 T:     git git://git.secretlab.ca/git/linux-2.6.git
 F:     Documentation/gpio.txt
@@ -3547,7 +3552,6 @@ K:        \b(ABS|SYN)_MT_
 
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:     Intel SCU Linux support <intel-linux-scu@intel.com>
-M:     Dan Williams <dan.j.williams@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
 M:     Ed Nadolski <edmund.nadolski@intel.com>
 L:     linux-scsi@vger.kernel.org
@@ -3590,8 +3594,8 @@ F:        arch/x86/kernel/microcode_core.c
 F:     arch/x86/kernel/microcode_intel.c
 
 INTEL I/OAT DMA DRIVER
-M:     Dan Williams <dan.j.williams@intel.com>
-S:     Supported
+M:     Dan Williams <djbw@fb.com>
+S:     Maintained
 F:     drivers/dma/ioat*
 
 INTEL IOMMU (VT-d)
@@ -3603,8 +3607,8 @@ F:        drivers/iommu/intel-iommu.c
 F:     include/linux/intel-iommu.h
 
 INTEL IOP-ADMA DMA DRIVER
-M:     Dan Williams <dan.j.williams@intel.com>
-S:     Maintained
+M:     Dan Williams <djbw@fb.com>
+S:     Odd fixes
 F:     drivers/dma/iop-adma.c
 
 INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
@@ -4533,7 +4537,7 @@ S:        Supported
 F:     arch/microblaze/
 
 MICROTEK X6 SCANNER
-M:     Oliver Neukum <oliver@neukum.name>
+M:     Oliver Neukum <oliver@neukum.org>
 S:     Maintained
 F:     drivers/usb/image/microtek.*
 
@@ -5329,14 +5333,15 @@ PIN CONTROL SUBSYSTEM
 M:     Linus Walleij <linus.walleij@linaro.org>
 S:     Maintained
 F:     drivers/pinctrl/
+F:     include/linux/pinctrl/
 
 PIN CONTROLLER - ST SPEAR
-M:     Viresh Kumar <viresh.linux@gmail.com>
+M:     Viresh Kumar <viresh.linux@gmail.com>
 L:     spear-devel@list.st.com
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.st.com/spear
 S:     Maintained
-F:     driver/pinctrl/spear/
+F:     drivers/pinctrl/spear/
 
 PKTCDVD DRIVER
 M:     Peter Osterlund <petero2@telia.com>
@@ -7071,7 +7076,7 @@ F:        include/linux/mtd/ubi.h
 F:     include/mtd/ubi-user.h
 
 USB ACM DRIVER
-M:     Oliver Neukum <oliver@neukum.name>
+M:     Oliver Neukum <oliver@neukum.org>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
 F:     Documentation/usb/acm.txt
@@ -7092,7 +7097,7 @@ S:        Supported
 F:     drivers/block/ub.c
 
 USB CDC ETHERNET DRIVER
-M:     Oliver Neukum <oliver@neukum.name>
+M:     Oliver Neukum <oliver@neukum.org>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
 F:     drivers/net/usb/cdc_*.c
@@ -7165,7 +7170,7 @@ F:        drivers/usb/host/isp116x*
 F:     include/linux/usb/isp116x.h
 
 USB KAWASAKI LSI DRIVER
-M:     Oliver Neukum <oliver@neukum.name>
+M:     Oliver Neukum <oliver@neukum.org>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
 F:     drivers/usb/serial/kl5kusb105.*
@@ -7283,6 +7288,12 @@ W:       http://www.connecttech.com
 S:     Supported
 F:     drivers/usb/serial/whiteheat*
 
+USB SMSC75XX ETHERNET DRIVER
+M:     Steve Glendinning <steve.glendinning@shawell.net>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     drivers/net/usb/smsc75xx.*
+
 USB SMSC95XX ETHERNET DRIVER
 M:     Steve Glendinning <steve.glendinning@shawell.net>
 L:     netdev@vger.kernel.org
@@ -7665,23 +7676,28 @@ S:      Supported
 F:     Documentation/hwmon/wm83??
 F:     arch/arm/mach-s3c64xx/mach-crag6410*
 F:     drivers/clk/clk-wm83*.c
+F:     drivers/extcon/extcon-arizona.c
 F:     drivers/leds/leds-wm83*.c
 F:     drivers/gpio/gpio-*wm*.c
+F:     drivers/gpio/gpio-arizona.c
 F:     drivers/hwmon/wm83??-hwmon.c
 F:     drivers/input/misc/wm831x-on.c
 F:     drivers/input/touchscreen/wm831x-ts.c
 F:     drivers/input/touchscreen/wm97*.c
-F:     drivers/mfd/wm8*.c
+F:     drivers/mfd/arizona*
+F:     drivers/mfd/wm*.c
 F:     drivers/power/wm83*.c
 F:     drivers/rtc/rtc-wm83*.c
 F:     drivers/regulator/wm8*.c
 F:     drivers/video/backlight/wm83*_bl.c
 F:     drivers/watchdog/wm83*_wdt.c
+F:     include/linux/mfd/arizona/
 F:     include/linux/mfd/wm831x/
 F:     include/linux/mfd/wm8350/
 F:     include/linux/mfd/wm8400*
 F:     include/linux/wm97xx.h
 F:     include/sound/wm????.h
+F:     sound/soc/codecs/arizona.?
 F:     sound/soc/codecs/wm*
 
 WORKQUEUE
index ddf5be952e456904ba009fbbe0d1c8e0a42470b7..371ce8899f5c758633ed25ffdacef01b45fa6e99 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc4
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
index d5b9b5e645cc7ad6ee66984d78434b306bc1aa13..9944dedee5b1b1b31abf08599a44421333bd9290 100644 (file)
@@ -18,6 +18,8 @@ config ALPHA
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_CMOS_UPDATE
+       select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_STRNLEN_USER
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
index 3bb7ffeae3bc610010bb54a3eaba698c513c0c7d..c2cbe4fc391cd7d77d319cb0cbeabd19f7e5ecbb 100644 (file)
@@ -14,8 +14,8 @@
  */
 
 
-#define ATOMIC_INIT(i)         ( (atomic_t) { (i) } )
-#define ATOMIC64_INIT(i)       ( (atomic64_t) { (i) } )
+#define ATOMIC_INIT(i)         { (i) }
+#define ATOMIC64_INIT(i)       { (i) }
 
 #define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic64_read(v)       (*(volatile long *)&(v)->counter)
index db00f7885faad8949db38886e5ebd798440f63f5..e477bcd5b94aaa3055486564c2ab2d54a5e44934 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef __ASM_ALPHA_FPU_H
 #define __ASM_ALPHA_FPU_H
 
+#ifdef __KERNEL__
 #include <asm/special_insns.h>
+#endif
 
 /*
  * Alpha floating-point control register defines:
index fd698a174f26a9358a2c8e63b663c68bc47a56c1..b87755a1955482f9a46282749ed68755afca4973 100644 (file)
@@ -76,7 +76,10 @@ struct switch_stack {
 #define task_pt_regs(task) \
   ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1)
 
-#define force_successful_syscall_return() (task_pt_regs(current)->r0 = 0)
+#define current_pt_regs() \
+  ((struct pt_regs *) ((char *)current_thread_info() + 2*PAGE_SIZE) - 1)
+
+#define force_successful_syscall_return() (current_pt_regs()->r0 = 0)
 
 #endif
 
index dcb221a4b5be3505686b05fb3060307cde68f29b..7d2f75be932e6d16e4ceba058fe0e0c769a8be32 100644 (file)
 /* Instruct lower device to use last 4-bytes of skb data as FCS */
 #define SO_NOFCS               43
 
+#ifdef __KERNEL__
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
  */
 #define SOCK_NONBLOCK  0x40000000
+#endif /* __KERNEL__ */
 
 #endif /* _ASM_SOCKET_H */
index b49ec2f8d6e3e0220e4009793387c917f1b8e090..766fdfde2b7aa0329cc42681f2fb907b08ce9064 100644 (file)
@@ -433,36 +433,12 @@ clear_user(void __user *to, long len)
 #undef __module_address
 #undef __module_call
 
-/* Returns: -EFAULT if exception before terminator, N if the entire
-   buffer filled, else strlen.  */
+#define user_addr_max() \
+        (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
 
-extern long __strncpy_from_user(char *__to, const char __user *__from, long __to_len);
-
-extern inline long
-strncpy_from_user(char *to, const char __user *from, long n)
-{
-       long ret = -EFAULT;
-       if (__access_ok((unsigned long)from, 0, get_fs()))
-               ret = __strncpy_from_user(to, from, n);
-       return ret;
-}
-
-/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-extern long __strlen_user(const char __user *);
-
-extern inline long strlen_user(const char __user *str)
-{
-       return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0;
-}
-
-/* Returns: 0 if exception before NUL or reaching the supplied limit (N),
- * a value greater than N if the limit would be exceeded, else strlen.  */
-extern long __strnlen_user(const char __user *, long);
-
-extern inline long strnlen_user(const char __user *str, long n)
-{
-       return access_ok(VERIFY_READ,str,0) ? __strnlen_user(str, n) : 0;
-}
+extern long strncpy_from_user(char *dest, const char __user *src, long count);
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
 
 /*
  * About the exception table:
index 633b23b0664ab2a4a075d648d26547dbc911a65d..a31a78eac9b99962cf6b55df76b1066cdcaf7b2b 100644 (file)
 #define __NR_setns                     501
 #define __NR_accept4                   502
 #define __NR_sendmmsg                  503
+#define __NR_process_vm_readv          504
+#define __NR_process_vm_writev         505
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS                    504
+#define NR_SYSCALLS                    506
 
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_STAT64
diff --git a/arch/alpha/include/asm/word-at-a-time.h b/arch/alpha/include/asm/word-at-a-time.h
new file mode 100644 (file)
index 0000000..6b340d0
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef _ASM_WORD_AT_A_TIME_H
+#define _ASM_WORD_AT_A_TIME_H
+
+#include <asm/compiler.h>
+
+/*
+ * word-at-a-time interface for Alpha.
+ */
+
+/*
+ * We do not use the word_at_a_time struct on Alpha, but it needs to be
+ * implemented to humour the generic code.
+ */
+struct word_at_a_time {
+       const unsigned long unused;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { 0 }
+
+/* Return nonzero if val has a zero */
+static inline unsigned long has_zero(unsigned long val, unsigned long *bits, const struct word_at_a_time *c)
+{
+       unsigned long zero_locations = __kernel_cmpbge(0, val);
+       *bits = zero_locations;
+       return zero_locations;
+}
+
+static inline unsigned long prep_zero_mask(unsigned long val, unsigned long bits, const struct word_at_a_time *c)
+{
+       return bits;
+}
+
+#define create_zero_mask(bits) (bits)
+
+static inline unsigned long find_zero(unsigned long bits)
+{
+#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
+       /* Simple if have CIX instructions */
+       return __kernel_cttz(bits);
+#else
+       unsigned long t1, t2, t3;
+       /* Retain lowest set bit only */
+       bits &= -bits;
+       /* Binary search for lowest set bit */
+       t1 = bits & 0xf0;
+       t2 = bits & 0xcc;
+       t3 = bits & 0xaa;
+       if (t1) t1 = 4;
+       if (t2) t2 = 2;
+       if (t3) t3 = 1;
+       return t1 + t2 + t3;
+#endif
+}
+
+#endif /* _ASM_WORD_AT_A_TIME_H */
index d96e742d4dc2c9d139e021ee34aae81eeabdda55..15fa821d09cd38ff58ea5390439617ee2ff4a2eb 100644 (file)
@@ -52,7 +52,6 @@ EXPORT_SYMBOL(alpha_write_fp_reg_s);
 
 /* entry.S */
 EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(kernel_execve);
 
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_tcpudp_magic);
@@ -74,8 +73,6 @@ EXPORT_SYMBOL(alpha_fp_emul);
  */
 EXPORT_SYMBOL(__copy_user);
 EXPORT_SYMBOL(__do_clear_user);
-EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(__strnlen_user);
 
 /* 
  * SMP-specific symbols.
index 6d159cee5f2f43a48bc9aac8355069a3e588ef7f..ec0da0567ab515e6203d2310a9d960be7d4fc0e7 100644 (file)
@@ -663,58 +663,6 @@ kernel_thread:
        br      ret_to_kernel
 .end kernel_thread
 
-/*
- * kernel_execve(path, argv, envp)
- */
-       .align  4
-       .globl  kernel_execve
-       .ent    kernel_execve
-kernel_execve:
-       /* We can be called from a module.  */
-       ldgp    $gp, 0($27)
-       lda     $sp, -(32+SIZEOF_PT_REGS+8)($sp)
-       .frame  $sp, 32+SIZEOF_PT_REGS+8, $26, 0
-       stq     $26, 0($sp)
-       stq     $16, 8($sp)
-       stq     $17, 16($sp)
-       stq     $18, 24($sp)
-       .prologue 1
-
-       lda     $16, 32($sp)
-       lda     $17, 0
-       lda     $18, SIZEOF_PT_REGS
-       bsr     $26, memset             !samegp
-
-       /* Avoid the HAE being gratuitously wrong, which would cause us
-          to do the whole turn off interrupts thing and restore it.  */
-       ldq     $2, alpha_mv+HAE_CACHE
-       stq     $2, 152+32($sp)
-
-       ldq     $16, 8($sp)
-       ldq     $17, 16($sp)
-       ldq     $18, 24($sp)
-       lda     $19, 32($sp)
-       bsr     $26, do_execve          !samegp
-
-       ldq     $26, 0($sp)
-       bne     $0, 1f                  /* error! */
-
-       /* Move the temporary pt_regs struct from its current location
-          to the top of the kernel stack frame.  See copy_thread for
-          details for a normal process.  */
-       lda     $16, 0x4000 - SIZEOF_PT_REGS($8)
-       lda     $17, 32($sp)
-       lda     $18, SIZEOF_PT_REGS
-       bsr     $26, memmove            !samegp
-
-       /* Take that over as our new stack frame and visit userland!  */
-       lda     $sp, 0x4000 - SIZEOF_PT_REGS($8)
-       br      $31, ret_from_sys_call
-
-1:     lda     $sp, 32+SIZEOF_PT_REGS+8($sp)
-       ret
-.end kernel_execve
-
 \f
 /*
  * Special system calls.  Most of these are special in that they either
@@ -796,115 +744,6 @@ sys_rt_sigreturn:
        br      ret_from_sys_call
 .end sys_rt_sigreturn
 
-       .align  4
-       .globl  sys_sethae
-       .ent    sys_sethae
-sys_sethae:
-       .prologue 0
-       stq     $16, 152($sp)
-       ret
-.end sys_sethae
-
-       .align  4
-       .globl  osf_getpriority
-       .ent    osf_getpriority
-osf_getpriority:
-       lda     $sp, -16($sp)
-       stq     $26, 0($sp)
-       .prologue 0
-
-       jsr     $26, sys_getpriority
-
-       ldq     $26, 0($sp)
-       blt     $0, 1f
-
-       /* Return value is the unbiased priority, i.e. 20 - prio.
-          This does result in negative return values, so signal
-          no error by writing into the R0 slot.  */
-       lda     $1, 20
-       stq     $31, 16($sp)
-       subl    $1, $0, $0
-       unop
-
-1:     lda     $sp, 16($sp)
-       ret
-.end osf_getpriority
-
-       .align  4
-       .globl  sys_getxuid
-       .ent    sys_getxuid
-sys_getxuid:
-       .prologue 0
-       ldq     $2, TI_TASK($8)
-       ldq     $3, TASK_CRED($2)
-       ldl     $0, CRED_UID($3)
-       ldl     $1, CRED_EUID($3)
-       stq     $1, 80($sp)
-       ret
-.end sys_getxuid
-
-       .align  4
-       .globl  sys_getxgid
-       .ent    sys_getxgid
-sys_getxgid:
-       .prologue 0
-       ldq     $2, TI_TASK($8)
-       ldq     $3, TASK_CRED($2)
-       ldl     $0, CRED_GID($3)
-       ldl     $1, CRED_EGID($3)
-       stq     $1, 80($sp)
-       ret
-.end sys_getxgid
-
-       .align  4
-       .globl  sys_getxpid
-       .ent    sys_getxpid
-sys_getxpid:
-       .prologue 0
-       ldq     $2, TI_TASK($8)
-
-       /* See linux/kernel/timer.c sys_getppid for discussion
-          about this loop.  */
-       ldq     $3, TASK_GROUP_LEADER($2)
-       ldq     $4, TASK_REAL_PARENT($3)
-       ldl     $0, TASK_TGID($2)
-1:     ldl     $1, TASK_TGID($4)
-#ifdef CONFIG_SMP
-       mov     $4, $5
-       mb
-       ldq     $3, TASK_GROUP_LEADER($2)
-       ldq     $4, TASK_REAL_PARENT($3)
-       cmpeq   $4, $5, $5
-       beq     $5, 1b
-#endif
-       stq     $1, 80($sp)
-       ret
-.end sys_getxpid
-
-       .align  4
-       .globl  sys_alpha_pipe
-       .ent    sys_alpha_pipe
-sys_alpha_pipe:
-       lda     $sp, -16($sp)
-       stq     $26, 0($sp)
-       .prologue 0
-
-       mov     $31, $17
-       lda     $16, 8($sp)
-       jsr     $26, do_pipe_flags
-
-       ldq     $26, 0($sp)
-       bne     $0, 1f
-
-       /* The return values are in $0 and $20.  */
-       ldl     $1, 12($sp)
-       ldl     $0, 8($sp)
-
-       stq     $1, 80+16($sp)
-1:     lda     $sp, 16($sp)
-       ret
-.end sys_alpha_pipe
-
        .align  4
        .globl  sys_execve
        .ent    sys_execve
index 98a103621af6c24e04c219b318281d412ce5018d..bc1acdda7a5ed8ab3945b72559c09a9e763ec030 100644 (file)
@@ -1404,3 +1404,52 @@ SYSCALL_DEFINE3(osf_writev, unsigned long, fd,
 }
 
 #endif
+
+SYSCALL_DEFINE2(osf_getpriority, int, which, int, who)
+{
+       int prio = sys_getpriority(which, who);
+       if (prio >= 0) {
+               /* Return value is the unbiased priority, i.e. 20 - prio.
+                  This does result in negative return values, so signal
+                  no error */
+               force_successful_syscall_return();
+               prio = 20 - prio;
+       }
+       return prio;
+}
+
+SYSCALL_DEFINE0(getxuid)
+{
+       current_pt_regs()->r20 = sys_geteuid();
+       return sys_getuid();
+}
+
+SYSCALL_DEFINE0(getxgid)
+{
+       current_pt_regs()->r20 = sys_getegid();
+       return sys_getgid();
+}
+
+SYSCALL_DEFINE0(getxpid)
+{
+       current_pt_regs()->r20 = sys_getppid();
+       return sys_getpid();
+}
+
+SYSCALL_DEFINE0(alpha_pipe)
+{
+       int fd[2];
+       int res = do_pipe_flags(fd, 0);
+       if (!res) {
+               /* The return values are in $0 and $20.  */
+               current_pt_regs()->r20 = fd[1];
+               res = fd[0];
+       }
+       return res;
+}
+
+SYSCALL_DEFINE1(sethae, unsigned long, val)
+{
+       current_pt_regs()->hae = val;
+       return 0;
+}
index 153d3fce3e8e9b4adc84c64fe63483d815a1ec59..d6fde98b74b38bf87aac592c2b9697c1bc925558 100644 (file)
@@ -455,3 +455,22 @@ get_wchan(struct task_struct *p)
        }
        return pc;
 }
+
+int kernel_execve(const char *path, const char *const argv[], const char *const envp[])
+{
+       /* Avoid the HAE being gratuitously wrong, which would cause us
+          to do the whole turn off interrupts thing and restore it.  */
+       struct pt_regs regs = {.hae = alpha_mv.hae_cache};
+       int err = do_execve(path, argv, envp, &regs);
+       if (!err) {
+               struct pt_regs *p = current_pt_regs();
+               /* copy regs to normal position and off to userland we go... */
+               *p = regs;
+               __asm__ __volatile__ (
+                       "mov    %0, $sp;"
+                       "br     $31, ret_from_sys_call"
+                       : : "r"(p));
+       }
+       return err;
+}
+EXPORT_SYMBOL(kernel_execve);
index 87835235f114bd3d6619c8985833046b368eea96..2ac6b45c3e0005d542a084bfabcc652b4747f75e 100644 (file)
@@ -111,7 +111,7 @@ sys_call_table:
        .quad sys_socket
        .quad sys_connect
        .quad sys_accept
-       .quad osf_getpriority                   /* 100 */
+       .quad sys_osf_getpriority                       /* 100 */
        .quad sys_send
        .quad sys_recv
        .quad sys_sigreturn
@@ -522,6 +522,8 @@ sys_call_table:
        .quad sys_setns
        .quad sys_accept4
        .quad sys_sendmmsg
+       .quad sys_process_vm_readv
+       .quad sys_process_vm_writev             /* 505 */
 
        .size sys_call_table, . - sys_call_table
        .type sys_call_table, @object
index c0a83ab62b785f332d817b9f5b0036545295b640..59660743237cc489b4e4eef405e92ab66f7b25e8 100644 (file)
@@ -31,8 +31,6 @@ lib-y =       __divqu.o __remqu.o __divlu.o __remlu.o \
        $(ev6-y)memchr.o \
        $(ev6-y)copy_user.o \
        $(ev6-y)clear_user.o \
-       $(ev6-y)strncpy_from_user.o \
-       $(ev67-y)strlen_user.o \
        $(ev6-y)csum_ipv6_magic.o \
        $(ev6-y)clear_page.o \
        $(ev6-y)copy_page.o \
diff --git a/arch/alpha/lib/ev6-strncpy_from_user.S b/arch/alpha/lib/ev6-strncpy_from_user.S
deleted file mode 100644 (file)
index d2e2817..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * arch/alpha/lib/ev6-strncpy_from_user.S
- * 21264 version contributed by Rick Gorton <rick.gorton@alpha-processor.com>
- *
- * Just like strncpy except in the return value:
- *
- * -EFAULT       if an exception occurs before the terminator is copied.
- * N             if the buffer filled.
- *
- * Otherwise the length of the string is returned.
- *
- * Much of the information about 21264 scheduling/coding comes from:
- *     Compiler Writer's Guide for the Alpha 21264
- *     abbreviated as 'CWG' in other comments here
- *     ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html
- * Scheduling notation:
- *     E       - either cluster
- *     U       - upper subcluster; U0 - subcluster U0; U1 - subcluster U1
- *     L       - lower subcluster; L0 - subcluster L0; L1 - subcluster L1
- * A bunch of instructions got moved and temp registers were changed
- * to aid in scheduling.  Control flow was also re-arranged to eliminate
- * branches, and to provide longer code sequences to enable better scheduling.
- * A total rewrite (using byte load/stores for start & tail sequences)
- * is desirable, but very difficult to do without a from-scratch rewrite.
- * Save that for the future.
- */
-
-
-#include <asm/errno.h>
-#include <asm/regdef.h>
-
-
-/* Allow an exception for an insn; exit if we get one.  */
-#define EX(x,y...)                     \
-       99: x,##y;                      \
-       .section __ex_table,"a";        \
-       .long 99b - .;                  \
-       lda $31, $exception-99b($0);    \
-       .previous
-
-
-       .set noat
-       .set noreorder
-       .text
-
-       .globl __strncpy_from_user
-       .ent __strncpy_from_user
-       .frame $30, 0, $26
-       .prologue 0
-
-       .align 4
-__strncpy_from_user:
-       and     a0, 7, t3       # E : find dest misalignment
-       beq     a2, $zerolength # U :
-
-       /* Are source and destination co-aligned?  */
-       mov     a0, v0          # E : save the string start
-       xor     a0, a1, t4      # E :
-       EX( ldq_u t1, 0(a1) )   # L : Latency=3 load first quadword
-       ldq_u   t0, 0(a0)       # L : load first (partial) aligned dest quadword
-
-       addq    a2, t3, a2      # E : bias count by dest misalignment
-       subq    a2, 1, a3       # E :
-       addq    zero, 1, t10    # E :
-       and     t4, 7, t4       # E : misalignment between the two
-
-       and     a3, 7, t6       # E : number of tail bytes
-       sll     t10, t6, t10    # E : t10 = bitmask of last count byte
-       bne     t4, $unaligned  # U :
-       lda     t2, -1          # E : build a mask against false zero
-
-       /*
-        * We are co-aligned; take care of a partial first word.
-        * On entry to this basic block:
-        * t0 == the first destination word for masking back in
-        * t1 == the first source word.
-        */
-
-       srl     a3, 3, a2       # E : a2 = loop counter = (count - 1)/8
-       addq    a1, 8, a1       # E :
-       mskqh   t2, a1, t2      # U :   detection in the src word
-       nop
-
-       /* Create the 1st output word and detect 0's in the 1st input word.  */
-       mskqh   t1, a1, t3      # U :
-       mskql   t0, a1, t0      # U : assemble the first output word
-       ornot   t1, t2, t2      # E :
-       nop
-
-       cmpbge  zero, t2, t8    # E : bits set iff null found
-       or      t0, t3, t0      # E :
-       beq     a2, $a_eoc      # U :
-       bne     t8, $a_eos      # U : 2nd branch in a quad.  Bad.
-
-       /* On entry to this basic block:
-        * t0 == a source quad not containing a null.
-        * a0 - current aligned destination address
-        * a1 - current aligned source address
-        * a2 - count of quadwords to move.
-        * NOTE: Loop improvement - unrolling this is going to be
-        *      a huge win, since we're going to stall otherwise.
-        *      Fix this later.  For _really_ large copies, look
-        *      at using wh64 on a look-ahead basis.  See the code
-        *      in clear_user.S and copy_user.S.
-        * Presumably, since (a0) and (a1) do not overlap (by C definition)
-        * Lots of nops here:
-        *      - Separate loads from stores
-        *      - Keep it to 1 branch/quadpack so the branch predictor
-        *        can train.
-        */
-$a_loop:
-       stq_u   t0, 0(a0)       # L :
-       addq    a0, 8, a0       # E :
-       nop
-       subq    a2, 1, a2       # E :
-
-       EX( ldq_u t0, 0(a1) )   # L :
-       addq    a1, 8, a1       # E :
-       cmpbge  zero, t0, t8    # E : Stall 2 cycles on t0
-       beq     a2, $a_eoc      # U :
-
-       beq     t8, $a_loop     # U :
-       nop
-       nop
-       nop
-
-       /* Take care of the final (partial) word store.  At this point
-        * the end-of-count bit is set in t8 iff it applies.
-        *
-        * On entry to this basic block we have:
-        * t0 == the source word containing the null
-        * t8 == the cmpbge mask that found it.
-        */
-$a_eos:
-       negq    t8, t12         # E : find low bit set
-       and     t8, t12, t12    # E : 
-
-       /* We're doing a partial word store and so need to combine
-          our source and original destination words.  */
-       ldq_u   t1, 0(a0)       # L :
-       subq    t12, 1, t6      # E :
-
-       or      t12, t6, t8     # E :
-       zapnot  t0, t8, t0      # U : clear src bytes > null
-       zap     t1, t8, t1      # U : clear dst bytes <= null
-       or      t0, t1, t0      # E :
-
-       stq_u   t0, 0(a0)       # L :
-       br      $finish_up      # L0 :
-       nop
-       nop
-
-       /* Add the end-of-count bit to the eos detection bitmask.  */
-       .align 4
-$a_eoc:
-       or      t10, t8, t8
-       br      $a_eos
-       nop
-       nop
-
-
-/* The source and destination are not co-aligned.  Align the destination
-   and cope.  We have to be very careful about not reading too much and
-   causing a SEGV.  */
-
-       .align 4
-$u_head:
-       /* We know just enough now to be able to assemble the first
-          full source word.  We can still find a zero at the end of it
-          that prevents us from outputting the whole thing.
-
-          On entry to this basic block:
-          t0 == the first dest word, unmasked
-          t1 == the shifted low bits of the first source word
-          t6 == bytemask that is -1 in dest word bytes */
-
-       EX( ldq_u t2, 8(a1) )   # L : load second src word
-       addq    a1, 8, a1       # E :
-       mskql   t0, a0, t0      # U : mask trailing garbage in dst
-       extqh   t2, a1, t4      # U :
-
-       or      t1, t4, t1      # E : first aligned src word complete
-       mskqh   t1, a0, t1      # U : mask leading garbage in src
-       or      t0, t1, t0      # E : first output word complete
-       or      t0, t6, t6      # E : mask original data for zero test
-
-       cmpbge  zero, t6, t8    # E :
-       beq     a2, $u_eocfin   # U :
-       bne     t8, $u_final    # U : bad news - 2nd branch in a quad
-       lda     t6, -1          # E : mask out the bits we have
-
-       mskql   t6, a1, t6      # U :   already seen
-       stq_u   t0, 0(a0)       # L : store first output word
-       or      t6, t2, t2      # E :
-       cmpbge  zero, t2, t8    # E : find nulls in second partial
-
-       addq    a0, 8, a0               # E :
-       subq    a2, 1, a2               # E :
-       bne     t8, $u_late_head_exit   # U :
-       nop
-
-       /* Finally, we've got all the stupid leading edge cases taken care
-          of and we can set up to enter the main loop.  */
-
-       extql   t2, a1, t1      # U : position hi-bits of lo word
-       EX( ldq_u t2, 8(a1) )   # L : read next high-order source word
-       addq    a1, 8, a1       # E :
-       cmpbge  zero, t2, t8    # E :
-
-       beq     a2, $u_eoc      # U :
-       bne     t8, $u_eos      # U :
-       nop
-       nop
-
-       /* Unaligned copy main loop.  In order to avoid reading too much,
-          the loop is structured to detect zeros in aligned source words.
-          This has, unfortunately, effectively pulled half of a loop
-          iteration out into the head and half into the tail, but it does
-          prevent nastiness from accumulating in the very thing we want
-          to run as fast as possible.
-
-          On entry to this basic block:
-          t1 == the shifted high-order bits from the previous source word
-          t2 == the unshifted current source word
-
-          We further know that t2 does not contain a null terminator.  */
-
-       /*
-        * Extra nops here:
-        *      separate load quads from store quads
-        *      only one branch/quad to permit predictor training
-        */
-
-       .align 4
-$u_loop:
-       extqh   t2, a1, t0      # U : extract high bits for current word
-       addq    a1, 8, a1       # E :
-       extql   t2, a1, t3      # U : extract low bits for next time
-       addq    a0, 8, a0       # E :
-
-       or      t0, t1, t0      # E : current dst word now complete
-       EX( ldq_u t2, 0(a1) )   # L : load high word for next time
-       subq    a2, 1, a2       # E :
-       nop
-
-       stq_u   t0, -8(a0)      # L : save the current word
-       mov     t3, t1          # E :
-       cmpbge  zero, t2, t8    # E : test new word for eos
-       beq     a2, $u_eoc      # U :
-
-       beq     t8, $u_loop     # U :
-       nop
-       nop
-       nop
-
-       /* We've found a zero somewhere in the source word we just read.
-          If it resides in the lower half, we have one (probably partial)
-          word to write out, and if it resides in the upper half, we
-          have one full and one partial word left to write out.
-
-          On entry to this basic block:
-          t1 == the shifted high-order bits from the previous source word
-          t2 == the unshifted current source word.  */
-       .align 4
-$u_eos:
-       extqh   t2, a1, t0      # U :
-       or      t0, t1, t0      # E : first (partial) source word complete
-       cmpbge  zero, t0, t8    # E : is the null in this first bit?
-       nop
-
-       bne     t8, $u_final    # U :
-       stq_u   t0, 0(a0)       # L : the null was in the high-order bits
-       addq    a0, 8, a0       # E :
-       subq    a2, 1, a2       # E :
-
-       .align 4
-$u_late_head_exit:
-       extql   t2, a1, t0      # U :
-       cmpbge  zero, t0, t8    # E :
-       or      t8, t10, t6     # E :
-       cmoveq  a2, t6, t8      # E :
-
-       /* Take care of a final (probably partial) result word.
-          On entry to this basic block:
-          t0 == assembled source word
-          t8 == cmpbge mask that found the null.  */
-       .align 4
-$u_final:
-       negq    t8, t6          # E : isolate low bit set
-       and     t6, t8, t12     # E :
-       ldq_u   t1, 0(a0)       # L :
-       subq    t12, 1, t6      # E :
-
-       or      t6, t12, t8     # E :
-       zapnot  t0, t8, t0      # U : kill source bytes > null
-       zap     t1, t8, t1      # U : kill dest bytes <= null
-       or      t0, t1, t0      # E :
-
-       stq_u   t0, 0(a0)       # E :
-       br      $finish_up      # U :
-       nop
-       nop
-
-       .align 4
-$u_eoc:                                # end-of-count
-       extqh   t2, a1, t0      # U :
-       or      t0, t1, t0      # E :
-       cmpbge  zero, t0, t8    # E :
-       nop
-
-       .align 4
-$u_eocfin:                     # end-of-count, final word
-       or      t10, t8, t8     # E :
-       br      $u_final        # U :
-       nop
-       nop
-
-       /* Unaligned copy entry point.  */
-       .align 4
-$unaligned:
-
-       srl     a3, 3, a2       # U : a2 = loop counter = (count - 1)/8
-       and     a0, 7, t4       # E : find dest misalignment
-       and     a1, 7, t5       # E : find src misalignment
-       mov     zero, t0        # E :
-
-       /* Conditionally load the first destination word and a bytemask
-          with 0xff indicating that the destination byte is sacrosanct.  */
-
-       mov     zero, t6        # E :
-       beq     t4, 1f          # U :
-       ldq_u   t0, 0(a0)       # L :
-       lda     t6, -1          # E :
-
-       mskql   t6, a0, t6      # E :
-       nop
-       nop
-       nop
-
-       .align 4
-1:
-       subq    a1, t4, a1      # E : sub dest misalignment from src addr
-       /* If source misalignment is larger than dest misalignment, we need
-          extra startup checks to avoid SEGV.  */
-       cmplt   t4, t5, t12     # E :
-       extql   t1, a1, t1      # U : shift src into place
-       lda     t2, -1          # E : for creating masks later
-
-       beq     t12, $u_head    # U :
-       mskqh   t2, t5, t2      # U : begin src byte validity mask
-       cmpbge  zero, t1, t8    # E : is there a zero?
-       nop
-
-       extql   t2, a1, t2      # U :
-       or      t8, t10, t5     # E : test for end-of-count too
-       cmpbge  zero, t2, t3    # E :
-       cmoveq  a2, t5, t8      # E : Latency=2, extra map slot
-
-       nop                     # E : goes with cmov
-       andnot  t8, t3, t8      # E :
-       beq     t8, $u_head     # U :
-       nop
-
-       /* At this point we've found a zero in the first partial word of
-          the source.  We need to isolate the valid source data and mask
-          it into the original destination data.  (Incidentally, we know
-          that we'll need at least one byte of that original dest word.) */
-
-       ldq_u   t0, 0(a0)       # L :
-       negq    t8, t6          # E : build bitmask of bytes <= zero
-       mskqh   t1, t4, t1      # U :
-       and     t6, t8, t12     # E :
-
-       subq    t12, 1, t6      # E :
-       or      t6, t12, t8     # E :
-       zapnot  t2, t8, t2      # U : prepare source word; mirror changes
-       zapnot  t1, t8, t1      # U : to source validity mask
-
-       andnot  t0, t2, t0      # E : zero place for source to reside
-       or      t0, t1, t0      # E : and put it there
-       stq_u   t0, 0(a0)       # L :
-       nop
-
-       .align 4
-$finish_up:
-       zapnot  t0, t12, t4     # U : was last byte written null?
-       and     t12, 0xf0, t3   # E : binary search for the address of the
-       cmovne  t4, 1, t4       # E : Latency=2, extra map slot
-       nop                     # E : with cmovne
-
-       and     t12, 0xcc, t2   # E : last byte written
-       and     t12, 0xaa, t1   # E :
-       cmovne  t3, 4, t3       # E : Latency=2, extra map slot
-       nop                     # E : with cmovne
-
-       bic     a0, 7, t0
-       cmovne  t2, 2, t2       # E : Latency=2, extra map slot
-       nop                     # E : with cmovne
-       nop
-
-       cmovne  t1, 1, t1       # E : Latency=2, extra map slot
-       nop                     # E : with cmovne
-       addq    t0, t3, t0      # E :
-       addq    t1, t2, t1      # E :
-
-       addq    t0, t1, t0      # E :
-       addq    t0, t4, t0      # add one if we filled the buffer
-       subq    t0, v0, v0      # find string length
-       ret                     # L0 :
-
-       .align 4
-$zerolength:
-       nop
-       nop
-       nop
-       clr     v0
-
-$exception:
-       nop
-       nop
-       nop
-       ret
-
-       .end __strncpy_from_user
diff --git a/arch/alpha/lib/ev67-strlen_user.S b/arch/alpha/lib/ev67-strlen_user.S
deleted file mode 100644 (file)
index 57e0d77..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * arch/alpha/lib/ev67-strlen_user.S
- * 21264 version contributed by Rick Gorton <rick.gorton@api-networks.com>
- *
- * Return the length of the string including the NULL terminator
- * (strlen+1) or zero if an error occurred.
- *
- * In places where it is critical to limit the processing time,
- * and the data is not trusted, strnlen_user() should be used.
- * It will return a value greater than its second argument if
- * that limit would be exceeded. This implementation is allowed
- * to access memory beyond the limit, but will not cross a page
- * boundary when doing so.
- *
- * Much of the information about 21264 scheduling/coding comes from:
- *      Compiler Writer's Guide for the Alpha 21264
- *      abbreviated as 'CWG' in other comments here
- *      ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html
- * Scheduling notation:
- *      E       - either cluster
- *      U       - upper subcluster; U0 - subcluster U0; U1 - subcluster U1
- *      L       - lower subcluster; L0 - subcluster L0; L1 - subcluster L1
- * Try not to change the actual algorithm if possible for consistency.
- */
-
-#include <asm/regdef.h>
-
-
-/* Allow an exception for an insn; exit if we get one.  */
-#define EX(x,y...)                     \
-       99: x,##y;                      \
-       .section __ex_table,"a";        \
-       .long 99b - .;                  \
-       lda v0, $exception-99b(zero);   \
-       .previous
-
-
-       .set noreorder
-       .set noat
-       .text
-
-       .globl __strlen_user
-       .ent __strlen_user
-       .frame sp, 0, ra
-
-       .align 4
-__strlen_user:
-       ldah    a1, 32767(zero) # do not use plain strlen_user() for strings
-                               # that might be almost 2 GB long; you should
-                               # be using strnlen_user() instead
-       nop
-       nop
-       nop
-
-       .globl __strnlen_user
-
-       .align 4
-__strnlen_user:
-       .prologue 0
-       EX( ldq_u t0, 0(a0) )   # L : load first quadword (a0 may be misaligned)
-       lda     t1, -1(zero)    # E :
-
-       insqh   t1, a0, t1      # U :
-       andnot  a0, 7, v0       # E :
-       or      t1, t0, t0      # E :
-       subq    a0, 1, a0       # E : get our +1 for the return 
-
-       cmpbge  zero, t0, t1    # E : t1 <- bitmask: bit i == 1 <==> i-th byte == 0
-       subq    a1, 7, t2       # E :
-       subq    a0, v0, t0      # E :
-       bne     t1, $found      # U :
-
-       addq    t2, t0, t2      # E :
-       addq    a1, 1, a1       # E :
-       nop                     # E :
-       nop                     # E :
-
-       .align 4
-$loop: ble     t2, $limit      # U :
-       EX( ldq t0, 8(v0) )     # L :
-       nop                     # E :
-       nop                     # E :
-
-       cmpbge  zero, t0, t1    # E :
-       subq    t2, 8, t2       # E :
-       addq    v0, 8, v0       # E : addr += 8
-       beq     t1, $loop       # U :
-
-$found: cttz   t1, t2          # U0 :
-       addq    v0, t2, v0      # E :
-       subq    v0, a0, v0      # E :
-       ret                     # L0 :
-
-$exception:
-       nop
-       nop
-       nop
-       ret
-
-       .align 4                # currently redundant
-$limit:
-       nop
-       nop
-       subq    a1, t2, v0
-       ret
-
-       .end __strlen_user
diff --git a/arch/alpha/lib/strlen_user.S b/arch/alpha/lib/strlen_user.S
deleted file mode 100644 (file)
index 508a18e..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * arch/alpha/lib/strlen_user.S
- *
- * Return the length of the string including the NUL terminator
- * (strlen+1) or zero if an error occurred.
- *
- * In places where it is critical to limit the processing time,
- * and the data is not trusted, strnlen_user() should be used.
- * It will return a value greater than its second argument if
- * that limit would be exceeded. This implementation is allowed
- * to access memory beyond the limit, but will not cross a page
- * boundary when doing so.
- */
-
-#include <asm/regdef.h>
-
-
-/* Allow an exception for an insn; exit if we get one.  */
-#define EX(x,y...)                     \
-       99: x,##y;                      \
-       .section __ex_table,"a";        \
-       .long 99b - .;                  \
-       lda v0, $exception-99b(zero);   \
-       .previous
-
-
-       .set noreorder
-       .set noat
-       .text
-
-       .globl __strlen_user
-       .ent __strlen_user
-       .frame sp, 0, ra
-
-       .align 3
-__strlen_user:
-       ldah    a1, 32767(zero) # do not use plain strlen_user() for strings
-                               # that might be almost 2 GB long; you should
-                               # be using strnlen_user() instead
-
-       .globl __strnlen_user
-
-       .align 3
-__strnlen_user:
-       .prologue 0
-
-       EX( ldq_u t0, 0(a0) )   # load first quadword (a0 may be misaligned)
-       lda     t1, -1(zero)
-       insqh   t1, a0, t1
-       andnot  a0, 7, v0
-       or      t1, t0, t0
-       subq    a0, 1, a0       # get our +1 for the return 
-       cmpbge  zero, t0, t1    # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
-       subq    a1, 7, t2
-       subq    a0, v0, t0
-       bne     t1, $found
-
-       addq    t2, t0, t2
-       addq    a1, 1, a1
-
-       .align 3
-$loop: ble     t2, $limit
-       EX( ldq t0, 8(v0) )
-       subq    t2, 8, t2
-       addq    v0, 8, v0       # addr += 8
-       cmpbge  zero, t0, t1
-       beq     t1, $loop
-
-$found:        negq    t1, t2          # clear all but least set bit
-       and     t1, t2, t1
-
-       and     t1, 0xf0, t2    # binary search for that set bit
-       and     t1, 0xcc, t3
-       and     t1, 0xaa, t4
-       cmovne  t2, 4, t2
-       cmovne  t3, 2, t3
-       cmovne  t4, 1, t4
-       addq    t2, t3, t2
-       addq    v0, t4, v0
-       addq    v0, t2, v0
-       nop                     # dual issue next two on ev4 and ev5
-       subq    v0, a0, v0
-$exception:
-       ret
-
-       .align 3                # currently redundant
-$limit:
-       subq    a1, t2, v0
-       ret
-
-       .end __strlen_user
diff --git a/arch/alpha/lib/strncpy_from_user.S b/arch/alpha/lib/strncpy_from_user.S
deleted file mode 100644 (file)
index 73ee211..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * arch/alpha/lib/strncpy_from_user.S
- * Contributed by Richard Henderson (rth@tamu.edu)
- *
- * Just like strncpy except in the return value:
- *
- * -EFAULT       if an exception occurs before the terminator is copied.
- * N             if the buffer filled.
- *
- * Otherwise the length of the string is returned.
- */
-
-
-#include <asm/errno.h>
-#include <asm/regdef.h>
-
-
-/* Allow an exception for an insn; exit if we get one.  */
-#define EX(x,y...)                     \
-       99: x,##y;                      \
-       .section __ex_table,"a";        \
-       .long 99b - .;                  \
-       lda $31, $exception-99b($0);    \
-       .previous
-
-
-       .set noat
-       .set noreorder
-       .text
-
-       .globl __strncpy_from_user
-       .ent __strncpy_from_user
-       .frame $30, 0, $26
-       .prologue 0
-
-       .align 3
-$aligned:
-       /* On entry to this basic block:
-          t0 == the first destination word for masking back in
-          t1 == the first source word.  */
-
-       /* Create the 1st output word and detect 0's in the 1st input word.  */
-       lda     t2, -1          # e1    : build a mask against false zero
-       mskqh   t2, a1, t2      # e0    :   detection in the src word
-       mskqh   t1, a1, t3      # e0    :
-       ornot   t1, t2, t2      # .. e1 :
-       mskql   t0, a1, t0      # e0    : assemble the first output word
-       cmpbge  zero, t2, t8    # .. e1 : bits set iff null found
-       or      t0, t3, t0      # e0    :
-       beq     a2, $a_eoc      # .. e1 :
-       bne     t8, $a_eos      # .. e1 :
-
-       /* On entry to this basic block:
-          t0 == a source word not containing a null.  */
-
-$a_loop:
-       stq_u   t0, 0(a0)       # e0    :
-       addq    a0, 8, a0       # .. e1 :
-       EX( ldq_u t0, 0(a1) )   # e0    :
-       addq    a1, 8, a1       # .. e1 :
-       subq    a2, 1, a2       # e0    :
-       cmpbge  zero, t0, t8    # .. e1 (stall)
-       beq     a2, $a_eoc      # e1    :
-       beq     t8, $a_loop     # e1    :
-
-       /* Take care of the final (partial) word store.  At this point
-          the end-of-count bit is set in t8 iff it applies.
-
-          On entry to this basic block we have:
-          t0 == the source word containing the null
-          t8 == the cmpbge mask that found it.  */
-
-$a_eos:
-       negq    t8, t12         # e0    : find low bit set
-       and     t8, t12, t12    # e1 (stall)
-
-       /* For the sake of the cache, don't read a destination word
-          if we're not going to need it.  */
-       and     t12, 0x80, t6   # e0    :
-       bne     t6, 1f          # .. e1 (zdb)
-
-       /* We're doing a partial word store and so need to combine
-          our source and original destination words.  */
-       ldq_u   t1, 0(a0)       # e0    :
-       subq    t12, 1, t6      # .. e1 :
-       or      t12, t6, t8     # e0    :
-       unop                    #
-       zapnot  t0, t8, t0      # e0    : clear src bytes > null
-       zap     t1, t8, t1      # .. e1 : clear dst bytes <= null
-       or      t0, t1, t0      # e1    :
-
-1:     stq_u   t0, 0(a0)
-       br      $finish_up
-
-       /* Add the end-of-count bit to the eos detection bitmask.  */
-$a_eoc:
-       or      t10, t8, t8
-       br      $a_eos
-
-       /*** The Function Entry Point ***/
-       .align 3
-__strncpy_from_user:
-       mov     a0, v0          # save the string start
-       beq     a2, $zerolength
-
-       /* Are source and destination co-aligned?  */
-       xor     a0, a1, t1      # e0    :
-       and     a0, 7, t0       # .. e1 : find dest misalignment
-       and     t1, 7, t1       # e0    :
-       addq    a2, t0, a2      # .. e1 : bias count by dest misalignment
-       subq    a2, 1, a2       # e0    :
-       and     a2, 7, t2       # e1    :
-       srl     a2, 3, a2       # e0    : a2 = loop counter = (count - 1)/8
-       addq    zero, 1, t10    # .. e1 :
-       sll     t10, t2, t10    # e0    : t10 = bitmask of last count byte
-       bne     t1, $unaligned  # .. e1 :
-
-       /* We are co-aligned; take care of a partial first word.  */
-
-       EX( ldq_u t1, 0(a1) )   # e0    : load first src word
-       addq    a1, 8, a1       # .. e1 :
-
-       beq     t0, $aligned    # avoid loading dest word if not needed
-       ldq_u   t0, 0(a0)       # e0    :
-       br      $aligned        # .. e1 :
-
-
-/* The source and destination are not co-aligned.  Align the destination
-   and cope.  We have to be very careful about not reading too much and
-   causing a SEGV.  */
-
-       .align 3
-$u_head:
-       /* We know just enough now to be able to assemble the first
-          full source word.  We can still find a zero at the end of it
-          that prevents us from outputting the whole thing.
-
-          On entry to this basic block:
-          t0 == the first dest word, unmasked
-          t1 == the shifted low bits of the first source word
-          t6 == bytemask that is -1 in dest word bytes */
-
-       EX( ldq_u t2, 8(a1) )   # e0    : load second src word
-       addq    a1, 8, a1       # .. e1 :
-       mskql   t0, a0, t0      # e0    : mask trailing garbage in dst
-       extqh   t2, a1, t4      # e0    :
-       or      t1, t4, t1      # e1    : first aligned src word complete
-       mskqh   t1, a0, t1      # e0    : mask leading garbage in src
-       or      t0, t1, t0      # e0    : first output word complete
-       or      t0, t6, t6      # e1    : mask original data for zero test
-       cmpbge  zero, t6, t8    # e0    :
-       beq     a2, $u_eocfin   # .. e1 :
-       bne     t8, $u_final    # e1    :
-
-       lda     t6, -1                  # e1    : mask out the bits we have
-       mskql   t6, a1, t6              # e0    :   already seen
-       stq_u   t0, 0(a0)               # e0    : store first output word
-       or      t6, t2, t2              # .. e1 :
-       cmpbge  zero, t2, t8            # e0    : find nulls in second partial
-       addq    a0, 8, a0               # .. e1 :
-       subq    a2, 1, a2               # e0    :
-       bne     t8, $u_late_head_exit   # .. e1 :
-
-       /* Finally, we've got all the stupid leading edge cases taken care
-          of and we can set up to enter the main loop.  */
-
-       extql   t2, a1, t1      # e0    : position hi-bits of lo word
-       EX( ldq_u t2, 8(a1) )   # .. e1 : read next high-order source word
-       addq    a1, 8, a1       # e0    :
-       cmpbge  zero, t2, t8    # e1 (stall)
-       beq     a2, $u_eoc      # e1    :
-       bne     t8, $u_eos      # e1    :
-
-       /* Unaligned copy main loop.  In order to avoid reading too much,
-          the loop is structured to detect zeros in aligned source words.
-          This has, unfortunately, effectively pulled half of a loop
-          iteration out into the head and half into the tail, but it does
-          prevent nastiness from accumulating in the very thing we want
-          to run as fast as possible.
-
-          On entry to this basic block:
-          t1 == the shifted high-order bits from the previous source word
-          t2 == the unshifted current source word
-
-          We further know that t2 does not contain a null terminator.  */
-
-       .align 3
-$u_loop:
-       extqh   t2, a1, t0      # e0    : extract high bits for current word
-       addq    a1, 8, a1       # .. e1 :
-       extql   t2, a1, t3      # e0    : extract low bits for next time
-       addq    a0, 8, a0       # .. e1 :
-       or      t0, t1, t0      # e0    : current dst word now complete
-       EX( ldq_u t2, 0(a1) )   # .. e1 : load high word for next time
-       stq_u   t0, -8(a0)      # e0    : save the current word
-       mov     t3, t1          # .. e1 :
-       subq    a2, 1, a2       # e0    :
-       cmpbge  zero, t2, t8    # .. e1 : test new word for eos
-       beq     a2, $u_eoc      # e1    :
-       beq     t8, $u_loop     # e1    :
-
-       /* We've found a zero somewhere in the source word we just read.
-          If it resides in the lower half, we have one (probably partial)
-          word to write out, and if it resides in the upper half, we
-          have one full and one partial word left to write out.
-
-          On entry to this basic block:
-          t1 == the shifted high-order bits from the previous source word
-          t2 == the unshifted current source word.  */
-$u_eos:
-       extqh   t2, a1, t0      # e0    :
-       or      t0, t1, t0      # e1    : first (partial) source word complete
-
-       cmpbge  zero, t0, t8    # e0    : is the null in this first bit?
-       bne     t8, $u_final    # .. e1 (zdb)
-
-       stq_u   t0, 0(a0)       # e0    : the null was in the high-order bits
-       addq    a0, 8, a0       # .. e1 :
-       subq    a2, 1, a2       # e1    :
-
-$u_late_head_exit:
-       extql   t2, a1, t0      # .. e0 :
-       cmpbge  zero, t0, t8    # e0    :
-       or      t8, t10, t6     # e1    :
-       cmoveq  a2, t6, t8      # e0    :
-       nop                     # .. e1 :
-
-       /* Take care of a final (probably partial) result word.
-          On entry to this basic block:
-          t0 == assembled source word
-          t8 == cmpbge mask that found the null.  */
-$u_final:
-       negq    t8, t6          # e0    : isolate low bit set
-       and     t6, t8, t12     # e1    :
-
-       and     t12, 0x80, t6   # e0    : avoid dest word load if we can
-       bne     t6, 1f          # .. e1 (zdb)
-
-       ldq_u   t1, 0(a0)       # e0    :
-       subq    t12, 1, t6      # .. e1 :
-       or      t6, t12, t8     # e0    :
-       zapnot  t0, t8, t0      # .. e1 : kill source bytes > null
-       zap     t1, t8, t1      # e0    : kill dest bytes <= null
-       or      t0, t1, t0      # e1    :
-
-1:     stq_u   t0, 0(a0)       # e0    :
-       br      $finish_up
-
-$u_eoc:                                # end-of-count
-       extqh   t2, a1, t0
-       or      t0, t1, t0
-       cmpbge  zero, t0, t8
-
-$u_eocfin:                     # end-of-count, final word
-       or      t10, t8, t8
-       br      $u_final
-
-       /* Unaligned copy entry point.  */
-       .align 3
-$unaligned:
-
-       EX( ldq_u t1, 0(a1) )   # e0    : load first source word
-
-       and     a0, 7, t4       # .. e1 : find dest misalignment
-       and     a1, 7, t5       # e0    : find src misalignment
-
-       /* Conditionally load the first destination word and a bytemask
-          with 0xff indicating that the destination byte is sacrosanct.  */
-
-       mov     zero, t0        # .. e1 :
-       mov     zero, t6        # e0    :
-       beq     t4, 1f          # .. e1 :
-       ldq_u   t0, 0(a0)       # e0    :
-       lda     t6, -1          # .. e1 :
-       mskql   t6, a0, t6      # e0    :
-1:
-       subq    a1, t4, a1      # .. e1 : sub dest misalignment from src addr
-
-       /* If source misalignment is larger than dest misalignment, we need
-          extra startup checks to avoid SEGV.  */
-
-       cmplt   t4, t5, t12     # e1    :
-       extql   t1, a1, t1      # .. e0 : shift src into place
-       lda     t2, -1          # e0    : for creating masks later
-       beq     t12, $u_head    # e1    :
-
-       mskqh   t2, t5, t2      # e0    : begin src byte validity mask
-       cmpbge  zero, t1, t8    # .. e1 : is there a zero?
-       extql   t2, a1, t2      # e0    :
-       or      t8, t10, t5     # .. e1 : test for end-of-count too
-       cmpbge  zero, t2, t3    # e0    :
-       cmoveq  a2, t5, t8      # .. e1 :
-       andnot  t8, t3, t8      # e0    :
-       beq     t8, $u_head     # .. e1 (zdb)
-
-       /* At this point we've found a zero in the first partial word of
-          the source.  We need to isolate the valid source data and mask
-          it into the original destination data.  (Incidentally, we know
-          that we'll need at least one byte of that original dest word.) */
-
-       ldq_u   t0, 0(a0)       # e0    :
-       negq    t8, t6          # .. e1 : build bitmask of bytes <= zero
-       mskqh   t1, t4, t1      # e0    :
-       and     t6, t8, t12     # .. e1 :
-       subq    t12, 1, t6      # e0    :
-       or      t6, t12, t8     # e1    :
-
-       zapnot  t2, t8, t2      # e0    : prepare source word; mirror changes
-       zapnot  t1, t8, t1      # .. e1 : to source validity mask
-
-       andnot  t0, t2, t0      # e0    : zero place for source to reside
-       or      t0, t1, t0      # e1    : and put it there
-       stq_u   t0, 0(a0)       # e0    :
-
-$finish_up:
-       zapnot  t0, t12, t4     # was last byte written null?
-       cmovne  t4, 1, t4
-
-       and     t12, 0xf0, t3   # binary search for the address of the
-       and     t12, 0xcc, t2   # last byte written
-       and     t12, 0xaa, t1
-       bic     a0, 7, t0
-       cmovne  t3, 4, t3
-       cmovne  t2, 2, t2
-       cmovne  t1, 1, t1
-       addq    t0, t3, t0
-       addq    t1, t2, t1
-       addq    t0, t1, t0
-       addq    t0, t4, t0      # add one if we filled the buffer
-
-       subq    t0, v0, v0      # find string length
-       ret
-
-$zerolength:
-       clr     v0
-$exception:
-       ret
-
-       .end __strncpy_from_user
index 5eecab1a84efd3430deab218698ab3dab91c0e6a..0c4132dd3507a0b62b3c40c2fc6fd4065a325262 100644 (file)
@@ -89,6 +89,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
        const struct exception_table_entry *fixup;
        int fault, si_code = SEGV_MAPERR;
        siginfo_t info;
+       unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+                             (cause > 0 ? FAULT_FLAG_WRITE : 0));
 
        /* As of EV6, a load into $31/$f31 is a prefetch, and never faults
           (or is suppressed by the PALcode).  Support that for older CPUs
@@ -114,6 +116,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
                goto vmalloc_fault;
 #endif
 
+retry:
        down_read(&mm->mmap_sem);
        vma = find_vma(mm, address);
        if (!vma)
@@ -144,8 +147,11 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
        /* If for any reason at all we couldn't handle the fault,
           make sure we exit gracefully rather than endlessly redo
           the fault.  */
-       fault = handle_mm_fault(mm, vma, address, cause > 0 ? FAULT_FLAG_WRITE : 0);
-       up_read(&mm->mmap_sem);
+       fault = handle_mm_fault(mm, vma, address, flags);
+
+       if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+               return;
+
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM)
                        goto out_of_memory;
@@ -153,10 +159,26 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
                        goto do_sigbus;
                BUG();
        }
-       if (fault & VM_FAULT_MAJOR)
-               current->maj_flt++;
-       else
-               current->min_flt++;
+
+       if (flags & FAULT_FLAG_ALLOW_RETRY) {
+               if (fault & VM_FAULT_MAJOR)
+                       current->maj_flt++;
+               else
+                       current->min_flt++;
+               if (fault & VM_FAULT_RETRY) {
+                       flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+                        /* No need to up_read(&mm->mmap_sem) as we would
+                        * have already released it in __lock_page_or_retry
+                        * in mm/filemap.c.
+                        */
+
+                       goto retry;
+               }
+       }
+
+       up_read(&mm->mmap_sem);
+
        return;
 
        /* Something tried to access memory that isn't in our memory map.
@@ -186,12 +208,14 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
        /* We ran out of memory, or some other thing happened to us that
           made us unable to handle the page fault gracefully.  */
  out_of_memory:
+       up_read(&mm->mmap_sem);
        if (!user_mode(regs))
                goto no_context;
        pagefault_out_of_memory();
        return;
 
  do_sigbus:
+       up_read(&mm->mmap_sem);
        /* Send a sigbus, regardless of whether we were in kernel
           or user mode.  */
        info.si_signo = SIGBUS;
index a0a5d27aa2150e48c840cfcdae78f43f5bc8c4dd..b8ce18f485d3ecce23d9903138eeb930ab62cb4d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/smp.h>
 #include <linux/errno.h>
 #include <asm/ptrace.h>
+#include <asm/special_insns.h>
 
 #include "op_impl.h"
 
index ac353cf0180bb17056957dbfe6881fb989f26ef7..aad7400e0913141288022d7784eb375d204e63f1 100644 (file)
@@ -38,7 +38,6 @@ config ARM
        select HARDIRQS_SW_RESEND
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
-       select GENERIC_IRQ_PROBE
        select ARCH_WANT_IPC_PARSE_VERSION
        select HARDIRQS_SW_RESEND
        select CPU_PM if (SUSPEND || CPU_IDLE)
@@ -126,11 +125,6 @@ config TRACE_IRQFLAGS_SUPPORT
        bool
        default y
 
-config GENERIC_LOCKBREAK
-       bool
-       default y
-       depends on SMP && PREEMPT
-
 config RWSEM_GENERIC_SPINLOCK
        bool
        default y
@@ -692,6 +686,7 @@ config ARCH_TEGRA
        select NEED_MACH_IO_H if PCI
        select ARCH_HAS_CPUFREQ
        select USE_OF
+       select COMMON_CLK
        help
          This enables support for NVIDIA Tegra based systems (Tegra APX,
          Tegra 6xx and Tegra 2 series).
@@ -2097,6 +2092,7 @@ source "drivers/cpufreq/Kconfig"
 config CPU_FREQ_IMX
        tristate "CPUfreq driver for i.MX CPUs"
        depends on ARCH_MXC && CPU_FREQ
+       select CPU_FREQ_TABLE
        help
          This enables the CPUfreq driver for i.MX CPUs.
 
index 59509c48d7e5a5c2474f73ac028f73537e0a6659..bd0cff3f808c7c5be55ce79dd31b343d37e6297a 100644 (file)
                        #size-cells = <0>;
                        ti,hwmods = "i2c3";
                };
+
+               wdt2: wdt@44e35000 {
+                       compatible = "ti,omap3-wdt";
+                       ti,hwmods = "wd_timer2";
+               };
        };
 };
index a874dbfb5ae69da5d6771c75d9605ca3bbbcbcaa..e6138310e5ced961a269b903fadcfff6869c7be2 100644 (file)
 
                        dma-apbh@80004000 {
                                compatible = "fsl,imx23-dma-apbh";
-                               reg = <0x80004000 2000>;
+                               reg = <0x80004000 0x2000>;
                        };
 
                        ecc@80008000 {
-                               reg = <0x80008000 2000>;
+                               reg = <0x80008000 0x2000>;
                                status = "disabled";
                        };
 
@@ -63,7 +63,7 @@
                                compatible = "fsl,imx23-gpmi-nand";
                                #address-cells = <1>;
                                #size-cells = <1>;
-                               reg = <0x8000c000 2000>, <0x8000a000 2000>;
+                               reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
                                reg-names = "gpmi-nand", "bch";
                                interrupts = <13>, <56>;
                                interrupt-names = "gpmi-dma", "bch";
                        };
 
                        ssp0: ssp@80010000 {
-                               reg = <0x80010000 2000>;
+                               reg = <0x80010000 0x2000>;
                                interrupts = <15 14>;
                                fsl,ssp-dma-channel = <1>;
                                status = "disabled";
                        };
 
                        etm@80014000 {
-                               reg = <0x80014000 2000>;
+                               reg = <0x80014000 0x2000>;
                                status = "disabled";
                        };
 
@@ -87,7 +87,7 @@
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx23-pinctrl", "simple-bus";
-                               reg = <0x80018000 2000>;
+                               reg = <0x80018000 0x2000>;
 
                                gpio0: gpio@0 {
                                        compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
                        };
 
                        emi@80020000 {
-                               reg = <0x80020000 2000>;
+                               reg = <0x80020000 0x2000>;
                                status = "disabled";
                        };
 
                        dma-apbx@80024000 {
                                compatible = "fsl,imx23-dma-apbx";
-                               reg = <0x80024000 2000>;
+                               reg = <0x80024000 0x2000>;
                        };
 
                        dcp@80028000 {
-                               reg = <0x80028000 2000>;
+                               reg = <0x80028000 0x2000>;
                                status = "disabled";
                        };
 
                        pxp@8002a000 {
-                               reg = <0x8002a000 2000>;
+                               reg = <0x8002a000 0x2000>;
                                status = "disabled";
                        };
 
                        ocotp@8002c000 {
-                               reg = <0x8002c000 2000>;
+                               reg = <0x8002c000 0x2000>;
                                status = "disabled";
                        };
 
                        axi-ahb@8002e000 {
-                               reg = <0x8002e000 2000>;
+                               reg = <0x8002e000 0x2000>;
                                status = "disabled";
                        };
 
                        };
 
                        ssp1: ssp@80034000 {
-                               reg = <0x80034000 2000>;
+                               reg = <0x80034000 0x2000>;
                                interrupts = <2 20>;
                                fsl,ssp-dma-channel = <2>;
                                status = "disabled";
                        };
 
                        tvenc@80038000 {
-                               reg = <0x80038000 2000>;
+                               reg = <0x80038000 0x2000>;
                                status = "disabled";
                        };
                 };
                        ranges;
 
                        clkctl@80040000 {
-                               reg = <0x80040000 2000>;
+                               reg = <0x80040000 0x2000>;
                                status = "disabled";
                        };
 
                        saif0: saif@80042000 {
-                               reg = <0x80042000 2000>;
+                               reg = <0x80042000 0x2000>;
                                status = "disabled";
                        };
 
                        power@80044000 {
-                               reg = <0x80044000 2000>;
+                               reg = <0x80044000 0x2000>;
                                status = "disabled";
                        };
 
                        saif1: saif@80046000 {
-                               reg = <0x80046000 2000>;
+                               reg = <0x80046000 0x2000>;
                                status = "disabled";
                        };
 
                        audio-out@80048000 {
-                               reg = <0x80048000 2000>;
+                               reg = <0x80048000 0x2000>;
                                status = "disabled";
                        };
 
                        audio-in@8004c000 {
-                               reg = <0x8004c000 2000>;
+                               reg = <0x8004c000 0x2000>;
                                status = "disabled";
                        };
 
                        lradc@80050000 {
-                               reg = <0x80050000 2000>;
+                               reg = <0x80050000 0x2000>;
                                status = "disabled";
                        };
 
                        };
 
                        i2c@80058000 {
-                               reg = <0x80058000 2000>;
+                               reg = <0x80058000 0x2000>;
                                status = "disabled";
                        };
 
                        rtc@8005c000 {
                                compatible = "fsl,imx23-rtc", "fsl,stmp3xxx-rtc";
-                               reg = <0x8005c000 2000>;
+                               reg = <0x8005c000 0x2000>;
                                interrupts = <22>;
                        };
 
                        pwm: pwm@80064000 {
                                compatible = "fsl,imx23-pwm";
-                               reg = <0x80064000 2000>;
+                               reg = <0x80064000 0x2000>;
                                #pwm-cells = <2>;
                                fsl,pwm-number = <5>;
                                status = "disabled";
                        };
 
                        timrot@80068000 {
-                               reg = <0x80068000 2000>;
+                               reg = <0x80068000 0x2000>;
                                status = "disabled";
                        };
 
                ranges;
 
                usbctrl@80080000 {
-                       reg = <0x80080000 0x10000>;
+                       reg = <0x80080000 0x40000>;
                        status = "disabled";
                };
        };
index d3f8296e19e0828ea1bd94e88ef04a9467327e21..0a8978a40ecef73d826c12be5d7970b2120195da 100644 (file)
@@ -27,7 +27,7 @@
                                status = "okay";
                        };
 
-                       uart@1000a000 {
+                       uart1: serial@1000a000 {
                                fsl,uart-has-rtscts;
                                status = "okay";
                        };
index 00bae3aad5ab601f7a21adf4da8539aa48880781..5303ab680a3461614e324b27ed455f7da01b253d 100644 (file)
                serial3 = &uart4;
                serial4 = &uart5;
                serial5 = &uart6;
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               gpio5 = &gpio6;
        };
 
        avic: avic-interrupt-controller@e0000000 {
index 787efac68da81b81f79318a0ac55817eb92c8879..3fa6d190fab4f9a2c1c4c47abc8904bce199b0da 100644 (file)
                        };
 
                        hsadc@80002000 {
-                               reg = <0x80002000 2000>;
+                               reg = <0x80002000 0x2000>;
                                interrupts = <13 87>;
                                status = "disabled";
                        };
 
                        dma-apbh@80004000 {
                                compatible = "fsl,imx28-dma-apbh";
-                               reg = <0x80004000 2000>;
+                               reg = <0x80004000 0x2000>;
                        };
 
                        perfmon@80006000 {
-                               reg = <0x80006000 800>;
+                               reg = <0x80006000 0x800>;
                                interrupts = <27>;
                                status = "disabled";
                        };
@@ -77,7 +77,7 @@
                                compatible = "fsl,imx28-gpmi-nand";
                                #address-cells = <1>;
                                #size-cells = <1>;
-                               reg = <0x8000c000 2000>, <0x8000a000 2000>;
+                               reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
                                reg-names = "gpmi-nand", "bch";
                                interrupts = <88>, <41>;
                                interrupt-names = "gpmi-dma", "bch";
                        };
 
                        ssp0: ssp@80010000 {
-                               reg = <0x80010000 2000>;
+                               reg = <0x80010000 0x2000>;
                                interrupts = <96 82>;
                                fsl,ssp-dma-channel = <0>;
                                status = "disabled";
                        };
 
                        ssp1: ssp@80012000 {
-                               reg = <0x80012000 2000>;
+                               reg = <0x80012000 0x2000>;
                                interrupts = <97 83>;
                                fsl,ssp-dma-channel = <1>;
                                status = "disabled";
                        };
 
                        ssp2: ssp@80014000 {
-                               reg = <0x80014000 2000>;
+                               reg = <0x80014000 0x2000>;
                                interrupts = <98 84>;
                                fsl,ssp-dma-channel = <2>;
                                status = "disabled";
                        };
 
                        ssp3: ssp@80016000 {
-                               reg = <0x80016000 2000>;
+                               reg = <0x80016000 0x2000>;
                                interrupts = <99 85>;
                                fsl,ssp-dma-channel = <3>;
                                status = "disabled";
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx28-pinctrl", "simple-bus";
-                               reg = <0x80018000 2000>;
+                               reg = <0x80018000 0x2000>;
 
                                gpio0: gpio@0 {
                                        compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
                        };
 
                        digctl@8001c000 {
-                               reg = <0x8001c000 2000>;
+                               reg = <0x8001c000 0x2000>;
                                interrupts = <89>;
                                status = "disabled";
                        };
 
                        etm@80022000 {
-                               reg = <0x80022000 2000>;
+                               reg = <0x80022000 0x2000>;
                                status = "disabled";
                        };
 
                        dma-apbx@80024000 {
                                compatible = "fsl,imx28-dma-apbx";
-                               reg = <0x80024000 2000>;
+                               reg = <0x80024000 0x2000>;
                        };
 
                        dcp@80028000 {
-                               reg = <0x80028000 2000>;
+                               reg = <0x80028000 0x2000>;
                                interrupts = <52 53 54>;
                                status = "disabled";
                        };
 
                        pxp@8002a000 {
-                               reg = <0x8002a000 2000>;
+                               reg = <0x8002a000 0x2000>;
                                interrupts = <39>;
                                status = "disabled";
                        };
 
                        ocotp@8002c000 {
-                               reg = <0x8002c000 2000>;
+                               reg = <0x8002c000 0x2000>;
                                status = "disabled";
                        };
 
                        axi-ahb@8002e000 {
-                               reg = <0x8002e000 2000>;
+                               reg = <0x8002e000 0x2000>;
                                status = "disabled";
                        };
 
                        lcdif@80030000 {
                                compatible = "fsl,imx28-lcdif";
-                               reg = <0x80030000 2000>;
+                               reg = <0x80030000 0x2000>;
                                interrupts = <38 86>;
                                status = "disabled";
                        };
 
                        can0: can@80032000 {
                                compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan";
-                               reg = <0x80032000 2000>;
+                               reg = <0x80032000 0x2000>;
                                interrupts = <8>;
                                status = "disabled";
                        };
 
                        can1: can@80034000 {
                                compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan";
-                               reg = <0x80034000 2000>;
+                               reg = <0x80034000 0x2000>;
                                interrupts = <9>;
                                status = "disabled";
                        };
 
                        simdbg@8003c000 {
-                               reg = <0x8003c000 200>;
+                               reg = <0x8003c000 0x200>;
                                status = "disabled";
                        };
 
                        simgpmisel@8003c200 {
-                               reg = <0x8003c200 100>;
+                               reg = <0x8003c200 0x100>;
                                status = "disabled";
                        };
 
                        simsspsel@8003c300 {
-                               reg = <0x8003c300 100>;
+                               reg = <0x8003c300 0x100>;
                                status = "disabled";
                        };
 
                        simmemsel@8003c400 {
-                               reg = <0x8003c400 100>;
+                               reg = <0x8003c400 0x100>;
                                status = "disabled";
                        };
 
                        gpiomon@8003c500 {
-                               reg = <0x8003c500 100>;
+                               reg = <0x8003c500 0x100>;
                                status = "disabled";
                        };
 
                        simenet@8003c700 {
-                               reg = <0x8003c700 100>;
+                               reg = <0x8003c700 0x100>;
                                status = "disabled";
                        };
 
                        armjtag@8003c800 {
-                               reg = <0x8003c800 100>;
+                               reg = <0x8003c800 0x100>;
                                status = "disabled";
                        };
                 };
                        ranges;
 
                        clkctl@80040000 {
-                               reg = <0x80040000 2000>;
+                               reg = <0x80040000 0x2000>;
                                status = "disabled";
                        };
 
                        saif0: saif@80042000 {
                                compatible = "fsl,imx28-saif";
-                               reg = <0x80042000 2000>;
+                               reg = <0x80042000 0x2000>;
                                interrupts = <59 80>;
                                fsl,saif-dma-channel = <4>;
                                status = "disabled";
                        };
 
                        power@80044000 {
-                               reg = <0x80044000 2000>;
+                               reg = <0x80044000 0x2000>;
                                status = "disabled";
                        };
 
                        saif1: saif@80046000 {
                                compatible = "fsl,imx28-saif";
-                               reg = <0x80046000 2000>;
+                               reg = <0x80046000 0x2000>;
                                interrupts = <58 81>;
                                fsl,saif-dma-channel = <5>;
                                status = "disabled";
                        };
 
                        lradc@80050000 {
-                               reg = <0x80050000 2000>;
+                               reg = <0x80050000 0x2000>;
                                status = "disabled";
                        };
 
                        spdif@80054000 {
-                               reg = <0x80054000 2000>;
+                               reg = <0x80054000 0x2000>;
                                interrupts = <45 66>;
                                status = "disabled";
                        };
 
                        rtc@80056000 {
                                compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc";
-                               reg = <0x80056000 2000>;
+                               reg = <0x80056000 0x2000>;
                                interrupts = <29>;
                        };
 
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx28-i2c";
-                               reg = <0x80058000 2000>;
+                               reg = <0x80058000 0x2000>;
                                interrupts = <111 68>;
                                clock-frequency = <100000>;
                                status = "disabled";
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx28-i2c";
-                               reg = <0x8005a000 2000>;
+                               reg = <0x8005a000 0x2000>;
                                interrupts = <110 69>;
                                clock-frequency = <100000>;
                                status = "disabled";
 
                        pwm: pwm@80064000 {
                                compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
-                               reg = <0x80064000 2000>;
+                               reg = <0x80064000 0x2000>;
                                #pwm-cells = <2>;
                                fsl,pwm-number = <8>;
                                status = "disabled";
                        };
 
                        timrot@80068000 {
-                               reg = <0x80068000 2000>;
+                               reg = <0x80068000 0x2000>;
                                status = "disabled";
                        };
 
index de065b5976e6cf0ed025c7e550198f4b079b817c..59d9789e550898cc041e6670ca0430776b204c2b 100644 (file)
@@ -25,8 +25,8 @@
                aips@70000000 { /* aips-1 */
                        spba@70000000 {
                                esdhc@70004000 { /* ESDHC1 */
-                                       fsl,cd-internal;
-                                       fsl,wp-internal;
+                                       fsl,cd-controller;
+                                       fsl,wp-controller;
                                        status = "okay";
                                };
 
@@ -53,7 +53,7 @@
                                                spi-max-frequency = <6000000>;
                                                reg = <0>;
                                                interrupt-parent = <&gpio1>;
-                                               interrupts = <8>;
+                                               interrupts = <8 0x4>;
 
                                                regulators {
                                                        sw1_reg: sw1 {
index 53cbaa3d4f904cbe464116640824fd24a4015d81..aba28dc87fc80b3d064b5acb0861ab80eec4eca1 100644 (file)
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
        };
 
        tzic: tz-interrupt-controller@e0000000 {
index 5b8eafcdbeec638009a894365b577df17256b3c0..da895e93a999113e0585905126dd980f3029e80b 100644 (file)
                        reg = <0xf4000000 0x2000000>;
                        phy-mode = "mii";
                        interrupt-parent = <&gpio2>;
-                       interrupts = <31>;
+                       interrupts = <31 0x8>;
                        reg-io-width = <4>;
+                       /*
+                        * VDD33A and VDDVARIO of LAN9220 are supplied by
+                        * SW4_3V3 of LTC3589.  Before the regulator driver
+                        * for this PMIC is available, we use a fixed dummy
+                        * 3V3 regulator to get LAN9220 driver probing work.
+                        */
+                       vdd33a-supply = <&reg_3p3v>;
+                       vddvario-supply = <&reg_3p3v>;
                        smsc,irq-push-pull;
                };
        };
 
+       regulators {
+               compatible = "simple-bus";
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
 
index fc79cdc4b4e6a18d96138025bad146caabb04004..cd37165edce5e5d2f06628813c01e17181aa8b8d 100644 (file)
                serial2 = &uart3;
                serial3 = &uart4;
                serial4 = &uart5;
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               gpio5 = &gpio6;
+               gpio6 = &gpio7;
        };
 
        tzic: tz-interrupt-controller@0fffc000 {
index d42e851ceb97e423fd785e3cd357ba6d70b23d8c..72f30f3e6171b4b737d122333c03a25a37189ddb 100644 (file)
@@ -53,6 +53,7 @@
                                                fsl,pins = <
                                                           144  0x80000000      /* MX6Q_PAD_EIM_D22__GPIO_3_22 */
                                                           121  0x80000000      /* MX6Q_PAD_EIM_D19__GPIO_3_19 */
+                                                          953  0x80000000      /* MX6Q_PAD_GPIO_0__CCM_CLKO */
                                                           >;
                                        };
                                };
index 3d3c64b014e61f9978072571343f6b84afb5f523..fd57079f71a95281d107da8df2328c37df8cc1d6 100644 (file)
                serial2 = &uart3;
                serial3 = &uart4;
                serial4 = &uart5;
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               gpio5 = &gpio6;
+               gpio6 = &gpio7;
        };
 
        cpus {
index 52d9470451069f5445661c79ffa902a7cc49eee1..f8ca6fa88192a5d36edb0c484a7a13c7c11e6e7c 100644 (file)
                };
                power-blue {
                        label = "power:blue";
-                       gpios = <&gpio1 11 0>;
+                       gpios = <&gpio1 10 0>;
                        linux,default-trigger = "timer";
                };
+               power-red {
+                       label = "power:red";
+                       gpios = <&gpio1 11 0>;
+               };
                usb1 {
                        label = "usb1:blue";
                        gpios = <&gpio1 12 0>;
index 3b2f3510d7eb91ca5ce520692682ad26aca89d31..d351b27d7213f65c50680e50965d41cdfd4218f2 100644 (file)
@@ -66,6 +66,7 @@
 
        vcxio: regulator@8 {
                compatible = "ti,twl6030-vcxio";
+               regulator-always-on;
        };
 
        vusb: regulator@9 {
 
        v1v8: regulator@10 {
                compatible = "ti,twl6030-v1v8";
+               regulator-always-on;
        };
 
        v2v1: regulator@11 {
                compatible = "ti,twl6030-v2v1";
+               regulator-always-on;
        };
 
        clk32kg: regulator@12 {
index f725b9637b3374a4079c17ca50823f064ea0bb6d..3c9f32f9b6b4dc6e5b77884deaa216c87684919c 100644 (file)
@@ -192,6 +192,7 @@ CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
 CONFIG_DMADEVICES=y
 CONFIG_IMX_SDMA=y
+CONFIG_MXS_DMA=y
 CONFIG_COMMON_CLK_DEBUG=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT2_FS=y
index ccdb6357fb74065e017d44527a27e8c2c7a3f46d..4edcfb4e4deeea476d9b5007779153d2281643b8 100644 (file)
@@ -34,7 +34,6 @@ CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_AEABI=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
 CONFIG_AUTO_ZRELADDR=y
 CONFIG_FPE_NWFPE=y
 CONFIG_NET=y
index 1d24f8458befd49cd41b98e6fb1d6f22fcca8f94..71277a1591bad96d77036ad8eb2557af2a6d4c54 100644 (file)
@@ -7,7 +7,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_KALLSYMS is not set
-# CONFIG_BUG is not set
+# CONFIG_BUGVERBOSE is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_SHMEM is not set
 CONFIG_SLOB=y
index 2d4f661d1cf6e757739429a4ba7730ea7be14eeb..da6845493caabae29842d959f0b80bdcc1bd7790 100644 (file)
@@ -86,6 +86,7 @@ CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_LM3530=y
 CONFIG_LEDS_LP5521=y
+CONFIG_LEDS_GPIO=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AB8500=y
 CONFIG_RTC_DRV_PL031=y
index f66626d71e7d1a304ad2c750fc4b00be9a436901..41dc31f834c3b68926a070036ac024b83f8e7b66 100644 (file)
@@ -195,6 +195,18 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 
 #define pte_clear(mm,addr,ptep)        set_pte_ext(ptep, __pte(0), 0)
 
+#define pte_none(pte)          (!pte_val(pte))
+#define pte_present(pte)       (pte_val(pte) & L_PTE_PRESENT)
+#define pte_write(pte)         (!(pte_val(pte) & L_PTE_RDONLY))
+#define pte_dirty(pte)         (pte_val(pte) & L_PTE_DIRTY)
+#define pte_young(pte)         (pte_val(pte) & L_PTE_YOUNG)
+#define pte_exec(pte)          (!(pte_val(pte) & L_PTE_XN))
+#define pte_special(pte)       (0)
+
+#define pte_present_user(pte) \
+       ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
+        (L_PTE_PRESENT | L_PTE_USER))
+
 #if __LINUX_ARM_ARCH__ < 6
 static inline void __sync_icache_dcache(pte_t pteval)
 {
@@ -206,25 +218,15 @@ extern void __sync_icache_dcache(pte_t pteval);
 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
                              pte_t *ptep, pte_t pteval)
 {
-       if (addr >= TASK_SIZE)
-               set_pte_ext(ptep, pteval, 0);
-       else {
+       unsigned long ext = 0;
+
+       if (addr < TASK_SIZE && pte_present_user(pteval)) {
                __sync_icache_dcache(pteval);
-               set_pte_ext(ptep, pteval, PTE_EXT_NG);
+               ext |= PTE_EXT_NG;
        }
-}
 
-#define pte_none(pte)          (!pte_val(pte))
-#define pte_present(pte)       (pte_val(pte) & L_PTE_PRESENT)
-#define pte_write(pte)         (!(pte_val(pte) & L_PTE_RDONLY))
-#define pte_dirty(pte)         (pte_val(pte) & L_PTE_DIRTY)
-#define pte_young(pte)         (pte_val(pte) & L_PTE_YOUNG)
-#define pte_exec(pte)          (!(pte_val(pte) & L_PTE_XN))
-#define pte_special(pte)       (0)
-
-#define pte_present_user(pte) \
-       ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
-        (L_PTE_PRESENT | L_PTE_USER))
+       set_pte_ext(ptep, pteval, ext);
+}
 
 #define PTE_BIT_FUNC(fn,op) \
 static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
@@ -251,13 +253,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  *
  *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *   <--------------- offset --------------------> <- type --> 0 0 0
+ *   <--------------- offset ----------------------> < type -> 0 0 0
  *
- * This gives us up to 63 swap files and 32GB per swap file.  Note that
+ * This gives us up to 31 swap files and 64GB per swap file.  Note that
  * the offset field is always non-zero.
  */
 #define __SWP_TYPE_SHIFT       3
-#define __SWP_TYPE_BITS                6
+#define __SWP_TYPE_BITS                5
 #define __SWP_TYPE_MASK                ((1 << __SWP_TYPE_BITS) - 1)
 #define __SWP_OFFSET_SHIFT     (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
 
index e3f7572634381bd28fbf3225eb375788431ee3fc..05b8e82ec9f5b66744305de1094df1115fc92798 100644 (file)
@@ -10,5 +10,7 @@
 
 extern void sched_clock_postinit(void);
 extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
+extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
+               unsigned long rate);
 
 #endif
index 27d186abbc06f8aa3aa6310faa5b67039d447f03..f4515393248dab76b97700f55ef17bba68e6cd0a 100644 (file)
@@ -21,6 +21,8 @@ struct clock_data {
        u32 epoch_cyc_copy;
        u32 mult;
        u32 shift;
+       bool suspended;
+       bool needs_suspend;
 };
 
 static void sched_clock_poll(unsigned long wrap_ticks);
@@ -49,6 +51,9 @@ static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask)
        u64 epoch_ns;
        u32 epoch_cyc;
 
+       if (cd.suspended)
+               return cd.epoch_ns;
+
        /*
         * Load the epoch_cyc and epoch_ns atomically.  We do this by
         * ensuring that we always write epoch_cyc, epoch_ns and
@@ -98,6 +103,13 @@ static void sched_clock_poll(unsigned long wrap_ticks)
        update_sched_clock();
 }
 
+void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
+               unsigned long rate)
+{
+       setup_sched_clock(read, bits, rate);
+       cd.needs_suspend = true;
+}
+
 void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
 {
        unsigned long r, w;
@@ -169,11 +181,23 @@ void __init sched_clock_postinit(void)
 static int sched_clock_suspend(void)
 {
        sched_clock_poll(sched_clock_timer.data);
+       if (cd.needs_suspend)
+               cd.suspended = true;
        return 0;
 }
 
+static void sched_clock_resume(void)
+{
+       if (cd.needs_suspend) {
+               cd.epoch_cyc = read_sched_clock();
+               cd.epoch_cyc_copy = cd.epoch_cyc;
+               cd.suspended = false;
+       }
+}
+
 static struct syscore_ops sched_clock_ops = {
        .suspend = sched_clock_suspend,
+       .resume = sched_clock_resume,
 };
 
 static int __init sched_clock_syscore_init(void)
index 198b08456e905e42d1c09819083c003d9a59e988..26c12c6440fcde02a3829f1ed3e1035f16ed6338 100644 (file)
@@ -321,7 +321,7 @@ void store_cpu_topology(unsigned int cpuid)
  * init_cpu_topology is called at boot when only one cpu is running
  * which prevent simultaneous write access to cpu_topology array
  */
-void init_cpu_topology(void)
+void __init init_cpu_topology(void)
 {
        unsigned int cpu;
 
index 2473fd1fd51cfa50ef02985e6e8d83c5f97119c8..af72969820b4951448c9d95135383ae9d8387cde 100644 (file)
@@ -16,13 +16,30 @@ lib-y               := backtrace.o changebit.o csumipv6.o csumpartial.o   \
                   call_with_stack.o
 
 mmu-y  := clear_user.o copy_page.o getuser.o putuser.o
-mmu-y  += copy_from_user.o copy_to_user.o
+
+# the code in uaccess.S is not preemption safe and
+# probably faster on ARMv3 only
+ifeq ($(CONFIG_PREEMPT),y)
+  mmu-y        += copy_from_user.o copy_to_user.o
+else
+ifneq ($(CONFIG_CPU_32v3),y)
+  mmu-y        += copy_from_user.o copy_to_user.o
+else
+  mmu-y        += uaccess.o
+endif
+endif
 
 # using lib_ here won't override already available weak symbols
 obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o
 
-lib-$(CONFIG_MMU)              += $(mmu-y)
-lib-y                          += io-readsw-armv4.o io-writesw-armv4.o
+lib-$(CONFIG_MMU) += $(mmu-y)
+
+ifeq ($(CONFIG_CPU_32v3),y)
+  lib-y        += io-readsw-armv3.o io-writesw-armv3.o
+else
+  lib-y        += io-readsw-armv4.o io-writesw-armv4.o
+endif
+
 lib-$(CONFIG_ARCH_RPC)         += ecard.o io-acorn.o floppydma.o
 lib-$(CONFIG_ARCH_SHARK)       += io-shark.o
 
diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S
new file mode 100644 (file)
index 0000000..88487c8
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  linux/arch/arm/lib/io-readsw-armv3.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * 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>
+
+.Linsw_bad_alignment:
+               adr     r0, .Linsw_bad_align_msg
+               mov     r2, lr
+               b       panic
+.Linsw_bad_align_msg:
+               .asciz  "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+               .align
+
+.Linsw_align:  tst     r1, #1
+               bne     .Linsw_bad_alignment
+
+               ldr     r3, [r0]
+               strb    r3, [r1], #1
+               mov     r3, r3, lsr #8
+               strb    r3, [r1], #1
+
+               subs    r2, r2, #1
+               moveq   pc, lr
+
+ENTRY(__raw_readsw)
+               teq     r2, #0          @ do we have to check for the zero len?
+               moveq   pc, lr
+               tst     r1, #3
+               bne     .Linsw_align
+
+.Linsw_aligned:        mov     ip, #0xff
+               orr     ip, ip, ip, lsl #8
+               stmfd   sp!, {r4, r5, r6, lr}
+
+               subs    r2, r2, #8
+               bmi     .Lno_insw_8
+
+.Linsw_8_lp:   ldr     r3, [r0]
+               and     r3, r3, ip
+               ldr     r4, [r0]
+               orr     r3, r3, r4, lsl #16
+
+               ldr     r4, [r0]
+               and     r4, r4, ip
+               ldr     r5, [r0]
+               orr     r4, r4, r5, lsl #16
+
+               ldr     r5, [r0]
+               and     r5, r5, ip
+               ldr     r6, [r0]
+               orr     r5, r5, r6, lsl #16
+
+               ldr     r6, [r0]
+               and     r6, r6, ip
+               ldr     lr, [r0]
+               orr     r6, r6, lr, lsl #16
+
+               stmia   r1!, {r3 - r6}
+
+               subs    r2, r2, #8
+               bpl     .Linsw_8_lp
+
+               tst     r2, #7
+               ldmeqfd sp!, {r4, r5, r6, pc}
+
+.Lno_insw_8:   tst     r2, #4
+               beq     .Lno_insw_4
+
+               ldr     r3, [r0]
+               and     r3, r3, ip
+               ldr     r4, [r0]
+               orr     r3, r3, r4, lsl #16
+
+               ldr     r4, [r0]
+               and     r4, r4, ip
+               ldr     r5, [r0]
+               orr     r4, r4, r5, lsl #16
+
+               stmia   r1!, {r3, r4}
+
+.Lno_insw_4:   tst     r2, #2
+               beq     .Lno_insw_2
+
+               ldr     r3, [r0]
+               and     r3, r3, ip
+               ldr     r4, [r0]
+               orr     r3, r3, r4, lsl #16
+
+               str     r3, [r1], #4
+
+.Lno_insw_2:   tst     r2, #1
+               ldrne   r3, [r0]
+               strneb  r3, [r1], #1
+               movne   r3, r3, lsr #8
+               strneb  r3, [r1]
+
+               ldmfd   sp!, {r4, r5, r6, pc}
+
+
diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S
new file mode 100644 (file)
index 0000000..49b8004
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ *  linux/arch/arm/lib/io-writesw-armv3.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * 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>
+
+.Loutsw_bad_alignment:
+               adr     r0, .Loutsw_bad_align_msg
+               mov     r2, lr
+               b       panic
+.Loutsw_bad_align_msg:
+               .asciz  "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+               .align
+
+.Loutsw_align: tst     r1, #1
+               bne     .Loutsw_bad_alignment
+
+               add     r1, r1, #2
+
+               ldr     r3, [r1, #-4]
+               mov     r3, r3, lsr #16
+               orr     r3, r3, r3, lsl #16
+               str     r3, [r0]
+               subs    r2, r2, #1
+               moveq   pc, lr
+
+ENTRY(__raw_writesw)
+               teq     r2, #0          @ do we have to check for the zero len?
+               moveq   pc, lr
+               tst     r1, #3
+               bne     .Loutsw_align
+
+               stmfd   sp!, {r4, r5, r6, lr}
+
+               subs    r2, r2, #8
+               bmi     .Lno_outsw_8
+
+.Loutsw_8_lp:  ldmia   r1!, {r3, r4, r5, r6}
+
+               mov     ip, r3, lsl #16
+               orr     ip, ip, ip, lsr #16
+               str     ip, [r0]
+
+               mov     ip, r3, lsr #16
+               orr     ip, ip, ip, lsl #16
+               str     ip, [r0]
+
+               mov     ip, r4, lsl #16
+               orr     ip, ip, ip, lsr #16
+               str     ip, [r0]
+
+               mov     ip, r4, lsr #16
+               orr     ip, ip, ip, lsl #16
+               str     ip, [r0]
+
+               mov     ip, r5, lsl #16
+               orr     ip, ip, ip, lsr #16
+               str     ip, [r0]
+
+               mov     ip, r5, lsr #16
+               orr     ip, ip, ip, lsl #16
+               str     ip, [r0]
+
+               mov     ip, r6, lsl #16
+               orr     ip, ip, ip, lsr #16
+               str     ip, [r0]
+
+               mov     ip, r6, lsr #16
+               orr     ip, ip, ip, lsl #16
+               str     ip, [r0]
+
+               subs    r2, r2, #8
+               bpl     .Loutsw_8_lp
+
+               tst     r2, #7
+               ldmeqfd sp!, {r4, r5, r6, pc}
+
+.Lno_outsw_8:  tst     r2, #4
+               beq     .Lno_outsw_4
+
+               ldmia   r1!, {r3, r4}
+
+               mov     ip, r3, lsl #16
+               orr     ip, ip, ip, lsr #16
+               str     ip, [r0]
+
+               mov     ip, r3, lsr #16
+               orr     ip, ip, ip, lsl #16
+               str     ip, [r0]
+
+               mov     ip, r4, lsl #16
+               orr     ip, ip, ip, lsr #16
+               str     ip, [r0]
+
+               mov     ip, r4, lsr #16
+               orr     ip, ip, ip, lsl #16
+               str     ip, [r0]
+
+.Lno_outsw_4:  tst     r2, #2
+               beq     .Lno_outsw_2
+
+               ldr     r3, [r1], #4
+
+               mov     ip, r3, lsl #16
+               orr     ip, ip, ip, lsr #16
+               str     ip, [r0]
+
+               mov     ip, r3, lsr #16
+               orr     ip, ip, ip, lsl #16
+               str     ip, [r0]
+
+.Lno_outsw_2:  tst     r2, #1
+
+               ldrne   r3, [r1]
+
+               movne   ip, r3, lsl #16
+               orrne   ip, ip, ip, lsr #16
+               strne   ip, [r0]
+
+               ldmfd   sp!, {r4, r5, r6, pc}
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
new file mode 100644 (file)
index 0000000..5c908b1
--- /dev/null
@@ -0,0 +1,564 @@
+/*
+ *  linux/arch/arm/lib/uaccess.S
+ *
+ *  Copyright (C) 1995, 1996,1997,1998 Russell King
+ *
+ * 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.
+ *
+ *  Routines to block copy data to/from user memory
+ *   These are highly optimised both for the 4k page size
+ *   and for various alignments.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+#include <asm/domain.h>
+
+               .text
+
+#define PAGE_SHIFT 12
+
+/* Prototype: int __copy_to_user(void *to, const char *from, size_t n)
+ * Purpose  : copy a block to user memory from kernel memory
+ * Params   : to   - user memory
+ *          : from - kernel memory
+ *          : n    - number of bytes to copy
+ * Returns  : Number of bytes NOT copied.
+ */
+
+.Lc2u_dest_not_aligned:
+               rsb     ip, ip, #4
+               cmp     ip, #2
+               ldrb    r3, [r1], #1
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
+               ldrgeb  r3, [r1], #1
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
+               ldrgtb  r3, [r1], #1
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
+               sub     r2, r2, ip
+               b       .Lc2u_dest_aligned
+
+ENTRY(__copy_to_user)
+               stmfd   sp!, {r2, r4 - r7, lr}
+               cmp     r2, #4
+               blt     .Lc2u_not_enough
+               ands    ip, r0, #3
+               bne     .Lc2u_dest_not_aligned
+.Lc2u_dest_aligned:
+
+               ands    ip, r1, #3
+               bne     .Lc2u_src_not_aligned
+/*
+ * Seeing as there has to be at least 8 bytes to copy, we can
+ * copy one word, and force a user-mode page fault...
+ */
+
+.Lc2u_0fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lc2u_0nowords
+               ldr     r3, [r1], #4
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
+               mov     ip, r0, lsl #32 - PAGE_SHIFT    @ On each page, use a ld/st??t instruction
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lc2u_0fupi
+/*
+ * ip = max no. of bytes to copy before needing another "strt" insn
+ */
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #32
+               blt     .Lc2u_0rem8lp
+
+.Lc2u_0cpy8lp: ldmia   r1!, {r3 - r6}
+               stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+               ldmia   r1!, {r3 - r6}
+               subs    ip, ip, #32
+               stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+               bpl     .Lc2u_0cpy8lp
+
+.Lc2u_0rem8lp: cmn     ip, #16
+               ldmgeia r1!, {r3 - r6}
+               stmgeia r0!, {r3 - r6}                  @ Shouldnt fault
+               tst     ip, #8
+               ldmneia r1!, {r3 - r4}
+               stmneia r0!, {r3 - r4}                  @ Shouldnt fault
+               tst     ip, #4
+               ldrne   r3, [r1], #4
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
+               ands    ip, ip, #3
+               beq     .Lc2u_0fupi
+.Lc2u_0nowords:        teq     ip, #0
+               beq     .Lc2u_finished
+.Lc2u_nowords: cmp     ip, #2
+               ldrb    r3, [r1], #1
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
+               ldrgeb  r3, [r1], #1
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
+               ldrgtb  r3, [r1], #1
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
+               b       .Lc2u_finished
+
+.Lc2u_not_enough:
+               movs    ip, r2
+               bne     .Lc2u_nowords
+.Lc2u_finished:        mov     r0, #0
+               ldmfd   sp!, {r2, r4 - r7, pc}
+
+.Lc2u_src_not_aligned:
+               bic     r1, r1, #3
+               ldr     r7, [r1], #4
+               cmp     ip, #2
+               bgt     .Lc2u_3fupi
+               beq     .Lc2u_2fupi
+.Lc2u_1fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lc2u_1nowords
+               mov     r3, r7, pull #8
+               ldr     r7, [r1], #4
+               orr     r3, r3, r7, push #24
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
+               mov     ip, r0, lsl #32 - PAGE_SHIFT
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lc2u_1fupi
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #16
+               blt     .Lc2u_1rem8lp
+
+.Lc2u_1cpy8lp: mov     r3, r7, pull #8
+               ldmia   r1!, {r4 - r7}
+               subs    ip, ip, #16
+               orr     r3, r3, r4, push #24
+               mov     r4, r4, pull #8
+               orr     r4, r4, r5, push #24
+               mov     r5, r5, pull #8
+               orr     r5, r5, r6, push #24
+               mov     r6, r6, pull #8
+               orr     r6, r6, r7, push #24
+               stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+               bpl     .Lc2u_1cpy8lp
+
+.Lc2u_1rem8lp: tst     ip, #8
+               movne   r3, r7, pull #8
+               ldmneia r1!, {r4, r7}
+               orrne   r3, r3, r4, push #24
+               movne   r4, r4, pull #8
+               orrne   r4, r4, r7, push #24
+               stmneia r0!, {r3 - r4}                  @ Shouldnt fault
+               tst     ip, #4
+               movne   r3, r7, pull #8
+               ldrne   r7, [r1], #4
+               orrne   r3, r3, r7, push #24
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
+               ands    ip, ip, #3
+               beq     .Lc2u_1fupi
+.Lc2u_1nowords:        mov     r3, r7, get_byte_1
+               teq     ip, #0
+               beq     .Lc2u_finished
+               cmp     ip, #2
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
+               movge   r3, r7, get_byte_2
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
+               movgt   r3, r7, get_byte_3
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
+               b       .Lc2u_finished
+
+.Lc2u_2fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lc2u_2nowords
+               mov     r3, r7, pull #16
+               ldr     r7, [r1], #4
+               orr     r3, r3, r7, push #16
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
+               mov     ip, r0, lsl #32 - PAGE_SHIFT
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lc2u_2fupi
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #16
+               blt     .Lc2u_2rem8lp
+
+.Lc2u_2cpy8lp: mov     r3, r7, pull #16
+               ldmia   r1!, {r4 - r7}
+               subs    ip, ip, #16
+               orr     r3, r3, r4, push #16
+               mov     r4, r4, pull #16
+               orr     r4, r4, r5, push #16
+               mov     r5, r5, pull #16
+               orr     r5, r5, r6, push #16
+               mov     r6, r6, pull #16
+               orr     r6, r6, r7, push #16
+               stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+               bpl     .Lc2u_2cpy8lp
+
+.Lc2u_2rem8lp: tst     ip, #8
+               movne   r3, r7, pull #16
+               ldmneia r1!, {r4, r7}
+               orrne   r3, r3, r4, push #16
+               movne   r4, r4, pull #16
+               orrne   r4, r4, r7, push #16
+               stmneia r0!, {r3 - r4}                  @ Shouldnt fault
+               tst     ip, #4
+               movne   r3, r7, pull #16
+               ldrne   r7, [r1], #4
+               orrne   r3, r3, r7, push #16
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
+               ands    ip, ip, #3
+               beq     .Lc2u_2fupi
+.Lc2u_2nowords:        mov     r3, r7, get_byte_2
+               teq     ip, #0
+               beq     .Lc2u_finished
+               cmp     ip, #2
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
+               movge   r3, r7, get_byte_3
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
+               ldrgtb  r3, [r1], #0
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
+               b       .Lc2u_finished
+
+.Lc2u_3fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lc2u_3nowords
+               mov     r3, r7, pull #24
+               ldr     r7, [r1], #4
+               orr     r3, r3, r7, push #8
+USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
+               mov     ip, r0, lsl #32 - PAGE_SHIFT
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lc2u_3fupi
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #16
+               blt     .Lc2u_3rem8lp
+
+.Lc2u_3cpy8lp: mov     r3, r7, pull #24
+               ldmia   r1!, {r4 - r7}
+               subs    ip, ip, #16
+               orr     r3, r3, r4, push #8
+               mov     r4, r4, pull #24
+               orr     r4, r4, r5, push #8
+               mov     r5, r5, pull #24
+               orr     r5, r5, r6, push #8
+               mov     r6, r6, pull #24
+               orr     r6, r6, r7, push #8
+               stmia   r0!, {r3 - r6}                  @ Shouldnt fault
+               bpl     .Lc2u_3cpy8lp
+
+.Lc2u_3rem8lp: tst     ip, #8
+               movne   r3, r7, pull #24
+               ldmneia r1!, {r4, r7}
+               orrne   r3, r3, r4, push #8
+               movne   r4, r4, pull #24
+               orrne   r4, r4, r7, push #8
+               stmneia r0!, {r3 - r4}                  @ Shouldnt fault
+               tst     ip, #4
+               movne   r3, r7, pull #24
+               ldrne   r7, [r1], #4
+               orrne   r3, r3, r7, push #8
+       TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
+               ands    ip, ip, #3
+               beq     .Lc2u_3fupi
+.Lc2u_3nowords:        mov     r3, r7, get_byte_3
+               teq     ip, #0
+               beq     .Lc2u_finished
+               cmp     ip, #2
+USER(  TUSER(  strb)   r3, [r0], #1)                   @ May fault
+               ldrgeb  r3, [r1], #1
+USER(  TUSER(  strgeb) r3, [r0], #1)                   @ May fault
+               ldrgtb  r3, [r1], #0
+USER(  TUSER(  strgtb) r3, [r0], #1)                   @ May fault
+               b       .Lc2u_finished
+ENDPROC(__copy_to_user)
+
+               .pushsection .fixup,"ax"
+               .align  0
+9001:          ldmfd   sp!, {r0, r4 - r7, pc}
+               .popsection
+
+/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
+ * Purpose  : copy a block from user memory to kernel memory
+ * Params   : to   - kernel memory
+ *          : from - user memory
+ *          : n    - number of bytes to copy
+ * Returns  : Number of bytes NOT copied.
+ */
+.Lcfu_dest_not_aligned:
+               rsb     ip, ip, #4
+               cmp     ip, #2
+USER(  TUSER(  ldrb)   r3, [r1], #1)                   @ May fault
+               strb    r3, [r0], #1
+USER(  TUSER(  ldrgeb) r3, [r1], #1)                   @ May fault
+               strgeb  r3, [r0], #1
+USER(  TUSER(  ldrgtb) r3, [r1], #1)                   @ May fault
+               strgtb  r3, [r0], #1
+               sub     r2, r2, ip
+               b       .Lcfu_dest_aligned
+
+ENTRY(__copy_from_user)
+               stmfd   sp!, {r0, r2, r4 - r7, lr}
+               cmp     r2, #4
+               blt     .Lcfu_not_enough
+               ands    ip, r0, #3
+               bne     .Lcfu_dest_not_aligned
+.Lcfu_dest_aligned:
+               ands    ip, r1, #3
+               bne     .Lcfu_src_not_aligned
+
+/*
+ * Seeing as there has to be at least 8 bytes to copy, we can
+ * copy one word, and force a user-mode page fault...
+ */
+
+.Lcfu_0fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lcfu_0nowords
+USER(  TUSER(  ldr)    r3, [r1], #4)
+               str     r3, [r0], #4
+               mov     ip, r1, lsl #32 - PAGE_SHIFT    @ On each page, use a ld/st??t instruction
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lcfu_0fupi
+/*
+ * ip = max no. of bytes to copy before needing another "strt" insn
+ */
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #32
+               blt     .Lcfu_0rem8lp
+
+.Lcfu_0cpy8lp: ldmia   r1!, {r3 - r6}                  @ Shouldnt fault
+               stmia   r0!, {r3 - r6}
+               ldmia   r1!, {r3 - r6}                  @ Shouldnt fault
+               subs    ip, ip, #32
+               stmia   r0!, {r3 - r6}
+               bpl     .Lcfu_0cpy8lp
+
+.Lcfu_0rem8lp: cmn     ip, #16
+               ldmgeia r1!, {r3 - r6}                  @ Shouldnt fault
+               stmgeia r0!, {r3 - r6}
+               tst     ip, #8
+               ldmneia r1!, {r3 - r4}                  @ Shouldnt fault
+               stmneia r0!, {r3 - r4}
+               tst     ip, #4
+       TUSER(  ldrne) r3, [r1], #4                     @ Shouldnt fault
+               strne   r3, [r0], #4
+               ands    ip, ip, #3
+               beq     .Lcfu_0fupi
+.Lcfu_0nowords:        teq     ip, #0
+               beq     .Lcfu_finished
+.Lcfu_nowords: cmp     ip, #2
+USER(  TUSER(  ldrb)   r3, [r1], #1)                   @ May fault
+               strb    r3, [r0], #1
+USER(  TUSER(  ldrgeb) r3, [r1], #1)                   @ May fault
+               strgeb  r3, [r0], #1
+USER(  TUSER(  ldrgtb) r3, [r1], #1)                   @ May fault
+               strgtb  r3, [r0], #1
+               b       .Lcfu_finished
+
+.Lcfu_not_enough:
+               movs    ip, r2
+               bne     .Lcfu_nowords
+.Lcfu_finished:        mov     r0, #0
+               add     sp, sp, #8
+               ldmfd   sp!, {r4 - r7, pc}
+
+.Lcfu_src_not_aligned:
+               bic     r1, r1, #3
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
+               cmp     ip, #2
+               bgt     .Lcfu_3fupi
+               beq     .Lcfu_2fupi
+.Lcfu_1fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lcfu_1nowords
+               mov     r3, r7, pull #8
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
+               orr     r3, r3, r7, push #24
+               str     r3, [r0], #4
+               mov     ip, r1, lsl #32 - PAGE_SHIFT
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lcfu_1fupi
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #16
+               blt     .Lcfu_1rem8lp
+
+.Lcfu_1cpy8lp: mov     r3, r7, pull #8
+               ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
+               subs    ip, ip, #16
+               orr     r3, r3, r4, push #24
+               mov     r4, r4, pull #8
+               orr     r4, r4, r5, push #24
+               mov     r5, r5, pull #8
+               orr     r5, r5, r6, push #24
+               mov     r6, r6, pull #8
+               orr     r6, r6, r7, push #24
+               stmia   r0!, {r3 - r6}
+               bpl     .Lcfu_1cpy8lp
+
+.Lcfu_1rem8lp: tst     ip, #8
+               movne   r3, r7, pull #8
+               ldmneia r1!, {r4, r7}                   @ Shouldnt fault
+               orrne   r3, r3, r4, push #24
+               movne   r4, r4, pull #8
+               orrne   r4, r4, r7, push #24
+               stmneia r0!, {r3 - r4}
+               tst     ip, #4
+               movne   r3, r7, pull #8
+USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
+               orrne   r3, r3, r7, push #24
+               strne   r3, [r0], #4
+               ands    ip, ip, #3
+               beq     .Lcfu_1fupi
+.Lcfu_1nowords:        mov     r3, r7, get_byte_1
+               teq     ip, #0
+               beq     .Lcfu_finished
+               cmp     ip, #2
+               strb    r3, [r0], #1
+               movge   r3, r7, get_byte_2
+               strgeb  r3, [r0], #1
+               movgt   r3, r7, get_byte_3
+               strgtb  r3, [r0], #1
+               b       .Lcfu_finished
+
+.Lcfu_2fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lcfu_2nowords
+               mov     r3, r7, pull #16
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
+               orr     r3, r3, r7, push #16
+               str     r3, [r0], #4
+               mov     ip, r1, lsl #32 - PAGE_SHIFT
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lcfu_2fupi
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #16
+               blt     .Lcfu_2rem8lp
+
+
+.Lcfu_2cpy8lp: mov     r3, r7, pull #16
+               ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
+               subs    ip, ip, #16
+               orr     r3, r3, r4, push #16
+               mov     r4, r4, pull #16
+               orr     r4, r4, r5, push #16
+               mov     r5, r5, pull #16
+               orr     r5, r5, r6, push #16
+               mov     r6, r6, pull #16
+               orr     r6, r6, r7, push #16
+               stmia   r0!, {r3 - r6}
+               bpl     .Lcfu_2cpy8lp
+
+.Lcfu_2rem8lp: tst     ip, #8
+               movne   r3, r7, pull #16
+               ldmneia r1!, {r4, r7}                   @ Shouldnt fault
+               orrne   r3, r3, r4, push #16
+               movne   r4, r4, pull #16
+               orrne   r4, r4, r7, push #16
+               stmneia r0!, {r3 - r4}
+               tst     ip, #4
+               movne   r3, r7, pull #16
+USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
+               orrne   r3, r3, r7, push #16
+               strne   r3, [r0], #4
+               ands    ip, ip, #3
+               beq     .Lcfu_2fupi
+.Lcfu_2nowords:        mov     r3, r7, get_byte_2
+               teq     ip, #0
+               beq     .Lcfu_finished
+               cmp     ip, #2
+               strb    r3, [r0], #1
+               movge   r3, r7, get_byte_3
+               strgeb  r3, [r0], #1
+USER(  TUSER(  ldrgtb) r3, [r1], #0)                   @ May fault
+               strgtb  r3, [r0], #1
+               b       .Lcfu_finished
+
+.Lcfu_3fupi:   subs    r2, r2, #4
+               addmi   ip, r2, #4
+               bmi     .Lcfu_3nowords
+               mov     r3, r7, pull #24
+USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
+               orr     r3, r3, r7, push #8
+               str     r3, [r0], #4
+               mov     ip, r1, lsl #32 - PAGE_SHIFT
+               rsb     ip, ip, #0
+               movs    ip, ip, lsr #32 - PAGE_SHIFT
+               beq     .Lcfu_3fupi
+               cmp     r2, ip
+               movlt   ip, r2
+               sub     r2, r2, ip
+               subs    ip, ip, #16
+               blt     .Lcfu_3rem8lp
+
+.Lcfu_3cpy8lp: mov     r3, r7, pull #24
+               ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
+               orr     r3, r3, r4, push #8
+               mov     r4, r4, pull #24
+               orr     r4, r4, r5, push #8
+               mov     r5, r5, pull #24
+               orr     r5, r5, r6, push #8
+               mov     r6, r6, pull #24
+               orr     r6, r6, r7, push #8
+               stmia   r0!, {r3 - r6}
+               subs    ip, ip, #16
+               bpl     .Lcfu_3cpy8lp
+
+.Lcfu_3rem8lp: tst     ip, #8
+               movne   r3, r7, pull #24
+               ldmneia r1!, {r4, r7}                   @ Shouldnt fault
+               orrne   r3, r3, r4, push #8
+               movne   r4, r4, pull #24
+               orrne   r4, r4, r7, push #8
+               stmneia r0!, {r3 - r4}
+               tst     ip, #4
+               movne   r3, r7, pull #24
+USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
+               orrne   r3, r3, r7, push #8
+               strne   r3, [r0], #4
+               ands    ip, ip, #3
+               beq     .Lcfu_3fupi
+.Lcfu_3nowords:        mov     r3, r7, get_byte_3
+               teq     ip, #0
+               beq     .Lcfu_finished
+               cmp     ip, #2
+               strb    r3, [r0], #1
+USER(  TUSER(  ldrgeb) r3, [r1], #1)                   @ May fault
+               strgeb  r3, [r0], #1
+USER(  TUSER(  ldrgtb) r3, [r1], #1)                   @ May fault
+               strgtb  r3, [r0], #1
+               b       .Lcfu_finished
+ENDPROC(__copy_from_user)
+
+               .pushsection .fixup,"ax"
+               .align  0
+               /*
+                * We took an exception.  r0 contains a pointer to
+                * the byte not copied.
+                */
+9001:          ldr     r2, [sp], #4                    @ void *to
+               sub     r2, r0, r2                      @ bytes copied
+               ldr     r1, [sp], #4                    @ unsigned long count
+               subs    r4, r1, r2                      @ bytes left to copy
+               movne   r1, r4
+               blne    __memzero
+               mov     r0, r4
+               ldmfd   sp!, {r4 - r7, pc}
+               .popsection
+
index 5de69f2fcca9fec965fc300b506056c4a1f29e01..f6b9fc70161b43338772a9f092b589aecfb021df 100644 (file)
@@ -162,38 +162,6 @@ static void __init davinci_ntosd2_map_io(void)
        dm644x_init();
 }
 
-/*
- I2C initialization
-*/
-static struct davinci_i2c_platform_data ntosd2_i2c_pdata = {
-       .bus_freq       = 20 /* kHz */,
-       .bus_delay      = 100 /* usec */,
-};
-
-static struct i2c_board_info __initdata ntosd2_i2c_info[] =  {
-};
-
-static int ntosd2_init_i2c(void)
-{
-       int     status;
-
-       davinci_init_i2c(&ntosd2_i2c_pdata);
-       status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type);
-       if (status == 0) {
-               status = gpio_direction_input(NTOSD2_MSP430_IRQ);
-               if (status == 0) {
-                       status = gpio_to_irq(NTOSD2_MSP430_IRQ);
-                       if (status > 0) {
-                               ntosd2_i2c_info[0].irq = status;
-                               i2c_register_board_info(1,
-                                       ntosd2_i2c_info,
-                                       ARRAY_SIZE(ntosd2_i2c_info));
-                       }
-               }
-       }
-       return status;
-}
-
 static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
        .wires          = 4,
        .version        = MMC_CTLR_VERSION_1
@@ -218,7 +186,6 @@ static __init void davinci_ntosd2_init(void)
 {
        struct clk *aemif_clk;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
-       int     status;
 
        aemif_clk = clk_get(NULL, "aemif");
        clk_enable(aemif_clk);
@@ -242,12 +209,6 @@ static __init void davinci_ntosd2_init(void)
        platform_add_devices(davinci_ntosd2_devices,
                                ARRAY_SIZE(davinci_ntosd2_devices));
 
-       /* Initialize I2C interface specific for this board */
-       status = ntosd2_init_i2c();
-       if (status < 0)
-               pr_warning("davinci_ntosd2_init: msp430 irq setup failed:"
-                                               "        %d\n", status);
-
        davinci_serial_init(&uart_config);
        dm644x_init_asp(&dm644x_ntosd2_snd_data);
 
index 4db5de54b6a7e1658639dc8888a79ec8cede8cc7..6321567d8eaa0c97a3cdaba3fe2664cf7a1ece6c 100644 (file)
@@ -102,7 +102,8 @@ void __init dove_ehci1_init(void)
 void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 {
        orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE,
-                       IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR);
+                       IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR,
+                       1600);
 }
 
 /*****************************************************************************
index 5ca80307d6d7789c9fe1781dd6d56658f64f72e5..4e574c24581ca2869fa37f96d487879ffe0c016a 100644 (file)
@@ -42,6 +42,7 @@
 #include <plat/backlight.h>
 #include <plat/fb.h>
 #include <plat/mfc.h>
+#include <plat/hdmi.h>
 
 #include <mach/ohci.h>
 #include <mach/map.h>
@@ -734,6 +735,11 @@ static void __init origen_bt_setup(void)
        s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE);
 }
 
+/* I2C module and id for HDMIPHY */
+static struct i2c_board_info hdmiphy_info = {
+       I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38),
+};
+
 static void s5p_tv_setup(void)
 {
        /* Direct HPD to HDMI chip */
@@ -781,6 +787,7 @@ static void __init origen_machine_init(void)
 
        s5p_tv_setup();
        s5p_i2c_hdmiphy_set_platdata(NULL);
+       s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0);
 
 #ifdef CONFIG_DRM_EXYNOS
        s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata;
index 3cfa688d274a8bda5b5657924509d9d0726f41f6..73f2bce097e179822d9a08d4dc14bba6f104888c 100644 (file)
@@ -40,6 +40,7 @@
 #include <plat/mfc.h>
 #include <plat/ehci.h>
 #include <plat/clock.h>
+#include <plat/hdmi.h>
 
 #include <mach/map.h>
 #include <mach/ohci.h>
@@ -354,6 +355,11 @@ static struct platform_pwm_backlight_data smdkv310_bl_data = {
        .pwm_period_ns  = 1000,
 };
 
+/* I2C module and id for HDMIPHY */
+static struct i2c_board_info hdmiphy_info = {
+       I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38),
+};
+
 static void s5p_tv_setup(void)
 {
        /* direct HPD to HDMI chip */
@@ -388,6 +394,7 @@ static void __init smdkv310_machine_init(void)
 
        s5p_tv_setup();
        s5p_i2c_hdmiphy_set_platdata(NULL);
+       s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0);
 
        samsung_keypad_set_platdata(&smdkv310_keypad_data);
 
index 373c3c00d24cdbbe054a1aae60625d97188e6208..c0bc83a7663ee5877edfc0ff768b63a1ed1a2e30 100644 (file)
@@ -115,7 +115,7 @@ static __init int exynos_pm_dt_parse_domains(void)
 }
 #endif /* CONFIG_OF */
 
-static __init void exynos_pm_add_dev_to_genpd(struct platform_device *pdev,
+static __init __maybe_unused void exynos_pm_add_dev_to_genpd(struct platform_device *pdev,
                                                struct exynos_pm_domain *pd)
 {
        if (pdev->dev.bus) {
index 07f7c226e4cfe6eec6181e5e506655223c2f1e1a..d004d37ad9d8595648dbbf981e56391e58432eda 100644 (file)
@@ -9,7 +9,8 @@ obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
 obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
 obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
 
-obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
+imx5-pm-$(CONFIG_PM) += pm-imx5.o
+obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) cpu_op-mx51.o
 
 obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
                            clk-pfd.o clk-busy.o
@@ -70,14 +71,13 @@ obj-$(CONFIG_DEBUG_LL) += lluart.o
 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
 obj-$(CONFIG_HAVE_IMX_SRC) += src.o
-obj-$(CONFIG_CPU_V7) += head-v7.o
-AFLAGS_head-v7.o :=-Wa,-march=armv7-a
-obj-$(CONFIG_SMP) += platsmp.o
+AFLAGS_headsmp.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
 
 ifeq ($(CONFIG_PM),y)
-obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
+obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
 endif
 
 # i.MX5 based machines
index 7aa6313fb1671bbf975d6cf6407aad3ecee66498..f69ca4680049dd9f253e30eec5fc1690569f8d0d 100644 (file)
@@ -223,7 +223,7 @@ int __init mx27_clocks_init(unsigned long fref)
        clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0");
        clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
        clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0");
-       clk_register_clkdev(clk[csi_ahb_gate], NULL, "mx2-camera.0");
+       clk_register_clkdev(clk[csi_ahb_gate], "ahb", "mx2-camera.0");
        clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
        clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
        clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
@@ -250,8 +250,10 @@ int __init mx27_clocks_init(unsigned long fref)
        clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1");
        clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0");
        clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad");
-       clk_register_clkdev(clk[emma_ahb_gate], "ahb", "imx-emma");
-       clk_register_clkdev(clk[emma_ipg_gate], "ipg", "imx-emma");
+       clk_register_clkdev(clk[emma_ahb_gate], "emma-ahb", "mx2-camera.0");
+       clk_register_clkdev(clk[emma_ipg_gate], "emma-ipg", "mx2-camera.0");
+       clk_register_clkdev(clk[emma_ahb_gate], "ahb", "m2m-emmaprp.0");
+       clk_register_clkdev(clk[emma_ipg_gate], "ipg", "m2m-emmaprp.0");
        clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL);
        clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL);
        clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL);
index 8e19e70f90f97f121b6379945ebeadc2ae2284ab..1253af2d99715a63f157a9f838230895006d9323 100644 (file)
@@ -130,7 +130,7 @@ int __init mx31_clocks_init(unsigned long fref)
        clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0");
        clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
        clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
-       clk_register_clkdev(clk[kpp_gate], "kpp", NULL);
+       clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
        clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0");
        clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0");
        clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
index f6086693ebd2aa665e29fc7a5d5623caeb0d3d53..4bdcaa97bd9803be209f5deed8b771a4b21094d6 100644 (file)
@@ -303,6 +303,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
        clk_prepare_enable(clk[aips_tz2]); /* fec */
        clk_prepare_enable(clk[spba]);
        clk_prepare_enable(clk[emi_fast_gate]); /* fec */
+       clk_prepare_enable(clk[emi_slow_gate]); /* eim */
        clk_prepare_enable(clk[tmax1]);
        clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */
        clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */
index ea89520b6e223fd3ab4db3227574c7299605e265..4233d9e3531d838e3cad29c9d2dceb012606d378 100644 (file)
@@ -152,7 +152,7 @@ enum mx6q_clks {
        ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3,
        usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
        pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg,
-       ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2,
+       ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
        clk_max
 };
 
@@ -288,8 +288,10 @@ int __init mx6q_clocks_init(void)
        clk[gpu3d_shader]     = imx_clk_divider("gpu3d_shader",     "gpu3d_shader_sel",  base + 0x18, 29, 3);
        clk[ipu1_podf]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          base + 0x3c, 11, 3);
        clk[ipu2_podf]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          base + 0x3c, 16, 3);
-       clk[ldb_di0_podf]     = imx_clk_divider("ldb_di0_podf",     "ldb_di0_sel",       base + 0x20, 10, 1);
-       clk[ldb_di1_podf]     = imx_clk_divider("ldb_di1_podf",     "ldb_di1_sel",       base + 0x20, 11, 1);
+       clk[ldb_di0_div_3_5]  = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+       clk[ldb_di0_podf]     = imx_clk_divider("ldb_di0_podf",     "ldb_di0_div_3_5",       base + 0x20, 10, 1);
+       clk[ldb_di1_div_3_5]  = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+       clk[ldb_di1_podf]     = imx_clk_divider("ldb_di1_podf",     "ldb_di1_div_3_5",   base + 0x20, 11, 1);
        clk[ipu1_di0_pre]     = imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  base + 0x34, 3,  3);
        clk[ipu1_di1_pre]     = imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  base + 0x34, 12, 3);
        clk[ipu2_di0_pre]     = imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  base + 0x38, 3,  3);
index 20ed2d56c1af6a3109ff3ea10843cda25d2a289e..f8f7437c83b82dbb07307e78895e66bb6af320e6 100644 (file)
@@ -42,22 +42,6 @@ static inline void cpu_enter_lowpower(void)
          : "cc");
 }
 
-static inline void cpu_leave_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile(
-               "mrc    p15, 0, %0, c1, c0, 0\n"
-       "       orr     %0, %0, %1\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       orr     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-         : "=&r" (v)
-         : "Ir" (CR_C), "Ir" (0x40)
-         : "cc");
-}
-
 /*
  * platform-specific code to shutdown a CPU
  *
@@ -67,11 +51,10 @@ void platform_cpu_die(unsigned int cpu)
 {
        cpu_enter_lowpower();
        imx_enable_cpu(cpu, false);
-       cpu_do_idle();
-       cpu_leave_lowpower();
 
-       /* We should never return from idle */
-       panic("cpu %d unexpectedly exit from shutdown\n", cpu);
+       /* spin here until hardware takes it down */
+       while (1)
+               ;
 }
 
 int platform_cpu_disable(unsigned int cpu)
index 5ec0608f2a764a9be584ea1bebbe1339f981a259..045b3f6a387dadef095f2900dc5b786464b525fa 100644 (file)
@@ -71,7 +71,7 @@ soft:
 /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
 static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 {
-       if (IS_ENABLED(CONFIG_PHYLIB)) {
+       if (IS_BUILTIN(CONFIG_PHYLIB)) {
                /* min rx data delay */
                phy_write(phydev, 0x0b, 0x8105);
                phy_write(phydev, 0x0c, 0x0000);
@@ -112,7 +112,7 @@ put_clk:
 
 static void __init imx6q_sabrelite_init(void)
 {
-       if (IS_ENABLED(CONFIG_PHYLIB))
+       if (IS_BUILTIN(CONFIG_PHYLIB))
                phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
                                ksz9021rn_phy_fixup);
        imx6q_sabrelite_cko1_setup();
index 208c05d9e68564c354f356c40c599813398494de..2af5034ea29e5eb69a611040089949f255e8e04c 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
index 7b1055c8e0b98c6619473ca4bca9cd711ccc316c..3b2267529f5e308cc1c47c048375ffedd5a60f9a 100644 (file)
@@ -456,7 +456,7 @@ static void __init ap_init_timer(void)
 
        clk = clk_get_sys("ap_timer", NULL);
        BUG_ON(IS_ERR(clk));
-       clk_enable(clk);
+       clk_prepare_enable(clk);
        rate = clk_get_rate(clk);
 
        writel(0, TIMER0_VA_BASE + TIMER_CTRL);
index 2a576abf409bd0323c64e0cac807d0f609e2135a..a13299d758e15540cfd6fef81b399efbe53d1691 100644 (file)
@@ -7,7 +7,8 @@ dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb
 dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb
 dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb
 dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb
-dtb-$(CONFIG_MACH_TS219_DT)    += kirkwood-qnap-ts219.dtb
+dtb-$(CONFIG_MACH_TS219_DT)    += kirkwood-ts219-6281.dtb
+dtb-$(CONFIG_MACH_TS219_DT)    += kirkwood-ts219-6282.dtb
 dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb
-dbt-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb
-dbt-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb
+dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb
+dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb
index c4b64adcbfce4be58c7a9b149df9e33d19e02e51..3226077735b1d7104627f8f40307e84c97d4ca5b 100644 (file)
@@ -301,7 +301,7 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 {
        orion_ge00_init(eth_data,
                        GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
-                       IRQ_KIRKWOOD_GE00_ERR);
+                       IRQ_KIRKWOOD_GE00_ERR, 1600);
        /* The interface forgets the MAC address assigned by u-boot if
        the clock is turned off, so claim the clk now. */
        clk_prepare_enable(ge0);
@@ -315,7 +315,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 {
        orion_ge01_init(eth_data,
                        GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
-                       IRQ_KIRKWOOD_GE01_ERR);
+                       IRQ_KIRKWOOD_GE01_ERR, 1600);
        clk_prepare_enable(ge1);
 }
 
index 4304f9519372d972c1d798a5c7a9aa33d3dce954..7e8a5a2e1ec7c210aaf2212d10b32905cebda72b 100644 (file)
@@ -68,7 +68,7 @@ static int __devinit sram_probe(struct platform_device *pdev)
        struct resource *res;
        int ret = 0;
 
-       if (!pdata && !pdata->pool_name)
+       if (!pdata || !pdata->pool_name)
                return -ENODEV;
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
index 62b53d710efde1a0a71095b2e9e54186cb454886..a9bc84180d21fb378ff27eafb32bcb2ea81f2e89 100644 (file)
@@ -37,7 +37,7 @@
 #define WIN0_OFF(n)            (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
 #define WIN8_OFF(n)            (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
 
-static void __init __iomem *win_cfg_base(int win)
+static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
 {
        /*
         * Find the control register base address for this window.
index b4c53b846c9caa8402ce764aec9f9f254379031a..3057f7d4329a7f3a17b247e5ce31df4e7f21643a 100644 (file)
@@ -213,7 +213,8 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 {
        orion_ge00_init(eth_data,
                        GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
-                       IRQ_MV78XX0_GE_ERR);
+                       IRQ_MV78XX0_GE_ERR,
+                       MV643XX_TX_CSUM_DEFAULT_LIMIT);
 }
 
 
@@ -224,7 +225,8 @@ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 {
        orion_ge01_init(eth_data,
                        GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
-                       NO_IRQ);
+                       NO_IRQ,
+                       MV643XX_TX_CSUM_DEFAULT_LIMIT);
 }
 
 
index ccdf83b17cf16030612bdf62c43711f7f926baa6..9a8bbda195b28a2b64e19a01d052990a2d6f1156 100644 (file)
@@ -2,9 +2,6 @@ if ARCH_MXS
 
 source "arch/arm/mach-mxs/devices/Kconfig"
 
-config MXS_OCOTP
-       bool
-
 config SOC_IMX23
        bool
        select ARM_AMBA
@@ -66,7 +63,6 @@ config MACH_MX28EVK
        select MXS_HAVE_PLATFORM_MXS_SAIF
        select MXS_HAVE_PLATFORM_MXS_I2C
        select MXS_HAVE_PLATFORM_RTC_STMP3XXX
-       select MXS_OCOTP
        help
          Include support for MX28EVK platform. This includes specific
          configurations for the board and its peripherals.
@@ -94,7 +90,6 @@ config MODULE_M28
        select MXS_HAVE_PLATFORM_MXS_I2C
        select MXS_HAVE_PLATFORM_MXS_MMC
        select MXS_HAVE_PLATFORM_MXSFB
-       select MXS_OCOTP
 
 config MODULE_APX4
        bool
@@ -106,7 +101,6 @@ config MODULE_APX4
        select MXS_HAVE_PLATFORM_MXS_I2C
        select MXS_HAVE_PLATFORM_MXS_MMC
        select MXS_HAVE_PLATFORM_MXS_SAIF
-       select MXS_OCOTP
 
 config MACH_TX28
        bool "Ka-Ro TX28 module"
index e41590ccb437feb62a0a9154778d91a700185521..fed3695a1339d89c754edb10ae382730429625b8 100644 (file)
@@ -1,7 +1,6 @@
 # Common support
-obj-y := devices.o icoll.o iomux.o system.o timer.o mm.o
+obj-y := devices.o icoll.o iomux.o ocotp.o system.o timer.o mm.o
 
-obj-$(CONFIG_MXS_OCOTP) += ocotp.o
 obj-$(CONFIG_PM) += pm.o
 
 obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o
index dd2db025f7787e590d94bb229cb143559f9a8317..fcd4e85c4ddcce66921a83b29e45669c50704918 100644 (file)
@@ -62,13 +62,14 @@ config ARCH_OMAP4
        select PM_OPP if PM
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
        select ARM_CPU_SUSPEND if PM
-       select ARCH_NEEDS_CPU_IDLE_COUPLED
+       select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
 
 config SOC_OMAP5
        bool "TI OMAP5"
        select CPU_V7
        select ARM_GIC
        select HAVE_SMP
+       select ARM_CPU_SUSPEND if PM
 
 comment "OMAP Core Type"
        depends on ARCH_OMAP2
index 74915295482ec849e0d0fefe5fc9a22703ee1f2c..28214483aaba24420e96fde47cf5ce91482a0d29 100644 (file)
@@ -554,6 +554,8 @@ static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = {
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+       /* SMSC9221 LAN Controller ETH IRQ (GPIO_176) */
+       OMAP3_MUX(MCSPI1_CS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #endif
index ef230a0eb5eb13e5cedde6f0a6c540f6a348eae6..0d362e9f9cb9a9854c32b378c5dd058f2f785327 100644 (file)
@@ -58,6 +58,7 @@
 #include "hsmmc.h"
 #include "common-board-devices.h"
 
+#define OMAP3_EVM_TS_GPIO      175
 #define OMAP3_EVM_EHCI_VBUS    22
 #define OMAP3_EVM_EHCI_SELECT  61
 
index 14734746457c2bd8bdfcabd1ea4681dc4edab36e..c1875862679fc7092044644bf83e6948ecdbe4c8 100644 (file)
@@ -35,16 +35,6 @@ static struct omap2_mcspi_device_config ads7846_mcspi_config = {
        .turbo_mode     = 0,
 };
 
-/*
- * ADS7846 driver maybe request a gpio according to the value
- * of pdata->get_pendown_state, but we have done this. So set
- * get_pendown_state to avoid twice gpio requesting.
- */
-static int omap3_get_pendown_state(void)
-{
-       return !gpio_get_value(OMAP3_EVM_TS_GPIO);
-}
-
 static struct ads7846_platform_data ads7846_config = {
        .x_max                  = 0x0fff,
        .y_max                  = 0x0fff,
@@ -55,7 +45,6 @@ static struct ads7846_platform_data ads7846_config = {
        .debounce_rep           = 1,
        .gpio_pendown           = -EINVAL,
        .keep_vref_on           = 1,
-       .get_pendown_state      = &omap3_get_pendown_state,
 };
 
 static struct spi_board_info ads7846_spi_board_info __initdata = {
index 4c4ef6a6166ba28b768ee46580b7f35dbafb7885..a0b4a42836ab9f7a29f1757ee410e37a237af00c 100644 (file)
@@ -4,7 +4,6 @@
 #include "twl-common.h"
 
 #define NAND_BLOCK_SIZE        SZ_128K
-#define OMAP3_EVM_TS_GPIO      175
 
 struct mtd_partition;
 struct ads7846_platform_data;
index ee05e193fc61e317b21b368c583f31ce71bbb76b..288bee6cbb76f701b9b675476d87c3b8f16b90cb 100644 (file)
@@ -238,8 +238,9 @@ int __init omap4_idle_init(void)
        for_each_cpu(cpu_id, cpu_online_mask) {
                dev = &per_cpu(omap4_idle_dev, cpu_id);
                dev->cpu = cpu_id;
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
                dev->coupled_cpus = *cpu_online_mask;
-
+#endif
                cpuidle_register_driver(&omap4_idle_driver);
 
                if (cpuidle_register_device(dev)) {
index 471e62a74a166fb64a7486670a54854239cfb3b6..76f9b3c2f586c577668d7f923f0aabff7bbd53a3 100644 (file)
@@ -127,7 +127,6 @@ struct omap_mux_partition {
  * @gpio:      GPIO number
  * @muxnames:  available signal modes for a ball
  * @balls:     available balls on the package
- * @partition: mux partition
  */
 struct omap_mux {
        u16     reg_offset;
index 2293ba27101b96fae1f387d5b366c5d77181f99b..c95415da23c275b184d2817372a990a371ddaf0c 100644 (file)
@@ -94,7 +94,7 @@ int __init omap4_opp_init(void)
 {
        int r = -ENODEV;
 
-       if (!cpu_is_omap44xx())
+       if (!cpu_is_omap443x())
                return r;
 
        r = omap_init_opp_table(omap44xx_opp_def_list,
index e4fc88c65dbd6a868b6dac07229de3ee3b7791ea..05bd8f02723f2966bfc559ae30b9c33feee9feb3 100644 (file)
@@ -272,21 +272,16 @@ void omap_sram_idle(void)
        per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
        core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
 
-       if (mpu_next_state < PWRDM_POWER_ON) {
-               pwrdm_pre_transition(mpu_pwrdm);
-               pwrdm_pre_transition(neon_pwrdm);
-       }
+       pwrdm_pre_transition(NULL);
 
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
-               pwrdm_pre_transition(per_pwrdm);
                per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
                omap2_gpio_prepare_for_idle(per_going_off);
        }
 
        /* CORE */
        if (core_next_state < PWRDM_POWER_ON) {
-               pwrdm_pre_transition(core_pwrdm);
                if (core_next_state == PWRDM_POWER_OFF) {
                        omap3_core_save_context();
                        omap3_cm_save_context();
@@ -339,20 +334,14 @@ void omap_sram_idle(void)
                        omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
                                               OMAP3430_GR_MOD,
                                               OMAP3_PRM_VOLTCTRL_OFFSET);
-               pwrdm_post_transition(core_pwrdm);
        }
        omap3_intc_resume_idle();
 
+       pwrdm_post_transition(NULL);
+
        /* PER */
-       if (per_next_state < PWRDM_POWER_ON) {
+       if (per_next_state < PWRDM_POWER_ON)
                omap2_gpio_resume_after_idle();
-               pwrdm_post_transition(per_pwrdm);
-       }
-
-       if (mpu_next_state < PWRDM_POWER_ON) {
-               pwrdm_post_transition(mpu_pwrdm);
-               pwrdm_post_transition(neon_pwrdm);
-       }
 }
 
 static void omap3_pm_idle(void)
index 9f6b83d1b193348a7af9e628cff41956c8684898..91e71d8f46f0aa731c9678e88423490aa1192cf9 100644 (file)
@@ -56,9 +56,13 @@ ppa_por_params:
  * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
  * It returns to the caller for CPU INACTIVE and ON power states or in case
  * CPU failed to transition to targeted OFF/DORMANT state.
+ *
+ * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save
+ * stack frame and it expects the caller to take care of it. Hence the entire
+ * stack frame is saved to avoid possible stack corruption.
  */
 ENTRY(omap4_finish_suspend)
-       stmfd   sp!, {lr}
+       stmfd   sp!, {r4-r12, lr}
        cmp     r0, #0x0
        beq     do_WFI                          @ No lowpower state, jump to WFI
 
@@ -226,7 +230,7 @@ scu_gp_clear:
 skip_scu_gp_clear:
        isb
        dsb
-       ldmfd   sp!, {pc}
+       ldmfd   sp!, {r4-r12, pc}
 ENDPROC(omap4_finish_suspend)
 
 /*
index de47f170ba50abf2506c363838d7cd82c70109ee..db5ff664237517562766ffdbc34887c6416c272f 100644 (file)
@@ -67,6 +67,7 @@ void __init omap_pmic_init(int bus, u32 clkrate,
                           const char *pmic_type, int pmic_irq,
                           struct twl4030_platform_data *pmic_data)
 {
+       omap_mux_init_signal("sys_nirq", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
        strncpy(pmic_i2c_board_info.type, pmic_type,
                sizeof(pmic_i2c_board_info.type));
        pmic_i2c_board_info.irq = pmic_irq;
index 9148b229d0de925b4f95fea5154421fa462331ba..410291c676668befcfe5b43723af071ba153e5db 100644 (file)
@@ -109,7 +109,8 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
 {
        orion_ge00_init(eth_data,
                        ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
-                       IRQ_ORION5X_ETH_ERR);
+                       IRQ_ORION5X_ETH_ERR,
+                       MV643XX_TX_CSUM_DEFAULT_LIMIT);
 }
 
 
index 5905ed130e94200abe59867d0b916e718cedae98..d89d87ae144cc77d2e71e1efe470761544573e3d 100644 (file)
@@ -953,12 +953,12 @@ static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = {
 
 static struct eeti_ts_platform_data eeti_ts_pdata = {
        .irq_active_high = 1,
+       .irq_gpio = GPIO_TOUCH_IRQ,
 };
 
 static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = {
        .type   = "eeti_ts",
        .addr   = 0x0a,
-       .irq    = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ),
        .platform_data = &eeti_ts_pdata,
 };
 
index e24961109b70286655c36c46a3083809511870c5..d56b0f7f2b202a0aaea0b36435328ff15b8c783f 100644 (file)
@@ -483,7 +483,7 @@ config MACH_NEO1973_GTA02
        select I2C
        select POWER_SUPPLY
        select MACH_NEO1973
-       select S3C2410_PWM
+       select S3C24XX_PWM
        select S3C_DEV_USB_HOST
        help
           Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
@@ -493,7 +493,7 @@ config MACH_RX1950
        select S3C24XX_DCLK
        select PM_H1940 if PM
        select I2C
-       select S3C2410_PWM
+       select S3C24XX_PWM
        select S3C_DEV_NAND
        select S3C2410_IOTIMING if S3C2440_CPUFREQ
        select S3C2440_XTAL_16934400
index 454831b66037f9c64d37521bf14e118dcc92bc9a..ee99fd56c0439f5bdc22152fa2c530282424fd70 100644 (file)
@@ -24,7 +24,8 @@
 */
 
 enum dma_ch {
-       DMACH_XD0,
+       DMACH_DT_PROP = -1,     /* not yet supported, do not use */
+       DMACH_XD0 = 0,
        DMACH_XD1,
        DMACH_SDI,
        DMACH_SPI0,
index c3d7303b9ac8f07a662e25739c6362a8e7ee4fd8..f07f99452a98ade3298334045a4d39baed4318b8 100644 (file)
@@ -12,9 +12,11 @@ obj-y                                        += powergate.o
 obj-y                                  += apbio.o
 obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
 obj-$(CONFIG_CPU_IDLE)                 += sleep.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_clocks.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks_data.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra2_emc.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += tegra30_clocks.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += tegra30_clocks_data.o
 obj-$(CONFIG_SMP)                      += platsmp.o headsmp.o
 obj-$(CONFIG_SMP)                       += reset.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
index c0999633a9ab24054a2c5e2cc9d526c020320b8c..b4e7cc14713cb0e2c0a9d4de05db4622aac943bc 100644 (file)
@@ -71,6 +71,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
 
 static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
        /* name         parent          rate            enabled */
+       { "uarta",      "pll_p",        216000000,      true },
        { "uartd",      "pll_p",        216000000,      true },
        { "usbd",       "clk_m",        12000000,       false },
        { "usb2",       "clk_m",        12000000,       false },
index 8fd387bf31f0c66a27b313d3b5edc8bd976e3d0a..b7344beec102b109d4d013b4db47a1ab56d90e42 100644 (file)
@@ -51,7 +51,7 @@ static struct regulator_init_data ldo0_data = {
        .consumer_supplies = tps658621_ldo0_supply,
 };
 
-#define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv)    \
+#define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv, _on)\
        static struct regulator_init_data _id##_data = {                \
                .supply_regulator = _supply,                            \
                .constraints = {                                        \
@@ -63,21 +63,22 @@ static struct regulator_init_data ldo0_data = {
                        .valid_ops_mask = (REGULATOR_CHANGE_MODE |      \
                                           REGULATOR_CHANGE_STATUS |    \
                                           REGULATOR_CHANGE_VOLTAGE),   \
+                       .always_on = _on,                               \
                },                                                      \
        }
 
-HARMONY_REGULATOR_INIT(sm0,  "vdd_sm0",  "vdd_sys", 725, 1500);
-HARMONY_REGULATOR_INIT(sm1,  "vdd_sm1",  "vdd_sys", 725, 1500);
-HARMONY_REGULATOR_INIT(sm2,  "vdd_sm2",  "vdd_sys", 3000, 4550);
-HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500);
-HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500);
-HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300);
-HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475);
-HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL,     1250, 3300);
-HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300);
-HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300);
-HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300);
-HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300);
+HARMONY_REGULATOR_INIT(sm0,  "vdd_sm0",  "vdd_sys", 725, 1500, 1);
+HARMONY_REGULATOR_INIT(sm1,  "vdd_sm1",  "vdd_sys", 725, 1500, 1);
+HARMONY_REGULATOR_INIT(sm2,  "vdd_sm2",  "vdd_sys", 3000, 4550, 1);
+HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500, 1);
+HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0);
+HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1);
+HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1);
+HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL,     1250, 3300, 1);
+HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0);
+HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0);
+HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0);
+HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300, 1);
 
 #define TPS_REG(_id, _data)                    \
        {                                       \
@@ -119,9 +120,10 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
 
 int __init harmony_regulator_init(void)
 {
+       regulator_register_always_on(0, "vdd_sys",
+               NULL, 0, 5000000);
+
        if (machine_is_harmony()) {
-               regulator_register_always_on(0, "vdd_sys",
-                       NULL, 0, 5000000);
                i2c_register_board_info(3, harmony_regulators, 1);
        } else { /* Harmony, booted using device tree */
                struct device_node *np;
index 58f981c0819c717883ae99c8d9d7d4c825ea1cae..632133fc985b4a91c571295fec0e3c83ef15be6e 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2012 NVIDIA CORPORATION.  All rights reserved.
  *
  * Author:
  *     Colin Cross <ccross@google.com>
@@ -19,8 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
 /*
  * Locking:
  *
- * Each struct clk has a spinlock.
- *
- * To avoid AB-BA locking problems, locks must always be traversed from child
- * clock to parent clock.  For example, when enabling a clock, the clock's lock
- * is taken, and then clk_enable is called on the parent, which take's the
- * parent clock's lock.  There is one exceptions to this ordering: When dumping
- * the clock tree through debugfs.  In this case, clk_lock_all is called,
- * which attemps to iterate through the entire list of clocks and take every
- * clock lock.  If any call to spin_trylock fails, all locked clocks are
- * unlocked, and the process is retried.  When all the locks are held,
- * the only clock operation that can be called is clk_get_rate_all_locked.
- *
- * Within a single clock, no clock operation can call another clock operation
- * on itself, except for clk_get_rate_locked and clk_set_rate_locked.  Any
- * clock operation can call any other clock operation on any of it's possible
- * parents.
- *
  * An additional mutex, clock_list_lock, is used to protect the list of all
  * clocks.
  *
- * The clock operations must lock internally to protect against
- * read-modify-write on registers that are shared by multiple clocks
  */
 static DEFINE_MUTEX(clock_list_lock);
 static LIST_HEAD(clocks);
 
-struct clk *tegra_get_clock_by_name(const char *name)
+void tegra_clk_add(struct clk *clk)
 {
-       struct clk *c;
-       struct clk *ret = NULL;
-       mutex_lock(&clock_list_lock);
-       list_for_each_entry(c, &clocks, node) {
-               if (strcmp(c->name, name) == 0) {
-                       ret = c;
-                       break;
-               }
-       }
-       mutex_unlock(&clock_list_lock);
-       return ret;
-}
-
-/* Must be called with c->spinlock held */
-static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
-{
-       u64 rate;
-
-       rate = clk_get_rate(p);
-
-       if (c->mul != 0 && c->div != 0) {
-               rate *= c->mul;
-               rate += c->div - 1; /* round up */
-               do_div(rate, c->div);
-       }
-
-       return rate;
-}
-
-/* Must be called with c->spinlock held */
-unsigned long clk_get_rate_locked(struct clk *c)
-{
-       unsigned long rate;
-
-       if (c->parent)
-               rate = clk_predict_rate_from_parent(c, c->parent);
-       else
-               rate = c->rate;
-
-       return rate;
-}
-
-unsigned long clk_get_rate(struct clk *c)
-{
-       unsigned long flags;
-       unsigned long rate;
-
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       rate = clk_get_rate_locked(c);
-
-       spin_unlock_irqrestore(&c->spinlock, flags);
-
-       return rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-int clk_reparent(struct clk *c, struct clk *parent)
-{
-       c->parent = parent;
-       return 0;
-}
-
-void clk_init(struct clk *c)
-{
-       spin_lock_init(&c->spinlock);
-
-       if (c->ops && c->ops->init)
-               c->ops->init(c);
-
-       if (!c->ops || !c->ops->enable) {
-               c->refcnt++;
-               c->set = true;
-               if (c->parent)
-                       c->state = c->parent->state;
-               else
-                       c->state = ON;
-       }
+       struct clk_tegra *c = to_clk_tegra(__clk_get_hw(clk));
 
        mutex_lock(&clock_list_lock);
        list_add(&c->node, &clocks);
        mutex_unlock(&clock_list_lock);
 }
 
-int clk_enable(struct clk *c)
-{
-       int ret = 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       if (c->refcnt == 0) {
-               if (c->parent) {
-                       ret = clk_enable(c->parent);
-                       if (ret)
-                               goto out;
-               }
-
-               if (c->ops && c->ops->enable) {
-                       ret = c->ops->enable(c);
-                       if (ret) {
-                               if (c->parent)
-                                       clk_disable(c->parent);
-                               goto out;
-                       }
-                       c->state = ON;
-                       c->set = true;
-               }
-       }
-       c->refcnt++;
-out:
-       spin_unlock_irqrestore(&c->spinlock, flags);
-       return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *c)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       if (c->refcnt == 0) {
-               WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
-               spin_unlock_irqrestore(&c->spinlock, flags);
-               return;
-       }
-       if (c->refcnt == 1) {
-               if (c->ops && c->ops->disable)
-                       c->ops->disable(c);
-
-               if (c->parent)
-                       clk_disable(c->parent);
-
-               c->state = OFF;
-       }
-       c->refcnt--;
-
-       spin_unlock_irqrestore(&c->spinlock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-int clk_set_parent(struct clk *c, struct clk *parent)
-{
-       int ret;
-       unsigned long flags;
-       unsigned long new_rate;
-       unsigned long old_rate;
-
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       if (!c->ops || !c->ops->set_parent) {
-               ret = -ENOSYS;
-               goto out;
-       }
-
-       new_rate = clk_predict_rate_from_parent(c, parent);
-       old_rate = clk_get_rate_locked(c);
-
-       ret = c->ops->set_parent(c, parent);
-       if (ret)
-               goto out;
-
-out:
-       spin_unlock_irqrestore(&c->spinlock, flags);
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *c)
-{
-       return c->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-int clk_set_rate_locked(struct clk *c, unsigned long rate)
-{
-       long new_rate;
-
-       if (!c->ops || !c->ops->set_rate)
-               return -ENOSYS;
-
-       if (rate > c->max_rate)
-               rate = c->max_rate;
-
-       if (c->ops && c->ops->round_rate) {
-               new_rate = c->ops->round_rate(c, rate);
-
-               if (new_rate < 0)
-                       return new_rate;
-
-               rate = new_rate;
-       }
-
-       return c->ops->set_rate(c, rate);
-}
-
-int clk_set_rate(struct clk *c, unsigned long rate)
-{
-       int ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       ret = clk_set_rate_locked(c, rate);
-
-       spin_unlock_irqrestore(&c->spinlock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-
-/* Must be called with clocks lock and all indvidual clock locks held */
-unsigned long clk_get_rate_all_locked(struct clk *c)
+struct clk *tegra_get_clock_by_name(const char *name)
 {
-       u64 rate;
-       int mul = 1;
-       int div = 1;
-       struct clk *p = c;
-
-       while (p) {
-               c = p;
-               if (c->mul != 0 && c->div != 0) {
-                       mul *= c->mul;
-                       div *= c->div;
+       struct clk_tegra *c;
+       struct clk *ret = NULL;
+       mutex_lock(&clock_list_lock);
+       list_for_each_entry(c, &clocks, node) {
+               if (strcmp(__clk_get_name(c->hw.clk), name) == 0) {
+                       ret = c->hw.clk;
+                       break;
                }
-               p = c->parent;
        }
-
-       rate = c->rate;
-       rate *= mul;
-       do_div(rate, div);
-
-       return rate;
-}
-
-long clk_round_rate(struct clk *c, unsigned long rate)
-{
-       unsigned long flags;
-       long ret;
-
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       if (!c->ops || !c->ops->round_rate) {
-               ret = -ENOSYS;
-               goto out;
-       }
-
-       if (rate > c->max_rate)
-               rate = c->max_rate;
-
-       ret = c->ops->round_rate(c, rate);
-
-out:
-       spin_unlock_irqrestore(&c->spinlock, flags);
+       mutex_unlock(&clock_list_lock);
        return ret;
 }
-EXPORT_SYMBOL(clk_round_rate);
 
 static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
 {
        struct clk *c;
        struct clk *p;
+       struct clk *parent;
 
        int ret = 0;
 
        c = tegra_get_clock_by_name(table->name);
 
        if (!c) {
-               pr_warning("Unable to initialize clock %s\n",
+               pr_warn("Unable to initialize clock %s\n",
                        table->name);
                return -ENODEV;
        }
 
+       parent = clk_get_parent(c);
+
        if (table->parent) {
                p = tegra_get_clock_by_name(table->parent);
                if (!p) {
-                       pr_warning("Unable to find parent %s of clock %s\n",
+                       pr_warn("Unable to find parent %s of clock %s\n",
                                table->parent, table->name);
                        return -ENODEV;
                }
 
-               if (c->parent != p) {
+               if (parent != p) {
                        ret = clk_set_parent(c, p);
                        if (ret) {
-                               pr_warning("Unable to set parent %s of clock %s: %d\n",
+                               pr_warn("Unable to set parent %s of clock %s: %d\n",
                                        table->parent, table->name, ret);
                                return -EINVAL;
                        }
@@ -360,16 +105,16 @@ static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
        if (table->rate && table->rate != clk_get_rate(c)) {
                ret = clk_set_rate(c, table->rate);
                if (ret) {
-                       pr_warning("Unable to set clock %s to rate %lu: %d\n",
+                       pr_warn("Unable to set clock %s to rate %lu: %d\n",
                                table->name, table->rate, ret);
                        return -EINVAL;
                }
        }
 
        if (table->enabled) {
-               ret = clk_enable(c);
+               ret = clk_prepare_enable(c);
                if (ret) {
-                       pr_warning("Unable to enable clock %s: %d\n",
+                       pr_warn("Unable to enable clock %s: %d\n",
                                table->name, ret);
                        return -EINVAL;
                }
@@ -383,19 +128,20 @@ void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
        for (; table->name; table++)
                tegra_clk_init_one_from_table(table);
 }
-EXPORT_SYMBOL(tegra_clk_init_from_table);
 
 void tegra_periph_reset_deassert(struct clk *c)
 {
-       BUG_ON(!c->ops->reset);
-       c->ops->reset(c, false);
+       struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
+       BUG_ON(!clk->reset);
+       clk->reset(__clk_get_hw(c), false);
 }
 EXPORT_SYMBOL(tegra_periph_reset_deassert);
 
 void tegra_periph_reset_assert(struct clk *c)
 {
-       BUG_ON(!c->ops->reset);
-       c->ops->reset(c, true);
+       struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
+       BUG_ON(!clk->reset);
+       clk->reset(__clk_get_hw(c), true);
 }
 EXPORT_SYMBOL(tegra_periph_reset_assert);
 
@@ -405,268 +151,14 @@ EXPORT_SYMBOL(tegra_periph_reset_assert);
 int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
 {
        int ret = 0;
-       unsigned long flags;
+       struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
 
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       if (!c->ops || !c->ops->clk_cfg_ex) {
+       if (!clk->clk_cfg_ex) {
                ret = -ENOSYS;
                goto out;
        }
-       ret = c->ops->clk_cfg_ex(c, p, setting);
+       ret = clk->clk_cfg_ex(__clk_get_hw(c), p, setting);
 
 out:
-       spin_unlock_irqrestore(&c->spinlock, flags);
-
        return ret;
 }
-
-#ifdef CONFIG_DEBUG_FS
-
-static int __clk_lock_all_spinlocks(void)
-{
-       struct clk *c;
-
-       list_for_each_entry(c, &clocks, node)
-               if (!spin_trylock(&c->spinlock))
-                       goto unlock_spinlocks;
-
-       return 0;
-
-unlock_spinlocks:
-       list_for_each_entry_continue_reverse(c, &clocks, node)
-               spin_unlock(&c->spinlock);
-
-       return -EAGAIN;
-}
-
-static void __clk_unlock_all_spinlocks(void)
-{
-       struct clk *c;
-
-       list_for_each_entry_reverse(c, &clocks, node)
-               spin_unlock(&c->spinlock);
-}
-
-/*
- * This function retries until it can take all locks, and may take
- * an arbitrarily long time to complete.
- * Must be called with irqs enabled, returns with irqs disabled
- * Must be called with clock_list_lock held
- */
-static void clk_lock_all(void)
-{
-       int ret;
-retry:
-       local_irq_disable();
-
-       ret = __clk_lock_all_spinlocks();
-       if (ret)
-               goto failed_spinlocks;
-
-       /* All locks taken successfully, return */
-       return;
-
-failed_spinlocks:
-       local_irq_enable();
-       yield();
-       goto retry;
-}
-
-/*
- * Unlocks all clocks after a clk_lock_all
- * Must be called with irqs disabled, returns with irqs enabled
- * Must be called with clock_list_lock held
- */
-static void clk_unlock_all(void)
-{
-       __clk_unlock_all_spinlocks();
-
-       local_irq_enable();
-}
-
-static struct dentry *clk_debugfs_root;
-
-
-static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
-{
-       struct clk *child;
-       const char *state = "uninit";
-       char div[8] = {0};
-
-       if (c->state == ON)
-               state = "on";
-       else if (c->state == OFF)
-               state = "off";
-
-       if (c->mul != 0 && c->div != 0) {
-               if (c->mul > c->div) {
-                       int mul = c->mul / c->div;
-                       int mul2 = (c->mul * 10 / c->div) % 10;
-                       int mul3 = (c->mul * 10) % c->div;
-                       if (mul2 == 0 && mul3 == 0)
-                               snprintf(div, sizeof(div), "x%d", mul);
-                       else if (mul3 == 0)
-                               snprintf(div, sizeof(div), "x%d.%d", mul, mul2);
-                       else
-                               snprintf(div, sizeof(div), "x%d.%d..", mul, mul2);
-               } else {
-                       snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
-                               (c->div % c->mul) ? ".5" : "");
-               }
-       }
-
-       seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n",
-               level * 3 + 1, "",
-               c->rate > c->max_rate ? '!' : ' ',
-               !c->set ? '*' : ' ',
-               30 - level * 3, c->name,
-               state, c->refcnt, div, clk_get_rate_all_locked(c));
-
-       list_for_each_entry(child, &clocks, node) {
-               if (child->parent != c)
-                       continue;
-
-               clock_tree_show_one(s, child, level + 1);
-       }
-}
-
-static int clock_tree_show(struct seq_file *s, void *data)
-{
-       struct clk *c;
-       seq_printf(s, "   clock                          state  ref div      rate\n");
-       seq_printf(s, "--------------------------------------------------------------\n");
-
-       mutex_lock(&clock_list_lock);
-
-       clk_lock_all();
-
-       list_for_each_entry(c, &clocks, node)
-               if (c->parent == NULL)
-                       clock_tree_show_one(s, c, 0);
-
-       clk_unlock_all();
-
-       mutex_unlock(&clock_list_lock);
-       return 0;
-}
-
-static int clock_tree_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, clock_tree_show, inode->i_private);
-}
-
-static const struct file_operations clock_tree_fops = {
-       .open           = clock_tree_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int possible_parents_show(struct seq_file *s, void *data)
-{
-       struct clk *c = s->private;
-       int i;
-
-       for (i = 0; c->inputs[i].input; i++) {
-               char *first = (i == 0) ? "" : " ";
-               seq_printf(s, "%s%s", first, c->inputs[i].input->name);
-       }
-       seq_printf(s, "\n");
-       return 0;
-}
-
-static int possible_parents_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, possible_parents_show, inode->i_private);
-}
-
-static const struct file_operations possible_parents_fops = {
-       .open           = possible_parents_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int clk_debugfs_register_one(struct clk *c)
-{
-       struct dentry *d;
-
-       d = debugfs_create_dir(c->name, clk_debugfs_root);
-       if (!d)
-               return -ENOMEM;
-       c->dent = d;
-
-       d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
-       if (!d)
-               goto err_out;
-
-       d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
-       if (!d)
-               goto err_out;
-
-       d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
-       if (!d)
-               goto err_out;
-
-       if (c->inputs) {
-               d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
-                       c, &possible_parents_fops);
-               if (!d)
-                       goto err_out;
-       }
-
-       return 0;
-
-err_out:
-       debugfs_remove_recursive(c->dent);
-       return -ENOMEM;
-}
-
-static int clk_debugfs_register(struct clk *c)
-{
-       int err;
-       struct clk *pa = c->parent;
-
-       if (pa && !pa->dent) {
-               err = clk_debugfs_register(pa);
-               if (err)
-                       return err;
-       }
-
-       if (!c->dent) {
-               err = clk_debugfs_register_one(c);
-               if (err)
-                       return err;
-       }
-       return 0;
-}
-
-int __init tegra_clk_debugfs_init(void)
-{
-       struct clk *c;
-       struct dentry *d;
-       int err = -ENOMEM;
-
-       d = debugfs_create_dir("clock", NULL);
-       if (!d)
-               return -ENOMEM;
-       clk_debugfs_root = d;
-
-       d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
-               &clock_tree_fops);
-       if (!d)
-               goto err_out;
-
-       list_for_each_entry(c, &clocks, node) {
-               err = clk_debugfs_register(c);
-               if (err)
-                       goto err_out;
-       }
-       return 0;
-err_out:
-       debugfs_remove_recursive(clk_debugfs_root);
-       return err;
-}
-
-#endif
index bc300657debaefe6b8eed297cb9e452bea618a74..2aa37f5c44c07d45c48f8166954c975a12d2b302 100644 (file)
@@ -2,6 +2,7 @@
  * arch/arm/mach-tegra/include/mach/clock.h
  *
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2012 NVIDIA CORPORATION.  All rights reserved.
  *
  * Author:
  *     Colin Cross <ccross@google.com>
@@ -20,9 +21,9 @@
 #ifndef __MACH_TEGRA_CLOCK_H
 #define __MACH_TEGRA_CLOCK_H
 
+#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/list.h>
-#include <linux/spinlock.h>
 
 #include <mach/clk.h>
 
@@ -52,7 +53,8 @@
 #define ENABLE_ON_INIT         (1 << 28)
 #define PERIPH_ON_APB           (1 << 29)
 
-struct clk;
+struct clk_tegra;
+#define to_clk_tegra(_hw) container_of(_hw, struct clk_tegra, hw)
 
 struct clk_mux_sel {
        struct clk      *input;
@@ -68,47 +70,29 @@ struct clk_pll_freq_table {
        u8              cpcon;
 };
 
-struct clk_ops {
-       void            (*init)(struct clk *);
-       int             (*enable)(struct clk *);
-       void            (*disable)(struct clk *);
-       int             (*set_parent)(struct clk *, struct clk *);
-       int             (*set_rate)(struct clk *, unsigned long);
-       long            (*round_rate)(struct clk *, unsigned long);
-       void            (*reset)(struct clk *, bool);
-       int             (*clk_cfg_ex)(struct clk *,
-                               enum tegra_clk_ex_param, u32);
-};
-
 enum clk_state {
        UNINITIALIZED = 0,
        ON,
        OFF,
 };
 
-struct clk {
+struct clk_tegra {
        /* node for master clocks list */
-       struct list_head        node;           /* node for list of all clocks */
+       struct list_head        node;   /* node for list of all clocks */
        struct clk_lookup       lookup;
+       struct clk_hw           hw;
 
-#ifdef CONFIG_DEBUG_FS
-       struct dentry           *dent;
-#endif
        bool                    set;
-       struct clk_ops          *ops;
-       unsigned long           rate;
+       unsigned long           fixed_rate;
        unsigned long           max_rate;
        unsigned long           min_rate;
        u32                     flags;
        const char              *name;
 
-       u32                     refcnt;
        enum clk_state          state;
-       struct clk              *parent;
        u32                     div;
        u32                     mul;
 
-       const struct clk_mux_sel        *inputs;
        u32                             reg;
        u32                             reg_shift;
 
@@ -144,7 +128,8 @@ struct clk {
                } shared_bus_user;
        } u;
 
-       spinlock_t spinlock;
+       void (*reset)(struct clk_hw *, bool);
+       int (*clk_cfg_ex)(struct clk_hw *, enum tegra_clk_ex_param, u32);
 };
 
 struct clk_duplicate {
@@ -159,13 +144,10 @@ struct tegra_clk_init_table {
        bool enabled;
 };
 
+void tegra_clk_add(struct clk *c);
 void tegra2_init_clocks(void);
 void tegra30_init_clocks(void);
-void clk_init(struct clk *clk);
 struct clk *tegra_get_clock_by_name(const char *name);
-int clk_reparent(struct clk *c, struct clk *parent);
 void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
-unsigned long clk_get_rate_locked(struct clk *c);
-int clk_set_rate_locked(struct clk *c, unsigned long rate);
 
 #endif
index 96fef6bcc65116bde2071ba6a2c46b66d6a1ed54..f3654f8309917b1ded954d5bb113a4ee3fc57698 100644 (file)
@@ -152,6 +152,5 @@ void __init tegra30_init_early(void)
 
 void __init tegra_init_late(void)
 {
-       tegra_clk_debugfs_init();
        tegra_powergate_debugfs_init();
 }
index ceb52db1e2f16409729c2ef0205b854163a3fae7..627bf0f4262ec01550242b8d52a8e384e2233c6a 100644 (file)
@@ -49,6 +49,8 @@ static struct cpufreq_frequency_table freq_table[] = {
 #define NUM_CPUS       2
 
 static struct clk *cpu_clk;
+static struct clk *pll_x_clk;
+static struct clk *pll_p_clk;
 static struct clk *emc_clk;
 
 static unsigned long target_cpu_speed[NUM_CPUS];
@@ -71,6 +73,42 @@ static unsigned int tegra_getspeed(unsigned int cpu)
        return rate;
 }
 
+static int tegra_cpu_clk_set_rate(unsigned long rate)
+{
+       int ret;
+
+       /*
+        * Take an extra reference to the main pll so it doesn't turn
+        * off when we move the cpu off of it
+        */
+       clk_prepare_enable(pll_x_clk);
+
+       ret = clk_set_parent(cpu_clk, pll_p_clk);
+       if (ret) {
+               pr_err("Failed to switch cpu to clock pll_p\n");
+               goto out;
+       }
+
+       if (rate == clk_get_rate(pll_p_clk))
+               goto out;
+
+       ret = clk_set_rate(pll_x_clk, rate);
+       if (ret) {
+               pr_err("Failed to change pll_x to %lu\n", rate);
+               goto out;
+       }
+
+       ret = clk_set_parent(cpu_clk, pll_x_clk);
+       if (ret) {
+               pr_err("Failed to switch cpu to clock pll_x\n");
+               goto out;
+       }
+
+out:
+       clk_disable_unprepare(pll_x_clk);
+       return ret;
+}
+
 static int tegra_update_cpu_speed(unsigned long rate)
 {
        int ret = 0;
@@ -101,7 +139,7 @@ static int tegra_update_cpu_speed(unsigned long rate)
               freqs.old, freqs.new);
 #endif
 
-       ret = clk_set_rate(cpu_clk, freqs.new * 1000);
+       ret = tegra_cpu_clk_set_rate(freqs.new * 1000);
        if (ret) {
                pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
                        freqs.new);
@@ -183,6 +221,14 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
        if (IS_ERR(cpu_clk))
                return PTR_ERR(cpu_clk);
 
+       pll_x_clk = clk_get_sys(NULL, "pll_x");
+       if (IS_ERR(pll_x_clk))
+               return PTR_ERR(pll_x_clk);
+
+       pll_p_clk = clk_get_sys(NULL, "pll_p");
+       if (IS_ERR(pll_p_clk))
+               return PTR_ERR(pll_p_clk);
+
        emc_clk = clk_get_sys("cpu", "emc");
        if (IS_ERR(emc_clk)) {
                clk_put(cpu_clk);
index d97e403303a0ef095c639042949f67e795e24c7e..95f3a547c770a79a468017789ec8349b47d7471e 100644 (file)
@@ -34,7 +34,10 @@ enum tegra_clk_ex_param {
 void tegra_periph_reset_deassert(struct clk *c);
 void tegra_periph_reset_assert(struct clk *c);
 
+#ifndef CONFIG_COMMON_CLK
 unsigned long clk_get_rate_all_locked(struct clk *c);
+#endif
+
 void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
 int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
 
diff --git a/arch/arm/mach-tegra/tegra20_clocks.c b/arch/arm/mach-tegra/tegra20_clocks.c
new file mode 100644 (file)
index 0000000..840ab26
--- /dev/null
@@ -0,0 +1,1555 @@
+/*
+ * arch/arm/mach-tegra/tegra20_clocks.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2010-2012 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Author:
+ *     Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+
+#include <mach/iomap.h>
+#include <mach/suspend.h>
+
+#include "clock.h"
+#include "fuse.h"
+#include "tegra2_emc.h"
+
+#define RST_DEVICES                    0x004
+#define RST_DEVICES_SET                        0x300
+#define RST_DEVICES_CLR                        0x304
+#define RST_DEVICES_NUM                        3
+
+#define CLK_OUT_ENB                    0x010
+#define CLK_OUT_ENB_SET                        0x320
+#define CLK_OUT_ENB_CLR                        0x324
+#define CLK_OUT_ENB_NUM                        3
+
+#define CLK_MASK_ARM                   0x44
+#define MISC_CLK_ENB                   0x48
+
+#define OSC_CTRL                       0x50
+#define OSC_CTRL_OSC_FREQ_MASK         (3<<30)
+#define OSC_CTRL_OSC_FREQ_13MHZ                (0<<30)
+#define OSC_CTRL_OSC_FREQ_19_2MHZ      (1<<30)
+#define OSC_CTRL_OSC_FREQ_12MHZ                (2<<30)
+#define OSC_CTRL_OSC_FREQ_26MHZ                (3<<30)
+#define OSC_CTRL_MASK                  (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
+
+#define OSC_FREQ_DET                   0x58
+#define OSC_FREQ_DET_TRIG              (1<<31)
+
+#define OSC_FREQ_DET_STATUS            0x5C
+#define OSC_FREQ_DET_BUSY              (1<<31)
+#define OSC_FREQ_DET_CNT_MASK          0xFFFF
+
+#define PERIPH_CLK_SOURCE_I2S1         0x100
+#define PERIPH_CLK_SOURCE_EMC          0x19c
+#define PERIPH_CLK_SOURCE_OSC          0x1fc
+#define PERIPH_CLK_SOURCE_NUM \
+       ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
+
+#define PERIPH_CLK_SOURCE_MASK         (3<<30)
+#define PERIPH_CLK_SOURCE_SHIFT                30
+#define PERIPH_CLK_SOURCE_PWM_MASK     (7<<28)
+#define PERIPH_CLK_SOURCE_PWM_SHIFT    28
+#define PERIPH_CLK_SOURCE_ENABLE       (1<<28)
+#define PERIPH_CLK_SOURCE_DIVU71_MASK  0xFF
+#define PERIPH_CLK_SOURCE_DIVU16_MASK  0xFFFF
+#define PERIPH_CLK_SOURCE_DIV_SHIFT    0
+
+#define SDMMC_CLK_INT_FB_SEL           (1 << 23)
+#define SDMMC_CLK_INT_FB_DLY_SHIFT     16
+#define SDMMC_CLK_INT_FB_DLY_MASK      (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
+
+#define PLL_BASE                       0x0
+#define PLL_BASE_BYPASS                        (1<<31)
+#define PLL_BASE_ENABLE                        (1<<30)
+#define PLL_BASE_REF_ENABLE            (1<<29)
+#define PLL_BASE_OVERRIDE              (1<<28)
+#define PLL_BASE_DIVP_MASK             (0x7<<20)
+#define PLL_BASE_DIVP_SHIFT            20
+#define PLL_BASE_DIVN_MASK             (0x3FF<<8)
+#define PLL_BASE_DIVN_SHIFT            8
+#define PLL_BASE_DIVM_MASK             (0x1F)
+#define PLL_BASE_DIVM_SHIFT            0
+
+#define PLL_OUT_RATIO_MASK             (0xFF<<8)
+#define PLL_OUT_RATIO_SHIFT            8
+#define PLL_OUT_OVERRIDE               (1<<2)
+#define PLL_OUT_CLKEN                  (1<<1)
+#define PLL_OUT_RESET_DISABLE          (1<<0)
+
+#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
+
+#define PLL_MISC_DCCON_SHIFT           20
+#define PLL_MISC_CPCON_SHIFT           8
+#define PLL_MISC_CPCON_MASK            (0xF<<PLL_MISC_CPCON_SHIFT)
+#define PLL_MISC_LFCON_SHIFT           4
+#define PLL_MISC_LFCON_MASK            (0xF<<PLL_MISC_LFCON_SHIFT)
+#define PLL_MISC_VCOCON_SHIFT          0
+#define PLL_MISC_VCOCON_MASK           (0xF<<PLL_MISC_VCOCON_SHIFT)
+
+#define PLLU_BASE_POST_DIV             (1<<20)
+
+#define PLLD_MISC_CLKENABLE            (1<<30)
+#define PLLD_MISC_DIV_RST              (1<<23)
+#define PLLD_MISC_DCCON_SHIFT          12
+
+#define PLLE_MISC_READY                        (1 << 15)
+
+#define PERIPH_CLK_TO_ENB_REG(c)       ((c->u.periph.clk_num / 32) * 4)
+#define PERIPH_CLK_TO_ENB_SET_REG(c)   ((c->u.periph.clk_num / 32) * 8)
+#define PERIPH_CLK_TO_ENB_BIT(c)       (1 << (c->u.periph.clk_num % 32))
+
+#define SUPER_CLK_MUX                  0x00
+#define SUPER_STATE_SHIFT              28
+#define SUPER_STATE_MASK               (0xF << SUPER_STATE_SHIFT)
+#define SUPER_STATE_STANDBY            (0x0 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IDLE               (0x1 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_RUN                        (0x2 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IRQ                        (0x3 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_FIQ                        (0x4 << SUPER_STATE_SHIFT)
+#define SUPER_SOURCE_MASK              0xF
+#define        SUPER_FIQ_SOURCE_SHIFT          12
+#define        SUPER_IRQ_SOURCE_SHIFT          8
+#define        SUPER_RUN_SOURCE_SHIFT          4
+#define        SUPER_IDLE_SOURCE_SHIFT         0
+
+#define SUPER_CLK_DIVIDER              0x04
+
+#define BUS_CLK_DISABLE                        (1<<3)
+#define BUS_CLK_DIV_MASK               0x3
+
+#define PMC_CTRL                       0x0
+ #define PMC_CTRL_BLINK_ENB            (1 << 7)
+
+#define PMC_DPD_PADS_ORIDE             0x1c
+ #define PMC_DPD_PADS_ORIDE_BLINK_ENB  (1 << 20)
+
+#define PMC_BLINK_TIMER_DATA_ON_SHIFT  0
+#define PMC_BLINK_TIMER_DATA_ON_MASK   0x7fff
+#define PMC_BLINK_TIMER_ENB            (1 << 15)
+#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
+#define PMC_BLINK_TIMER_DATA_OFF_MASK  0xffff
+
+static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+
+/*
+ * Some clocks share a register with other clocks.  Any clock op that
+ * non-atomically modifies a register used by another clock must lock
+ * clock_register_lock first.
+ */
+static DEFINE_SPINLOCK(clock_register_lock);
+
+/*
+ * Some peripheral clocks share an enable bit, so refcount the enable bits
+ * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
+ */
+static int tegra_periph_clk_enable_refcount[3 * 32];
+
+#define clk_writel(value, reg) \
+       __raw_writel(value, reg_clk_base + (reg))
+#define clk_readl(reg) \
+       __raw_readl(reg_clk_base + (reg))
+#define pmc_writel(value, reg) \
+       __raw_writel(value, reg_pmc_base + (reg))
+#define pmc_readl(reg) \
+       __raw_readl(reg_pmc_base + (reg))
+
+static unsigned long clk_measure_input_freq(void)
+{
+       u32 clock_autodetect;
+       clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
+       do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
+       clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
+       if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
+               return 12000000;
+       } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
+               return 13000000;
+       } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
+               return 19200000;
+       } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
+               return 26000000;
+       } else {
+               pr_err("%s: Unexpected clock autodetect value %d",
+                                               __func__, clock_autodetect);
+               BUG();
+               return 0;
+       }
+}
+
+static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
+{
+       s64 divider_u71 = parent_rate * 2;
+       divider_u71 += rate - 1;
+       do_div(divider_u71, rate);
+
+       if (divider_u71 - 2 < 0)
+               return 0;
+
+       if (divider_u71 - 2 > 255)
+               return -EINVAL;
+
+       return divider_u71 - 2;
+}
+
+static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
+{
+       s64 divider_u16;
+
+       divider_u16 = parent_rate;
+       divider_u16 += rate - 1;
+       do_div(divider_u16, rate);
+
+       if (divider_u16 - 1 < 0)
+               return 0;
+
+       if (divider_u16 - 1 > 0xFFFF)
+               return -EINVAL;
+
+       return divider_u16 - 1;
+}
+
+static unsigned long tegra_clk_fixed_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return to_clk_tegra(hw)->fixed_rate;
+}
+
+struct clk_ops tegra_clk_32k_ops = {
+       .recalc_rate = tegra_clk_fixed_recalc_rate,
+};
+
+/* clk_m functions */
+static unsigned long tegra20_clk_m_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       if (!to_clk_tegra(hw)->fixed_rate)
+               to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq();
+       return to_clk_tegra(hw)->fixed_rate;
+}
+
+static void tegra20_clk_m_init(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 osc_ctrl = clk_readl(OSC_CTRL);
+       u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
+
+       switch (c->fixed_rate) {
+       case 12000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
+               break;
+       case 13000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
+               break;
+       case 19200000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
+               break;
+       case 26000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
+               break;
+       default:
+               BUG();
+       }
+       clk_writel(auto_clock_control, OSC_CTRL);
+}
+
+struct clk_ops tegra_clk_m_ops = {
+       .init = tegra20_clk_m_init,
+       .recalc_rate = tegra20_clk_m_recalc_rate,
+};
+
+/* super clock functions */
+/* "super clocks" on tegra have two-stage muxes and a clock skipping
+ * super divider.  We will ignore the clock skipping divider, since we
+ * can't lower the voltage when using the clock skip, but we can if we
+ * lower the PLL frequency.
+ */
+static int tegra20_super_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+
+       val = clk_readl(c->reg + SUPER_CLK_MUX);
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       c->state = ON;
+       return c->state;
+}
+
+static int tegra20_super_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
+       return 0;
+}
+
+static void tegra20_super_clk_disable(struct clk_hw *hw)
+{
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
+
+       /* oops - don't disable the CPU clock! */
+       BUG();
+}
+
+static u8 tegra20_super_clk_get_parent(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       int val = clk_readl(c->reg + SUPER_CLK_MUX);
+       int source;
+       int shift;
+
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+       source = (val >> shift) & SUPER_SOURCE_MASK;
+       return source;
+}
+
+static int tegra20_super_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg + SUPER_CLK_MUX);
+       int shift;
+
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+       val &= ~(SUPER_SOURCE_MASK << shift);
+       val |= index << shift;
+
+       clk_writel(val, c->reg);
+
+       return 0;
+}
+
+/* FIX ME: Need to switch parents to change the source PLL rate */
+static unsigned long tegra20_super_clk_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       return prate;
+}
+
+static long tegra20_super_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       return *prate;
+}
+
+static int tegra20_super_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       return 0;
+}
+
+struct clk_ops tegra_super_ops = {
+       .is_enabled = tegra20_super_clk_is_enabled,
+       .enable = tegra20_super_clk_enable,
+       .disable = tegra20_super_clk_disable,
+       .set_parent = tegra20_super_clk_set_parent,
+       .get_parent = tegra20_super_clk_get_parent,
+       .set_rate = tegra20_super_clk_set_rate,
+       .round_rate = tegra20_super_clk_round_rate,
+       .recalc_rate = tegra20_super_clk_recalc_rate,
+};
+
+static unsigned long tegra20_twd_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
+}
+
+struct clk_ops tegra_twd_ops = {
+       .recalc_rate = tegra20_twd_clk_recalc_rate,
+};
+
+static u8 tegra20_cop_clk_get_parent(struct clk_hw *hw)
+{
+       return 0;
+}
+
+struct clk_ops tegra_cop_ops = {
+       .get_parent = tegra20_cop_clk_get_parent,
+};
+
+/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
+ * reset the COP block (i.e. AVP) */
+void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert)
+{
+       unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
+
+       pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
+       clk_writel(1 << 1, reg);
+}
+
+/* bus clock functions */
+static int tegra20_bus_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+
+       c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
+       return c->state;
+}
+
+static int tegra20_bus_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long flags;
+       u32 val;
+
+       spin_lock_irqsave(&clock_register_lock, flags);
+
+       val = clk_readl(c->reg);
+       val &= ~(BUS_CLK_DISABLE << c->reg_shift);
+       clk_writel(val, c->reg);
+
+       spin_unlock_irqrestore(&clock_register_lock, flags);
+
+       return 0;
+}
+
+static void tegra20_bus_clk_disable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long flags;
+       u32 val;
+
+       spin_lock_irqsave(&clock_register_lock, flags);
+
+       val = clk_readl(c->reg);
+       val |= BUS_CLK_DISABLE << c->reg_shift;
+       clk_writel(val, c->reg);
+
+       spin_unlock_irqrestore(&clock_register_lock, flags);
+}
+
+static unsigned long tegra20_bus_clk_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+       u64 rate = prate;
+
+       c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
+       c->mul = 1;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+       return rate;
+}
+
+static int tegra20_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       int ret = -EINVAL;
+       unsigned long flags;
+       u32 val;
+       int i;
+
+       spin_lock_irqsave(&clock_register_lock, flags);
+
+       val = clk_readl(c->reg);
+       for (i = 1; i <= 4; i++) {
+               if (rate == parent_rate / i) {
+                       val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
+                       val |= (i - 1) << c->reg_shift;
+                       clk_writel(val, c->reg);
+                       c->div = i;
+                       c->mul = 1;
+                       ret = 0;
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(&clock_register_lock, flags);
+
+       return ret;
+}
+
+static long tegra20_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       unsigned long parent_rate = *prate;
+       s64 divider;
+
+       if (rate >= parent_rate)
+               return rate;
+
+       divider = parent_rate;
+       divider += rate - 1;
+       do_div(divider, rate);
+
+       if (divider < 0)
+               return divider;
+
+       if (divider > 4)
+               divider = 4;
+       do_div(parent_rate, divider);
+
+       return parent_rate;
+}
+
+struct clk_ops tegra_bus_ops = {
+       .is_enabled = tegra20_bus_clk_is_enabled,
+       .enable = tegra20_bus_clk_enable,
+       .disable = tegra20_bus_clk_disable,
+       .set_rate = tegra20_bus_clk_set_rate,
+       .round_rate = tegra20_bus_clk_round_rate,
+       .recalc_rate = tegra20_bus_clk_recalc_rate,
+};
+
+/* Blink output functions */
+static int tegra20_blink_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+
+       val = pmc_readl(PMC_CTRL);
+       c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
+       return c->state;
+}
+
+static unsigned long tegra20_blink_clk_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = prate;
+       u32 val;
+
+       c->mul = 1;
+       val = pmc_readl(c->reg);
+
+       if (val & PMC_BLINK_TIMER_ENB) {
+               unsigned int on_off;
+
+               on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
+                       PMC_BLINK_TIMER_DATA_ON_MASK;
+               val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+               val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+               on_off += val;
+               /* each tick in the blink timer is 4 32KHz clocks */
+               c->div = on_off * 4;
+       } else {
+               c->div = 1;
+       }
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+       return rate;
+}
+
+static int tegra20_blink_clk_enable(struct clk_hw *hw)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_DPD_PADS_ORIDE);
+       pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+
+       val = pmc_readl(PMC_CTRL);
+       pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+       return 0;
+}
+
+static void tegra20_blink_clk_disable(struct clk_hw *hw)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_CTRL);
+       pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+       val = pmc_readl(PMC_DPD_PADS_ORIDE);
+       pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+}
+
+static int tegra20_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+
+       if (rate >= parent_rate) {
+               c->div = 1;
+               pmc_writel(0, c->reg);
+       } else {
+               unsigned int on_off;
+               u32 val;
+
+               on_off = DIV_ROUND_UP(parent_rate / 8, rate);
+               c->div = on_off * 8;
+
+               val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
+                       PMC_BLINK_TIMER_DATA_ON_SHIFT;
+               on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+               on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+               val |= on_off;
+               val |= PMC_BLINK_TIMER_ENB;
+               pmc_writel(val, c->reg);
+       }
+
+       return 0;
+}
+
+static long tegra20_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       int div;
+       int mul;
+       long round_rate = *prate;
+
+       mul = 1;
+
+       if (rate >= *prate) {
+               div = 1;
+       } else {
+               div = DIV_ROUND_UP(*prate / 8, rate);
+               div *= 8;
+       }
+
+       round_rate *= mul;
+       round_rate += div - 1;
+       do_div(round_rate, div);
+
+       return round_rate;
+}
+
+struct clk_ops tegra_blink_clk_ops = {
+       .is_enabled = tegra20_blink_clk_is_enabled,
+       .enable = tegra20_blink_clk_enable,
+       .disable = tegra20_blink_clk_disable,
+       .set_rate = tegra20_blink_clk_set_rate,
+       .round_rate = tegra20_blink_clk_round_rate,
+       .recalc_rate = tegra20_blink_clk_recalc_rate,
+};
+
+/* PLL Functions */
+static int tegra20_pll_clk_wait_for_lock(struct clk_tegra *c)
+{
+       udelay(c->u.pll.lock_delay);
+       return 0;
+}
+
+static int tegra20_pll_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg + PLL_BASE);
+
+       c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
+       return c->state;
+}
+
+static unsigned long tegra20_pll_clk_recalc_rate(struct clk_hw *hw,
+                               unsigned long prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg + PLL_BASE);
+       u64 rate = prate;
+
+       if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
+               const struct clk_pll_freq_table *sel;
+               for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+                       if (sel->input_rate == prate &&
+                               sel->output_rate == c->u.pll.fixed_rate) {
+                               c->mul = sel->n;
+                               c->div = sel->m * sel->p;
+                               break;
+                       }
+               }
+               pr_err("Clock %s has unknown fixed frequency\n",
+                       __clk_get_name(hw->clk));
+               BUG();
+       } else if (val & PLL_BASE_BYPASS) {
+               c->mul = 1;
+               c->div = 1;
+       } else {
+               c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+               c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+               if (c->flags & PLLU)
+                       c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
+               else
+                       c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
+       }
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+       return rate;
+}
+
+static int tegra20_pll_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
+
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~PLL_BASE_BYPASS;
+       val |= PLL_BASE_ENABLE;
+       clk_writel(val, c->reg + PLL_BASE);
+
+       tegra20_pll_clk_wait_for_lock(c);
+
+       return 0;
+}
+
+static void tegra20_pll_clk_disable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
+
+       val = clk_readl(c->reg);
+       val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+       clk_writel(val, c->reg);
+}
+
+static int tegra20_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long input_rate = parent_rate;
+       const struct clk_pll_freq_table *sel;
+       u32 val;
+
+       pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
+
+       if (c->flags & PLL_FIXED) {
+               int ret = 0;
+               if (rate != c->u.pll.fixed_rate) {
+                       pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
+                               __func__, __clk_get_name(hw->clk),
+                               c->u.pll.fixed_rate, rate);
+                       ret = -EINVAL;
+               }
+               return ret;
+       }
+
+       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+               if (sel->input_rate == input_rate && sel->output_rate == rate) {
+                       c->mul = sel->n;
+                       c->div = sel->m * sel->p;
+
+                       val = clk_readl(c->reg + PLL_BASE);
+                       if (c->flags & PLL_FIXED)
+                               val |= PLL_BASE_OVERRIDE;
+                       val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
+                                PLL_BASE_DIVM_MASK);
+                       val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
+                               (sel->n << PLL_BASE_DIVN_SHIFT);
+                       BUG_ON(sel->p < 1 || sel->p > 2);
+                       if (c->flags & PLLU) {
+                               if (sel->p == 1)
+                                       val |= PLLU_BASE_POST_DIV;
+                       } else {
+                               if (sel->p == 2)
+                                       val |= 1 << PLL_BASE_DIVP_SHIFT;
+                       }
+                       clk_writel(val, c->reg + PLL_BASE);
+
+                       if (c->flags & PLL_HAS_CPCON) {
+                               val = clk_readl(c->reg + PLL_MISC(c));
+                               val &= ~PLL_MISC_CPCON_MASK;
+                               val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
+                               clk_writel(val, c->reg + PLL_MISC(c));
+                       }
+
+                       if (c->state == ON)
+                               tegra20_pll_clk_enable(hw);
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static long tegra20_pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       const struct clk_pll_freq_table *sel;
+       unsigned long input_rate = *prate;
+       u64 output_rate = *prate;
+       int mul;
+       int div;
+
+       if (c->flags & PLL_FIXED)
+               return c->u.pll.fixed_rate;
+
+       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++)
+               if (sel->input_rate == input_rate && sel->output_rate == rate) {
+                       mul = sel->n;
+                       div = sel->m * sel->p;
+                       break;
+               }
+
+       if (sel->input_rate == 0)
+               return -EINVAL;
+
+       output_rate *= mul;
+       output_rate += div - 1; /* round up */
+       do_div(output_rate, div);
+
+       return output_rate;
+}
+
+struct clk_ops tegra_pll_ops = {
+       .is_enabled = tegra20_pll_clk_is_enabled,
+       .enable = tegra20_pll_clk_enable,
+       .disable = tegra20_pll_clk_disable,
+       .set_rate = tegra20_pll_clk_set_rate,
+       .recalc_rate = tegra20_pll_clk_recalc_rate,
+       .round_rate = tegra20_pll_clk_round_rate,
+};
+
+static void tegra20_pllx_clk_init(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+
+       if (tegra_sku_id == 7)
+               c->max_rate = 750000000;
+}
+
+struct clk_ops tegra_pllx_ops = {
+       .init = tegra20_pllx_clk_init,
+       .is_enabled = tegra20_pll_clk_is_enabled,
+       .enable = tegra20_pll_clk_enable,
+       .disable = tegra20_pll_clk_disable,
+       .set_rate = tegra20_pll_clk_set_rate,
+       .recalc_rate = tegra20_pll_clk_recalc_rate,
+       .round_rate = tegra20_pll_clk_round_rate,
+};
+
+static int tegra20_plle_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
+
+       mdelay(1);
+
+       val = clk_readl(c->reg + PLL_BASE);
+       if (!(val & PLLE_MISC_READY))
+               return -EBUSY;
+
+       val = clk_readl(c->reg + PLL_BASE);
+       val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
+       clk_writel(val, c->reg + PLL_BASE);
+
+       return 0;
+}
+
+struct clk_ops tegra_plle_ops = {
+       .is_enabled = tegra20_pll_clk_is_enabled,
+       .enable = tegra20_plle_clk_enable,
+       .set_rate = tegra20_pll_clk_set_rate,
+       .recalc_rate = tegra20_pll_clk_recalc_rate,
+       .round_rate = tegra20_pll_clk_round_rate,
+};
+
+/* Clock divider ops */
+static int tegra20_pll_div_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+
+       val >>= c->reg_shift;
+       c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
+       if (!(val & PLL_OUT_RESET_DISABLE))
+               c->state = OFF;
+       return c->state;
+}
+
+static unsigned long tegra20_pll_div_clk_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = prate;
+       u32 val = clk_readl(c->reg);
+       u32 divu71;
+
+       val >>= c->reg_shift;
+
+       if (c->flags & DIV_U71) {
+               divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
+               c->div = (divu71 + 2);
+               c->mul = 2;
+       } else if (c->flags & DIV_2) {
+               c->div = 2;
+               c->mul = 1;
+       } else {
+               c->div = 1;
+               c->mul = 1;
+       }
+
+       rate *= c->mul;
+       rate += c->div - 1; /* round up */
+       do_div(rate, c->div);
+
+       return rate;
+}
+
+static int tegra20_pll_div_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long flags;
+       u32 new_val;
+       u32 val;
+
+       pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
+
+       if (c->flags & DIV_U71) {
+               spin_lock_irqsave(&clock_register_lock, flags);
+               val = clk_readl(c->reg);
+               new_val = val >> c->reg_shift;
+               new_val &= 0xFFFF;
+
+               new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
+
+               val &= ~(0xFFFF << c->reg_shift);
+               val |= new_val << c->reg_shift;
+               clk_writel(val, c->reg);
+               spin_unlock_irqrestore(&clock_register_lock, flags);
+               return 0;
+       } else if (c->flags & DIV_2) {
+               BUG_ON(!(c->flags & PLLD));
+               spin_lock_irqsave(&clock_register_lock, flags);
+               val = clk_readl(c->reg);
+               val &= ~PLLD_MISC_DIV_RST;
+               clk_writel(val, c->reg);
+               spin_unlock_irqrestore(&clock_register_lock, flags);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static void tegra20_pll_div_clk_disable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long flags;
+       u32 new_val;
+       u32 val;
+
+       pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
+
+       if (c->flags & DIV_U71) {
+               spin_lock_irqsave(&clock_register_lock, flags);
+               val = clk_readl(c->reg);
+               new_val = val >> c->reg_shift;
+               new_val &= 0xFFFF;
+
+               new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
+
+               val &= ~(0xFFFF << c->reg_shift);
+               val |= new_val << c->reg_shift;
+               clk_writel(val, c->reg);
+               spin_unlock_irqrestore(&clock_register_lock, flags);
+       } else if (c->flags & DIV_2) {
+               BUG_ON(!(c->flags & PLLD));
+               spin_lock_irqsave(&clock_register_lock, flags);
+               val = clk_readl(c->reg);
+               val |= PLLD_MISC_DIV_RST;
+               clk_writel(val, c->reg);
+               spin_unlock_irqrestore(&clock_register_lock, flags);
+       }
+}
+
+static int tegra20_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long flags;
+       int divider_u71;
+       u32 new_val;
+       u32 val;
+
+       pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
+
+       if (c->flags & DIV_U71) {
+               divider_u71 = clk_div71_get_divider(parent_rate, rate);
+               if (divider_u71 >= 0) {
+                       spin_lock_irqsave(&clock_register_lock, flags);
+                       val = clk_readl(c->reg);
+                       new_val = val >> c->reg_shift;
+                       new_val &= 0xFFFF;
+                       if (c->flags & DIV_U71_FIXED)
+                               new_val |= PLL_OUT_OVERRIDE;
+                       new_val &= ~PLL_OUT_RATIO_MASK;
+                       new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
+
+                       val &= ~(0xFFFF << c->reg_shift);
+                       val |= new_val << c->reg_shift;
+                       clk_writel(val, c->reg);
+                       c->div = divider_u71 + 2;
+                       c->mul = 2;
+                       spin_unlock_irqrestore(&clock_register_lock, flags);
+                       return 0;
+               }
+       } else if (c->flags & DIV_2) {
+               if (parent_rate == rate * 2)
+                       return 0;
+       }
+       return -EINVAL;
+}
+
+static long tegra20_pll_div_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long parent_rate = *prate;
+       int divider;
+
+       pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(parent_rate, rate);
+               if (divider < 0)
+                       return divider;
+               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+       } else if (c->flags & DIV_2) {
+               return DIV_ROUND_UP(parent_rate, 2);
+       }
+       return -EINVAL;
+}
+
+struct clk_ops tegra_pll_div_ops = {
+       .is_enabled = tegra20_pll_div_clk_is_enabled,
+       .enable = tegra20_pll_div_clk_enable,
+       .disable = tegra20_pll_div_clk_disable,
+       .set_rate = tegra20_pll_div_clk_set_rate,
+       .round_rate = tegra20_pll_div_clk_round_rate,
+       .recalc_rate = tegra20_pll_div_clk_recalc_rate,
+};
+
+/* Periph clk ops */
+
+static int tegra20_periph_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+
+       c->state = ON;
+
+       if (!c->u.periph.clk_num)
+               goto out;
+
+       if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+                       PERIPH_CLK_TO_ENB_BIT(c)))
+               c->state = OFF;
+
+       if (!(c->flags & PERIPH_NO_RESET))
+               if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
+                               PERIPH_CLK_TO_ENB_BIT(c))
+                       c->state = OFF;
+
+out:
+       return c->state;
+}
+
+static int tegra20_periph_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long flags;
+       u32 val;
+
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
+
+       if (!c->u.periph.clk_num)
+               return 0;
+
+       tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
+       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
+               return 0;
+
+       spin_lock_irqsave(&clock_register_lock, flags);
+
+       clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+               CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
+       if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
+               clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+                       RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+       if (c->flags & PERIPH_EMC_ENB) {
+               /* The EMC peripheral clock has 2 extra enable bits */
+               /* FIXME: Do they need to be disabled? */
+               val = clk_readl(c->reg);
+               val |= 0x3 << 24;
+               clk_writel(val, c->reg);
+       }
+
+       spin_unlock_irqrestore(&clock_register_lock, flags);
+
+       return 0;
+}
+
+static void tegra20_periph_clk_disable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long flags;
+
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
+
+       if (!c->u.periph.clk_num)
+               return;
+
+       tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
+
+       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0)
+               return;
+
+       spin_lock_irqsave(&clock_register_lock, flags);
+
+       clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+               CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+
+       spin_unlock_irqrestore(&clock_register_lock, flags);
+}
+
+void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
+
+       pr_debug("%s %s on clock %s\n", __func__,
+               assert ? "assert" : "deassert", __clk_get_name(hw->clk));
+
+       BUG_ON(!c->u.periph.clk_num);
+
+       if (!(c->flags & PERIPH_NO_RESET))
+               clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+                          base + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+static int tegra20_periph_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+       u32 mask;
+       u32 shift;
+
+       pr_debug("%s: %s %d\n", __func__, __clk_get_name(hw->clk), index);
+
+       if (c->flags & MUX_PWM) {
+               shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
+               mask = PERIPH_CLK_SOURCE_PWM_MASK;
+       } else {
+               shift = PERIPH_CLK_SOURCE_SHIFT;
+               mask = PERIPH_CLK_SOURCE_MASK;
+       }
+
+       val = clk_readl(c->reg);
+       val &= ~mask;
+       val |= (index) << shift;
+
+       clk_writel(val, c->reg);
+
+       return 0;
+}
+
+static u8 tegra20_periph_clk_get_parent(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+       u32 mask;
+       u32 shift;
+
+       if (c->flags & MUX_PWM) {
+               shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
+               mask = PERIPH_CLK_SOURCE_PWM_MASK;
+       } else {
+               shift = PERIPH_CLK_SOURCE_SHIFT;
+               mask = PERIPH_CLK_SOURCE_MASK;
+       }
+
+       if (c->flags & MUX)
+               return (val & mask) >> shift;
+       else
+               return 0;
+}
+
+static unsigned long tegra20_periph_clk_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long rate = prate;
+       u32 val = clk_readl(c->reg);
+
+       if (c->flags & DIV_U71) {
+               u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
+               c->div = divu71 + 2;
+               c->mul = 2;
+       } else if (c->flags & DIV_U16) {
+               u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+               c->div = divu16 + 1;
+               c->mul = 1;
+       } else {
+               c->div = 1;
+               c->mul = 1;
+               return rate;
+       }
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
+}
+
+static int tegra20_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+       int divider;
+
+       val = clk_readl(c->reg);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(parent_rate, rate);
+
+               if (divider >= 0) {
+                       val = clk_readl(c->reg);
+                       val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
+                       val |= divider;
+                       clk_writel(val, c->reg);
+                       c->div = divider + 2;
+                       c->mul = 2;
+                       return 0;
+               }
+       } else if (c->flags & DIV_U16) {
+               divider = clk_div16_get_divider(parent_rate, rate);
+               if (divider >= 0) {
+                       val = clk_readl(c->reg);
+                       val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
+                       val |= divider;
+                       clk_writel(val, c->reg);
+                       c->div = divider + 1;
+                       c->mul = 1;
+                       return 0;
+               }
+       } else if (parent_rate <= rate) {
+               c->div = 1;
+               c->mul = 1;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static long tegra20_periph_clk_round_rate(struct clk_hw *hw,
+       unsigned long rate, unsigned long *prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+       int divider;
+
+       pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
+
+       if (prate)
+               parent_rate = *prate;
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(parent_rate, rate);
+               if (divider < 0)
+                       return divider;
+
+               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+       } else if (c->flags & DIV_U16) {
+               divider = clk_div16_get_divider(parent_rate, rate);
+               if (divider < 0)
+                       return divider;
+               return DIV_ROUND_UP(parent_rate, divider + 1);
+       }
+       return -EINVAL;
+}
+
+struct clk_ops tegra_periph_clk_ops = {
+       .is_enabled = tegra20_periph_clk_is_enabled,
+       .enable = tegra20_periph_clk_enable,
+       .disable = tegra20_periph_clk_disable,
+       .set_parent = tegra20_periph_clk_set_parent,
+       .get_parent = tegra20_periph_clk_get_parent,
+       .set_rate = tegra20_periph_clk_set_rate,
+       .round_rate = tegra20_periph_clk_round_rate,
+       .recalc_rate = tegra20_periph_clk_recalc_rate,
+};
+
+/* External memory controller clock ops */
+static void tegra20_emc_clk_init(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       c->max_rate = __clk_get_rate(hw->clk);
+}
+
+static long tegra20_emc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       long emc_rate;
+       long clk_rate;
+
+       /*
+        * The slowest entry in the EMC clock table that is at least as
+        * fast as rate.
+        */
+       emc_rate = tegra_emc_round_rate(rate);
+       if (emc_rate < 0)
+               return c->max_rate;
+
+       /*
+        * The fastest rate the PLL will generate that is at most the
+        * requested rate.
+        */
+       clk_rate = tegra20_periph_clk_round_rate(hw, emc_rate, NULL);
+
+       /*
+        * If this fails, and emc_rate > clk_rate, it's because the maximum
+        * rate in the EMC tables is larger than the maximum rate of the EMC
+        * clock. The EMC clock's max rate is the rate it was running when the
+        * kernel booted. Such a mismatch is probably due to using the wrong
+        * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25.
+        */
+       WARN_ONCE(emc_rate != clk_rate,
+               "emc_rate %ld != clk_rate %ld",
+               emc_rate, clk_rate);
+
+       return emc_rate;
+}
+
+static int tegra20_emc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       int ret;
+
+       /*
+        * The Tegra2 memory controller has an interlock with the clock
+        * block that allows memory shadowed registers to be updated,
+        * and then transfer them to the main registers at the same
+        * time as the clock update without glitches.
+        */
+       ret = tegra_emc_set_rate(rate);
+       if (ret < 0)
+               return ret;
+
+       ret = tegra20_periph_clk_set_rate(hw, rate, parent_rate);
+       udelay(1);
+
+       return ret;
+}
+
+struct clk_ops tegra_emc_clk_ops = {
+       .init = tegra20_emc_clk_init,
+       .is_enabled = tegra20_periph_clk_is_enabled,
+       .enable = tegra20_periph_clk_enable,
+       .disable = tegra20_periph_clk_disable,
+       .set_parent = tegra20_periph_clk_set_parent,
+       .get_parent = tegra20_periph_clk_get_parent,
+       .set_rate = tegra20_emc_clk_set_rate,
+       .round_rate = tegra20_emc_clk_round_rate,
+       .recalc_rate = tegra20_periph_clk_recalc_rate,
+};
+
+/* Clock doubler ops */
+static int tegra20_clk_double_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+
+       c->state = ON;
+
+       if (!c->u.periph.clk_num)
+               goto out;
+
+       if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+                       PERIPH_CLK_TO_ENB_BIT(c)))
+               c->state = OFF;
+
+out:
+       return c->state;
+};
+
+static unsigned long tegra20_clk_double_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = prate;
+
+       c->mul = 2;
+       c->div = 1;
+
+       rate *= c->mul;
+       rate += c->div - 1; /* round up */
+       do_div(rate, c->div);
+
+       return rate;
+}
+
+static long tegra20_clk_double_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       unsigned long output_rate = *prate;
+
+       do_div(output_rate, 2);
+       return output_rate;
+}
+
+static int tegra20_clk_double_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       if (rate != 2 * parent_rate)
+               return -EINVAL;
+       return 0;
+}
+
+struct clk_ops tegra_clk_double_ops = {
+       .is_enabled = tegra20_clk_double_is_enabled,
+       .enable = tegra20_periph_clk_enable,
+       .disable = tegra20_periph_clk_disable,
+       .set_rate = tegra20_clk_double_set_rate,
+       .recalc_rate = tegra20_clk_double_recalc_rate,
+       .round_rate = tegra20_clk_double_round_rate,
+};
+
+/* Audio sync clock ops */
+static int tegra20_audio_sync_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+
+       c->state = (val & (1<<4)) ? OFF : ON;
+       return c->state;
+}
+
+static int tegra20_audio_sync_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+
+       clk_writel(0, c->reg);
+       return 0;
+}
+
+static void tegra20_audio_sync_clk_disable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       clk_writel(1, c->reg);
+}
+
+static u8 tegra20_audio_sync_clk_get_parent(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+       int source;
+
+       source = val & 0xf;
+       return source;
+}
+
+static int tegra20_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+
+       val = clk_readl(c->reg);
+       val &= ~0xf;
+       val |= index;
+
+       clk_writel(val, c->reg);
+
+       return 0;
+}
+
+struct clk_ops tegra_audio_sync_clk_ops = {
+       .is_enabled = tegra20_audio_sync_clk_is_enabled,
+       .enable = tegra20_audio_sync_clk_enable,
+       .disable = tegra20_audio_sync_clk_disable,
+       .set_parent = tegra20_audio_sync_clk_set_parent,
+       .get_parent = tegra20_audio_sync_clk_get_parent,
+};
+
+/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
+
+static int tegra20_cdev_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
+        * currently done in the pinmux code. */
+       c->state = ON;
+
+       BUG_ON(!c->u.periph.clk_num);
+
+       if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+                       PERIPH_CLK_TO_ENB_BIT(c)))
+               c->state = OFF;
+       return c->state;
+}
+
+static int tegra20_cdev_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       BUG_ON(!c->u.periph.clk_num);
+
+       clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+               CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
+       return 0;
+}
+
+static void tegra20_cdev_clk_disable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       BUG_ON(!c->u.periph.clk_num);
+
+       clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+               CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+static unsigned long tegra20_cdev_recalc_rate(struct clk_hw *hw,
+                       unsigned long prate)
+{
+       return to_clk_tegra(hw)->fixed_rate;
+}
+
+struct clk_ops tegra_cdev_clk_ops = {
+       .is_enabled = tegra20_cdev_clk_is_enabled,
+       .enable = tegra20_cdev_clk_enable,
+       .disable = tegra20_cdev_clk_disable,
+       .recalc_rate = tegra20_cdev_recalc_rate,
+};
diff --git a/arch/arm/mach-tegra/tegra20_clocks.h b/arch/arm/mach-tegra/tegra20_clocks.h
new file mode 100644 (file)
index 0000000..8bfd31b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA20_CLOCK_H
+#define __MACH_TEGRA20_CLOCK_H
+
+extern struct clk_ops tegra_clk_32k_ops;
+extern struct clk_ops tegra_pll_ops;
+extern struct clk_ops tegra_clk_m_ops;
+extern struct clk_ops tegra_pll_div_ops;
+extern struct clk_ops tegra_pllx_ops;
+extern struct clk_ops tegra_plle_ops;
+extern struct clk_ops tegra_clk_double_ops;
+extern struct clk_ops tegra_cdev_clk_ops;
+extern struct clk_ops tegra_audio_sync_clk_ops;
+extern struct clk_ops tegra_super_ops;
+extern struct clk_ops tegra_cpu_ops;
+extern struct clk_ops tegra_twd_ops;
+extern struct clk_ops tegra_cop_ops;
+extern struct clk_ops tegra_bus_ops;
+extern struct clk_ops tegra_blink_clk_ops;
+extern struct clk_ops tegra_emc_clk_ops;
+extern struct clk_ops tegra_periph_clk_ops;
+extern struct clk_ops tegra_clk_shared_bus_ops;
+
+void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert);
+void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert);
+
+#endif
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c b/arch/arm/mach-tegra/tegra20_clocks_data.c
new file mode 100644 (file)
index 0000000..6cfe2f9
--- /dev/null
@@ -0,0 +1,1138 @@
+/*
+ * arch/arm/mach-tegra/tegra2_clocks.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2012 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Author:
+ *     Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-private.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <mach/iomap.h>
+#include <mach/suspend.h>
+
+#include "clock.h"
+#include "fuse.h"
+#include "tegra2_emc.h"
+#include "tegra20_clocks.h"
+
+/* Clock definitions */
+
+#define DEFINE_CLK_TEGRA(_name, _rate, _ops, _flags,           \
+                  _parent_names, _parents, _parent)            \
+       static struct clk tegra_##_name = {                     \
+               .hw = &tegra_##_name##_hw.hw,                   \
+               .name = #_name,                                 \
+               .rate = _rate,                                  \
+               .ops = _ops,                                    \
+               .flags = _flags,                                \
+               .parent_names = _parent_names,                  \
+               .parents = _parents,                            \
+               .num_parents = ARRAY_SIZE(_parent_names),       \
+               .parent = _parent,                              \
+       };
+
+static struct clk tegra_clk_32k;
+static struct clk_tegra tegra_clk_32k_hw = {
+       .hw = {
+               .clk = &tegra_clk_32k,
+       },
+       .fixed_rate = 32768,
+};
+
+static struct clk tegra_clk_32k = {
+       .name = "clk_32k",
+       .rate = 32768,
+       .ops = &tegra_clk_32k_ops,
+       .hw = &tegra_clk_32k_hw.hw,
+       .flags = CLK_IS_ROOT,
+};
+
+static struct clk tegra_clk_m;
+static struct clk_tegra tegra_clk_m_hw = {
+       .hw = {
+               .clk = &tegra_clk_m,
+       },
+       .flags = ENABLE_ON_INIT,
+       .reg = 0x1fc,
+       .reg_shift = 28,
+       .max_rate = 26000000,
+       .fixed_rate = 0,
+};
+
+static struct clk tegra_clk_m = {
+       .name = "clk_m",
+       .ops = &tegra_clk_m_ops,
+       .hw = &tegra_clk_m_hw.hw,
+       .flags = CLK_IS_ROOT,
+};
+
+#define DEFINE_PLL(_name, _flags, _reg, _max_rate, _input_min, \
+                  _input_max, _cf_min, _cf_max, _vco_min,      \
+                  _vco_max, _freq_table, _lock_delay, _ops,    \
+                  _fixed_rate, _parent)                        \
+       static const char *tegra_##_name##_parent_names[] = {   \
+               #_parent,                                       \
+       };                                                      \
+       static struct clk *tegra_##_name##_parents[] = {        \
+               &tegra_##_parent,                               \
+       };                                                      \
+       static struct clk tegra_##_name;                        \
+       static struct clk_tegra tegra_##_name##_hw = {          \
+               .hw = {                                         \
+                       .clk = &tegra_##_name,                  \
+               },                                              \
+               .flags = _flags,                                \
+               .reg = _reg,                                    \
+               .max_rate = _max_rate,                          \
+               .u.pll = {                                      \
+                       .input_min = _input_min,                \
+                       .input_max = _input_max,                \
+                       .cf_min = _cf_min,                      \
+                       .cf_max = _cf_max,                      \
+                       .vco_min = _vco_min,                    \
+                       .vco_max = _vco_max,                    \
+                       .freq_table = _freq_table,              \
+                       .lock_delay = _lock_delay,              \
+                       .fixed_rate = _fixed_rate,              \
+               },                                              \
+       };                                                      \
+       static struct clk tegra_##_name = {                     \
+               .name = #_name,                                 \
+               .ops = &_ops,                                   \
+               .hw = &tegra_##_name##_hw.hw,                   \
+               .parent = &tegra_##_parent,                     \
+               .parent_names = tegra_##_name##_parent_names,   \
+               .parents = tegra_##_name##_parents,             \
+               .num_parents = 1,                               \
+       };
+
+#define DEFINE_PLL_OUT(_name, _flags, _reg, _reg_shift,                \
+               _max_rate, _ops, _parent, _clk_flags)           \
+       static const char *tegra_##_name##_parent_names[] = {   \
+               #_parent,                                       \
+       };                                                      \
+       static struct clk *tegra_##_name##_parents[] = {        \
+               &tegra_##_parent,                               \
+       };                                                      \
+       static struct clk tegra_##_name;                        \
+       static struct clk_tegra tegra_##_name##_hw = {          \
+               .hw = {                                         \
+                       .clk = &tegra_##_name,                  \
+               },                                              \
+               .flags = _flags,                                \
+               .reg = _reg,                                    \
+               .max_rate = _max_rate,                          \
+               .reg_shift = _reg_shift,                        \
+       };                                                      \
+       static struct clk tegra_##_name = {                     \
+               .name = #_name,                                 \
+               .ops = &tegra_pll_div_ops,                      \
+               .hw = &tegra_##_name##_hw.hw,                   \
+               .parent = &tegra_##_parent,                     \
+               .parent_names = tegra_##_name##_parent_names,   \
+               .parents = tegra_##_name##_parents,             \
+               .num_parents = 1,                               \
+               .flags = _clk_flags,                            \
+       };
+
+
+static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
+       {32768, 12000000, 366, 1, 1, 0},
+       {32768, 13000000, 397, 1, 1, 0},
+       {32768, 19200000, 586, 1, 1, 0},
+       {32768, 26000000, 793, 1, 1, 0},
+       {0, 0, 0, 0, 0, 0},
+};
+
+DEFINE_PLL(pll_s, PLL_ALT_MISC_REG, 0xf0, 26000000, 32768, 32768, 0,
+               0, 12000000, 26000000, tegra_pll_s_freq_table, 300,
+               tegra_pll_ops, 0, clk_32k);
+
+static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
+       { 12000000, 600000000, 600, 12, 1, 8 },
+       { 13000000, 600000000, 600, 13, 1, 8 },
+       { 19200000, 600000000, 500, 16, 1, 6 },
+       { 26000000, 600000000, 600, 26, 1, 8 },
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_c, PLL_HAS_CPCON, 0x80, 600000000, 2000000, 31000000, 1000000,
+               6000000, 20000000, 1400000000, tegra_pll_c_freq_table, 300,
+               tegra_pll_ops, 0, clk_m);
+
+DEFINE_PLL_OUT(pll_c_out1, DIV_U71, 0x84, 0, 600000000,
+               tegra_pll_div_ops, pll_c, 0);
+
+static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
+       { 12000000, 666000000, 666, 12, 1, 8},
+       { 13000000, 666000000, 666, 13, 1, 8},
+       { 19200000, 666000000, 555, 16, 1, 8},
+       { 26000000, 666000000, 666, 26, 1, 8},
+       { 12000000, 600000000, 600, 12, 1, 8},
+       { 13000000, 600000000, 600, 13, 1, 8},
+       { 19200000, 600000000, 375, 12, 1, 6},
+       { 26000000, 600000000, 600, 26, 1, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_m, PLL_HAS_CPCON, 0x90, 800000000, 2000000, 31000000, 1000000,
+               6000000, 20000000, 1200000000, tegra_pll_m_freq_table, 300,
+               tegra_pll_ops, 0, clk_m);
+
+DEFINE_PLL_OUT(pll_m_out1, DIV_U71, 0x94, 0, 600000000,
+               tegra_pll_div_ops, pll_m, 0);
+
+static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
+       { 12000000, 216000000, 432, 12, 2, 8},
+       { 13000000, 216000000, 432, 13, 2, 8},
+       { 19200000, 216000000, 90,   4, 2, 1},
+       { 26000000, 216000000, 432, 26, 2, 8},
+       { 12000000, 432000000, 432, 12, 1, 8},
+       { 13000000, 432000000, 432, 13, 1, 8},
+       { 19200000, 432000000, 90,   4, 1, 1},
+       { 26000000, 432000000, 432, 26, 1, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+
+DEFINE_PLL(pll_p, ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, 0xa0, 432000000,
+               2000000, 31000000, 1000000, 6000000, 20000000, 1400000000,
+               tegra_pll_p_freq_table, 300, tegra_pll_ops, 216000000, clk_m);
+
+DEFINE_PLL_OUT(pll_p_out1, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, 0,
+               432000000, tegra_pll_div_ops, pll_p, 0);
+DEFINE_PLL_OUT(pll_p_out2, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, 16,
+               432000000, tegra_pll_div_ops, pll_p, 0);
+DEFINE_PLL_OUT(pll_p_out3, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, 0,
+               432000000, tegra_pll_div_ops, pll_p, 0);
+DEFINE_PLL_OUT(pll_p_out4, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, 16,
+               432000000, tegra_pll_div_ops, pll_p, 0);
+
+static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
+       { 28800000, 56448000, 49, 25, 1, 1},
+       { 28800000, 73728000, 64, 25, 1, 1},
+       { 28800000, 24000000,  5,  6, 1, 1},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_a, PLL_HAS_CPCON, 0xb0, 73728000, 2000000, 31000000, 1000000,
+               6000000, 20000000, 1400000000, tegra_pll_a_freq_table, 300,
+               tegra_pll_ops, 0, pll_p_out1);
+
+DEFINE_PLL_OUT(pll_a_out0, DIV_U71, 0xb4, 0, 73728000,
+               tegra_pll_div_ops, pll_a, 0);
+
+static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
+       { 12000000, 216000000, 216, 12, 1, 4},
+       { 13000000, 216000000, 216, 13, 1, 4},
+       { 19200000, 216000000, 135, 12, 1, 3},
+       { 26000000, 216000000, 216, 26, 1, 4},
+
+       { 12000000, 594000000, 594, 12, 1, 8},
+       { 13000000, 594000000, 594, 13, 1, 8},
+       { 19200000, 594000000, 495, 16, 1, 8},
+       { 26000000, 594000000, 594, 26, 1, 8},
+
+       { 12000000, 1000000000, 1000, 12, 1, 12},
+       { 13000000, 1000000000, 1000, 13, 1, 12},
+       { 19200000, 1000000000, 625,  12, 1, 8},
+       { 26000000, 1000000000, 1000, 26, 1, 12},
+
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_d, PLL_HAS_CPCON | PLLD, 0xd0, 1000000000, 2000000, 40000000,
+               1000000, 6000000, 40000000, 1000000000, tegra_pll_d_freq_table,
+               1000, tegra_pll_ops, 0, clk_m);
+
+DEFINE_PLL_OUT(pll_d_out0, DIV_2 | PLLD, 0, 0, 500000000,
+               tegra_pll_div_ops, pll_d, CLK_SET_RATE_PARENT);
+
+static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
+       { 12000000, 480000000, 960, 12, 2, 0},
+       { 13000000, 480000000, 960, 13, 2, 0},
+       { 19200000, 480000000, 200, 4,  2, 0},
+       { 26000000, 480000000, 960, 26, 2, 0},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_u, PLLU, 0xc0, 480000000, 2000000, 40000000, 1000000, 6000000,
+               48000000, 960000000, tegra_pll_u_freq_table, 1000,
+               tegra_pll_ops, 0, clk_m);
+
+static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
+       /* 1 GHz */
+       { 12000000, 1000000000, 1000, 12, 1, 12},
+       { 13000000, 1000000000, 1000, 13, 1, 12},
+       { 19200000, 1000000000, 625,  12, 1, 8},
+       { 26000000, 1000000000, 1000, 26, 1, 12},
+
+       /* 912 MHz */
+       { 12000000, 912000000,  912,  12, 1, 12},
+       { 13000000, 912000000,  912,  13, 1, 12},
+       { 19200000, 912000000,  760,  16, 1, 8},
+       { 26000000, 912000000,  912,  26, 1, 12},
+
+       /* 816 MHz */
+       { 12000000, 816000000,  816,  12, 1, 12},
+       { 13000000, 816000000,  816,  13, 1, 12},
+       { 19200000, 816000000,  680,  16, 1, 8},
+       { 26000000, 816000000,  816,  26, 1, 12},
+
+       /* 760 MHz */
+       { 12000000, 760000000,  760,  12, 1, 12},
+       { 13000000, 760000000,  760,  13, 1, 12},
+       { 19200000, 760000000,  950,  24, 1, 8},
+       { 26000000, 760000000,  760,  26, 1, 12},
+
+       /* 750 MHz */
+       { 12000000, 750000000,  750,  12, 1, 12},
+       { 13000000, 750000000,  750,  13, 1, 12},
+       { 19200000, 750000000,  625,  16, 1, 8},
+       { 26000000, 750000000,  750,  26, 1, 12},
+
+       /* 608 MHz */
+       { 12000000, 608000000,  608,  12, 1, 12},
+       { 13000000, 608000000,  608,  13, 1, 12},
+       { 19200000, 608000000,  380,  12, 1, 8},
+       { 26000000, 608000000,  608,  26, 1, 12},
+
+       /* 456 MHz */
+       { 12000000, 456000000,  456,  12, 1, 12},
+       { 13000000, 456000000,  456,  13, 1, 12},
+       { 19200000, 456000000,  380,  16, 1, 8},
+       { 26000000, 456000000,  456,  26, 1, 12},
+
+       /* 312 MHz */
+       { 12000000, 312000000,  312,  12, 1, 12},
+       { 13000000, 312000000,  312,  13, 1, 12},
+       { 19200000, 312000000,  260,  16, 1, 8},
+       { 26000000, 312000000,  312,  26, 1, 12},
+
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_x, PLL_HAS_CPCON | PLL_ALT_MISC_REG, 0xe0, 1000000000, 2000000,
+               31000000, 1000000, 6000000, 20000000, 1200000000,
+               tegra_pll_x_freq_table, 300, tegra_pllx_ops, 0, clk_m);
+
+static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
+       { 12000000, 100000000,  200,  24, 1, 0 },
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_e, PLL_ALT_MISC_REG, 0xe8, 100000000, 12000000, 12000000, 0, 0,
+               0, 0, tegra_pll_e_freq_table, 0, tegra_plle_ops, 0, clk_m);
+
+static const char *tegra_common_parent_names[] = {
+       "clk_m",
+};
+
+static struct clk *tegra_common_parents[] = {
+       &tegra_clk_m,
+};
+
+static struct clk tegra_clk_d;
+static struct clk_tegra tegra_clk_d_hw = {
+       .hw = {
+               .clk = &tegra_clk_d,
+       },
+       .flags = PERIPH_NO_RESET,
+       .reg = 0x34,
+       .reg_shift = 12,
+       .max_rate = 52000000,
+       .u.periph = {
+               .clk_num = 90,
+       },
+};
+
+static struct clk tegra_clk_d = {
+       .name = "clk_d",
+       .hw = &tegra_clk_d_hw.hw,
+       .ops = &tegra_clk_double_ops,
+       .parent = &tegra_clk_m,
+       .parent_names = tegra_common_parent_names,
+       .parents = tegra_common_parents,
+       .num_parents = ARRAY_SIZE(tegra_common_parent_names),
+};
+
+static struct clk tegra_cdev1;
+static struct clk_tegra tegra_cdev1_hw = {
+       .hw = {
+               .clk = &tegra_cdev1,
+       },
+       .fixed_rate = 26000000,
+       .u.periph = {
+               .clk_num = 94,
+       },
+};
+static struct clk tegra_cdev1 = {
+       .name = "cdev1",
+       .hw = &tegra_cdev1_hw.hw,
+       .ops = &tegra_cdev_clk_ops,
+       .flags = CLK_IS_ROOT,
+};
+
+/* dap_mclk2, belongs to the cdev2 pingroup. */
+static struct clk tegra_cdev2;
+static struct clk_tegra tegra_cdev2_hw = {
+       .hw = {
+               .clk = &tegra_cdev2,
+       },
+       .fixed_rate = 26000000,
+       .u.periph = {
+               .clk_num  = 93,
+       },
+};
+static struct clk tegra_cdev2 = {
+       .name = "cdev2",
+       .hw = &tegra_cdev2_hw.hw,
+       .ops = &tegra_cdev_clk_ops,
+       .flags = CLK_IS_ROOT,
+};
+
+/* initialized before peripheral clocks */
+static struct clk_mux_sel mux_audio_sync_clk[8+1];
+static const struct audio_sources {
+       const char *name;
+       int value;
+} mux_audio_sync_clk_sources[] = {
+       { .name = "spdif_in", .value = 0 },
+       { .name = "i2s1", .value = 1 },
+       { .name = "i2s2", .value = 2 },
+       { .name = "pll_a_out0", .value = 4 },
+#if 0 /* FIXME: not implemented */
+       { .name = "ac97", .value = 3 },
+       { .name = "ext_audio_clk2", .value = 5 },
+       { .name = "ext_audio_clk1", .value = 6 },
+       { .name = "ext_vimclk", .value = 7 },
+#endif
+       { NULL, 0 }
+};
+
+static const char *audio_parent_names[] = {
+       "spdif_in",
+       "i2s1",
+       "i2s2",
+       "dummy",
+       "pll_a_out0",
+       "dummy",
+       "dummy",
+       "dummy",
+};
+
+static struct clk *audio_parents[] = {
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+};
+
+static struct clk tegra_audio;
+static struct clk_tegra tegra_audio_hw = {
+       .hw = {
+               .clk = &tegra_audio,
+       },
+       .reg = 0x38,
+       .max_rate = 73728000,
+};
+DEFINE_CLK_TEGRA(audio, 0, &tegra_audio_sync_clk_ops, 0, audio_parent_names,
+               audio_parents, NULL);
+
+static const char *audio_2x_parent_names[] = {
+       "audio",
+};
+
+static struct clk *audio_2x_parents[] = {
+       &tegra_audio,
+};
+
+static struct clk tegra_audio_2x;
+static struct clk_tegra tegra_audio_2x_hw = {
+       .hw = {
+               .clk = &tegra_audio_2x,
+       },
+       .flags = PERIPH_NO_RESET,
+       .max_rate = 48000000,
+       .reg = 0x34,
+       .reg_shift = 8,
+       .u.periph = {
+               .clk_num = 89,
+       },
+};
+DEFINE_CLK_TEGRA(audio_2x, 0, &tegra_clk_double_ops, 0, audio_2x_parent_names,
+               audio_2x_parents, &tegra_audio);
+
+static struct clk_lookup tegra_audio_clk_lookups[] = {
+       { .con_id = "audio", .clk = &tegra_audio },
+       { .con_id = "audio_2x", .clk = &tegra_audio_2x }
+};
+
+/* This is called after peripheral clocks are initialized, as the
+ * audio_sync clock depends on some of the peripheral clocks.
+ */
+
+static void init_audio_sync_clock_mux(void)
+{
+       int i;
+       struct clk_mux_sel *sel = mux_audio_sync_clk;
+       const struct audio_sources *src = mux_audio_sync_clk_sources;
+       struct clk_lookup *lookup;
+
+       for (i = 0; src->name; i++, sel++, src++) {
+               sel->input = tegra_get_clock_by_name(src->name);
+               if (!sel->input)
+                       pr_err("%s: could not find clk %s\n", __func__,
+                               src->name);
+               audio_parents[src->value] = sel->input;
+               sel->value = src->value;
+       }
+
+       lookup = tegra_audio_clk_lookups;
+       for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
+               struct clk *c = lookup->clk;
+               struct clk_tegra *clk = to_clk_tegra(c->hw);
+               __clk_init(NULL, c);
+               INIT_LIST_HEAD(&clk->shared_bus_list);
+               clk->lookup.con_id = lookup->con_id;
+               clk->lookup.clk = c;
+               clkdev_add(&clk->lookup);
+               tegra_clk_add(c);
+       }
+}
+
+static const char *mux_cclk[] = {
+       "clk_m",
+       "pll_c",
+       "clk_32k",
+       "pll_m",
+       "pll_p",
+       "pll_p_out4",
+       "pll_p_out3",
+       "clk_d",
+       "pll_x",
+};
+
+
+static struct clk *mux_cclk_p[] = {
+       &tegra_clk_m,
+       &tegra_pll_c,
+       &tegra_clk_32k,
+       &tegra_pll_m,
+       &tegra_pll_p,
+       &tegra_pll_p_out4,
+       &tegra_pll_p_out3,
+       &tegra_clk_d,
+       &tegra_pll_x,
+};
+
+static const char *mux_sclk[] = {
+       "clk_m",
+       "pll_c_out1",
+       "pll_p_out4",
+       "pllp_p_out3",
+       "pll_p_out2",
+       "clk_d",
+       "clk_32k",
+       "pll_m_out1",
+};
+
+static struct clk *mux_sclk_p[] = {
+       &tegra_clk_m,
+       &tegra_pll_c_out1,
+       &tegra_pll_p_out4,
+       &tegra_pll_p_out3,
+       &tegra_pll_p_out2,
+       &tegra_clk_d,
+       &tegra_clk_32k,
+       &tegra_pll_m_out1,
+};
+
+static struct clk tegra_cclk;
+static struct clk_tegra tegra_cclk_hw = {
+       .hw = {
+               .clk = &tegra_cclk,
+       },
+       .reg = 0x20,
+       .max_rate = 1000000000,
+};
+DEFINE_CLK_TEGRA(cclk, 0, &tegra_super_ops, 0, mux_cclk,
+               mux_cclk_p, NULL);
+
+static const char *mux_twd[] = {
+       "cclk",
+};
+
+static struct clk *mux_twd_p[] = {
+       &tegra_cclk,
+};
+
+static struct clk tegra_clk_twd;
+static struct clk_tegra tegra_clk_twd_hw = {
+       .hw = {
+               .clk = &tegra_clk_twd,
+       },
+       .max_rate = 1000000000,
+       .mul = 1,
+       .div = 4,
+};
+
+static struct clk tegra_clk_twd = {
+       .name = "twd",
+       .ops = &tegra_twd_ops,
+       .hw = &tegra_clk_twd_hw.hw,
+       .parent = &tegra_cclk,
+       .parent_names = mux_twd,
+       .parents = mux_twd_p,
+       .num_parents = ARRAY_SIZE(mux_twd),
+};
+
+static struct clk tegra_sclk;
+static struct clk_tegra tegra_sclk_hw = {
+       .hw = {
+               .clk = &tegra_sclk,
+       },
+       .reg = 0x28,
+       .max_rate = 240000000,
+       .min_rate = 120000000,
+};
+DEFINE_CLK_TEGRA(sclk, 0, &tegra_super_ops, 0, mux_sclk,
+               mux_sclk_p, NULL);
+
+static const char *tegra_cop_parent_names[] = {
+       "tegra_sclk",
+};
+
+static struct clk *tegra_cop_parents[] = {
+       &tegra_sclk,
+};
+
+static struct clk tegra_cop;
+static struct clk_tegra tegra_cop_hw = {
+       .hw = {
+               .clk = &tegra_cop,
+       },
+       .max_rate  = 240000000,
+       .reset = &tegra2_cop_clk_reset,
+};
+DEFINE_CLK_TEGRA(cop, 0, &tegra_cop_ops, CLK_SET_RATE_PARENT,
+               tegra_cop_parent_names, tegra_cop_parents, &tegra_sclk);
+
+static const char *tegra_hclk_parent_names[] = {
+       "tegra_sclk",
+};
+
+static struct clk *tegra_hclk_parents[] = {
+       &tegra_sclk,
+};
+
+static struct clk tegra_hclk;
+static struct clk_tegra tegra_hclk_hw = {
+       .hw = {
+               .clk = &tegra_hclk,
+       },
+       .flags = DIV_BUS,
+       .reg = 0x30,
+       .reg_shift = 4,
+       .max_rate = 240000000,
+};
+DEFINE_CLK_TEGRA(hclk, 0, &tegra_bus_ops, 0, tegra_hclk_parent_names,
+               tegra_hclk_parents, &tegra_sclk);
+
+static const char *tegra_pclk_parent_names[] = {
+       "tegra_hclk",
+};
+
+static struct clk *tegra_pclk_parents[] = {
+       &tegra_hclk,
+};
+
+static struct clk tegra_pclk;
+static struct clk_tegra tegra_pclk_hw = {
+       .hw = {
+               .clk = &tegra_pclk,
+       },
+       .flags = DIV_BUS,
+       .reg = 0x30,
+       .reg_shift = 0,
+       .max_rate = 120000000,
+};
+DEFINE_CLK_TEGRA(pclk, 0, &tegra_bus_ops, 0, tegra_pclk_parent_names,
+               tegra_pclk_parents, &tegra_hclk);
+
+static const char *tegra_blink_parent_names[] = {
+       "clk_32k",
+};
+
+static struct clk *tegra_blink_parents[] = {
+       &tegra_clk_32k,
+};
+
+static struct clk tegra_blink;
+static struct clk_tegra tegra_blink_hw = {
+       .hw = {
+               .clk = &tegra_blink,
+       },
+       .reg = 0x40,
+       .max_rate = 32768,
+};
+DEFINE_CLK_TEGRA(blink, 0, &tegra_blink_clk_ops, 0, tegra_blink_parent_names,
+               tegra_blink_parents, &tegra_clk_32k);
+
+static const char *mux_pllm_pllc_pllp_plla[] = {
+       "pll_m",
+       "pll_c",
+       "pll_p",
+       "pll_a_out0",
+};
+
+static struct clk *mux_pllm_pllc_pllp_plla_p[] = {
+       &tegra_pll_m,
+       &tegra_pll_c,
+       &tegra_pll_p,
+       &tegra_pll_a_out0,
+};
+
+static const char *mux_pllm_pllc_pllp_clkm[] = {
+       "pll_m",
+       "pll_c",
+       "pll_p",
+       "clk_m",
+};
+
+static struct clk *mux_pllm_pllc_pllp_clkm_p[] = {
+       &tegra_pll_m,
+       &tegra_pll_c,
+       &tegra_pll_p,
+       &tegra_clk_m,
+};
+
+static const char *mux_pllp_pllc_pllm_clkm[] = {
+       "pll_p",
+       "pll_c",
+       "pll_m",
+       "clk_m",
+};
+
+static struct clk *mux_pllp_pllc_pllm_clkm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_c,
+       &tegra_pll_m,
+       &tegra_clk_m,
+};
+
+static const char *mux_pllaout0_audio2x_pllp_clkm[] = {
+       "pll_a_out0",
+       "audio_2x",
+       "pll_p",
+       "clk_m",
+};
+
+static struct clk *mux_pllaout0_audio2x_pllp_clkm_p[] = {
+       &tegra_pll_a_out0,
+       &tegra_audio_2x,
+       &tegra_pll_p,
+       &tegra_clk_m,
+};
+
+static const char *mux_pllp_plld_pllc_clkm[] = {
+       "pllp",
+       "pll_d_out0",
+       "pll_c",
+       "clk_m",
+};
+
+static struct clk *mux_pllp_plld_pllc_clkm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_d_out0,
+       &tegra_pll_c,
+       &tegra_clk_m,
+};
+
+static const char *mux_pllp_pllc_audio_clkm_clk32[] = {
+       "pll_p",
+       "pll_c",
+       "audio",
+       "clk_m",
+       "clk_32k",
+};
+
+static struct clk *mux_pllp_pllc_audio_clkm_clk32_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_c,
+       &tegra_audio,
+       &tegra_clk_m,
+       &tegra_clk_32k,
+};
+
+static const char *mux_pllp_pllc_pllm[] = {
+       "pll_p",
+       "pll_c",
+       "pll_m"
+};
+
+static struct clk *mux_pllp_pllc_pllm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_c,
+       &tegra_pll_m,
+};
+
+static const char *mux_clk_m[] = {
+       "clk_m",
+};
+
+static struct clk *mux_clk_m_p[] = {
+       &tegra_clk_m,
+};
+
+static const char *mux_pllp_out3[] = {
+       "pll_p_out3",
+};
+
+static struct clk *mux_pllp_out3_p[] = {
+       &tegra_pll_p_out3,
+};
+
+static const char *mux_plld[] = {
+       "pll_d",
+};
+
+static struct clk *mux_plld_p[] = {
+       &tegra_pll_d,
+};
+
+static const char *mux_clk_32k[] = {
+       "clk_32k",
+};
+
+static struct clk *mux_clk_32k_p[] = {
+       &tegra_clk_32k,
+};
+
+static const char *mux_pclk[] = {
+       "pclk",
+};
+
+static struct clk *mux_pclk_p[] = {
+       &tegra_pclk,
+};
+
+static struct clk tegra_emc;
+static struct clk_tegra tegra_emc_hw = {
+       .hw = {
+               .clk = &tegra_emc,
+       },
+       .reg = 0x19c,
+       .max_rate = 800000000,
+       .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
+       .reset = &tegra2_periph_clk_reset,
+       .u.periph = {
+               .clk_num = 57,
+       },
+};
+DEFINE_CLK_TEGRA(emc, 0, &tegra_emc_clk_ops, 0, mux_pllm_pllc_pllp_clkm,
+               mux_pllm_pllc_pllp_clkm_p, NULL);
+
+#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg,  \
+               _max, _inputs, _flags)                  \
+       static struct clk tegra_##_name;                \
+       static struct clk_tegra tegra_##_name##_hw = {  \
+               .hw = {                                 \
+                       .clk = &tegra_##_name,          \
+               },                                      \
+               .lookup = {                             \
+                       .dev_id = _dev,                 \
+                       .con_id = _con,                 \
+               },                                      \
+               .reg = _reg,                            \
+               .flags = _flags,                        \
+               .max_rate = _max,                       \
+               .u.periph = {                           \
+                       .clk_num = _clk_num,            \
+               },                                      \
+               .reset = tegra2_periph_clk_reset,       \
+       };                                              \
+       static struct clk tegra_##_name = {             \
+               .name = #_name,                         \
+               .ops = &tegra_periph_clk_ops,           \
+               .hw = &tegra_##_name##_hw.hw,           \
+               .parent_names = _inputs,                \
+               .parents = _inputs##_p,                 \
+               .num_parents = ARRAY_SIZE(_inputs),     \
+       };
+
+PERIPH_CLK(apbdma,     "tegra-apbdma",         NULL,   34,     0,      108000000, mux_pclk,                    0);
+PERIPH_CLK(rtc,                "rtc-tegra",            NULL,   4,      0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET);
+PERIPH_CLK(timer,      "timer",                NULL,   5,      0,      26000000,  mux_clk_m,                   0);
+PERIPH_CLK(i2s1,       "tegra20-i2s.0",        NULL,   11,     0x100,  26000000,  mux_pllaout0_audio2x_pllp_clkm,      MUX | DIV_U71);
+PERIPH_CLK(i2s2,       "tegra20-i2s.1",        NULL,   18,     0x104,  26000000,  mux_pllaout0_audio2x_pllp_clkm,      MUX | DIV_U71);
+PERIPH_CLK(spdif_out,  "spdif_out",            NULL,   10,     0x108,  100000000, mux_pllaout0_audio2x_pllp_clkm,      MUX | DIV_U71);
+PERIPH_CLK(spdif_in,   "spdif_in",             NULL,   10,     0x10c,  100000000, mux_pllp_pllc_pllm,          MUX | DIV_U71);
+PERIPH_CLK(pwm,                "tegra-pwm",            NULL,   17,     0x110,  432000000, mux_pllp_pllc_audio_clkm_clk32,      MUX | DIV_U71 | MUX_PWM);
+PERIPH_CLK(spi,                "spi",                  NULL,   43,     0x114,  40000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(xio,                "xio",                  NULL,   45,     0x120,  150000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(twc,                "twc",                  NULL,   16,     0x12c,  150000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(sbc1,       "spi_tegra.0",          NULL,   41,     0x134,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(sbc2,       "spi_tegra.1",          NULL,   44,     0x118,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(sbc3,       "spi_tegra.2",          NULL,   46,     0x11c,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(sbc4,       "spi_tegra.3",          NULL,   68,     0x1b4,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(ide,                "ide",                  NULL,   25,     0x144,  100000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(ndflash,    "tegra_nand",           NULL,   13,     0x160,  164000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(vfir,       "vfir",                 NULL,   7,      0x168,  72000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(sdmmc1,     "sdhci-tegra.0",        NULL,   14,     0x150,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(sdmmc2,     "sdhci-tegra.1",        NULL,   9,      0x154,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(sdmmc3,     "sdhci-tegra.2",        NULL,   69,     0x1bc,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(sdmmc4,     "sdhci-tegra.3",        NULL,   15,     0x164,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(vcp,                "tegra-avp",            "vcp",  29,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(bsea,       "tegra-avp",            "bsea", 62,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(bsev,       "tegra-aes",            "bsev", 63,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(vde,                "tegra-avp",            "vde",  61,     0x1c8,  250000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage and process_id */
+PERIPH_CLK(csite,      "csite",                NULL,   73,     0x1d4,  144000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* max rate ??? */
+/* FIXME: what is la? */
+PERIPH_CLK(la,         "la",                   NULL,   76,     0x1f8,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(owr,                "tegra_w1",             NULL,   71,     0x1cc,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(nor,                "nor",                  NULL,   42,     0x1d0,  92000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(mipi,       "mipi",                 NULL,   50,     0x174,  60000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(i2c1,       "tegra-i2c.0",          "div-clk", 12,  0x124,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16);
+PERIPH_CLK(i2c2,       "tegra-i2c.1",          "div-clk", 54,  0x198,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16);
+PERIPH_CLK(i2c3,       "tegra-i2c.2",          "div-clk", 67,  0x1b8,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16);
+PERIPH_CLK(dvc,                "tegra-i2c.3",          "div-clk", 47,  0x128,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16);
+PERIPH_CLK(uarta,      "tegra-uart.0",         NULL,   6,      0x178,  600000000, mux_pllp_pllc_pllm_clkm,     MUX);
+PERIPH_CLK(uartb,      "tegra-uart.1",         NULL,   7,      0x17c,  600000000, mux_pllp_pllc_pllm_clkm,     MUX);
+PERIPH_CLK(uartc,      "tegra-uart.2",         NULL,   55,     0x1a0,  600000000, mux_pllp_pllc_pllm_clkm,     MUX);
+PERIPH_CLK(uartd,      "tegra-uart.3",         NULL,   65,     0x1c0,  600000000, mux_pllp_pllc_pllm_clkm,     MUX);
+PERIPH_CLK(uarte,      "tegra-uart.4",         NULL,   66,     0x1c4,  600000000, mux_pllp_pllc_pllm_clkm,     MUX);
+PERIPH_CLK(3d,         "3d",                   NULL,   24,     0x158,  300000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_MANUAL_RESET); /* scales with voltage and process_id */
+PERIPH_CLK(2d,         "2d",                   NULL,   21,     0x15c,  300000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71); /* scales with voltage and process_id */
+PERIPH_CLK(vi,         "tegra_camera",         "vi",   20,     0x148,  150000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71); /* scales with voltage and process_id */
+PERIPH_CLK(vi_sensor,  "tegra_camera",         "vi_sensor",    20,     0x1a8,  150000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_NO_RESET); /* scales with voltage and process_id */
+PERIPH_CLK(epp,                "epp",                  NULL,   19,     0x16c,  300000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71); /* scales with voltage and process_id */
+PERIPH_CLK(mpe,                "mpe",                  NULL,   60,     0x170,  250000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71); /* scales with voltage and process_id */
+PERIPH_CLK(host1x,     "host1x",               NULL,   28,     0x180,  166000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71); /* scales with voltage and process_id */
+PERIPH_CLK(cve,                "cve",                  NULL,   49,     0x140,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(tvo,                "tvo",                  NULL,   49,     0x188,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(hdmi,       "hdmi",                 NULL,   51,     0x18c,  600000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(tvdac,      "tvdac",                NULL,   53,     0x194,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(disp1,      "tegradc.0",            NULL,   27,     0x138,  600000000, mux_pllp_plld_pllc_clkm,     MUX); /* scales with voltage and process_id */
+PERIPH_CLK(disp2,      "tegradc.1",            NULL,   26,     0x13c,  600000000, mux_pllp_plld_pllc_clkm,     MUX); /* scales with voltage and process_id */
+PERIPH_CLK(usbd,       "fsl-tegra-udc",        NULL,   22,     0,      480000000, mux_clk_m,                   0); /* requires min voltage */
+PERIPH_CLK(usb2,       "tegra-ehci.1",         NULL,   58,     0,      480000000, mux_clk_m,                   0); /* requires min voltage */
+PERIPH_CLK(usb3,       "tegra-ehci.2",         NULL,   59,     0,      480000000, mux_clk_m,                   0); /* requires min voltage */
+PERIPH_CLK(dsi,                "dsi",                  NULL,   48,     0,      500000000, mux_plld,                    0); /* scales with voltage */
+PERIPH_CLK(csi,                "tegra_camera",         "csi",  52,     0,      72000000,  mux_pllp_out3,               0);
+PERIPH_CLK(isp,                "tegra_camera",         "isp",  23,     0,      150000000, mux_clk_m,                   0); /* same frequency as VI */
+PERIPH_CLK(csus,       "tegra_camera",         "csus", 92,     0,      150000000, mux_clk_m,                   PERIPH_NO_RESET);
+PERIPH_CLK(pex,                NULL,                   "pex",  70,     0,      26000000,  mux_clk_m,                   PERIPH_MANUAL_RESET);
+PERIPH_CLK(afi,                NULL,                   "afi",  72,     0,      26000000,  mux_clk_m,                   PERIPH_MANUAL_RESET);
+PERIPH_CLK(pcie_xclk,  NULL,             "pcie_xclk",  74,     0,      26000000,  mux_clk_m,                   PERIPH_MANUAL_RESET);
+
+static struct clk *tegra_list_clks[] = {
+       &tegra_apbdma,
+       &tegra_rtc,
+       &tegra_i2s1,
+       &tegra_i2s2,
+       &tegra_spdif_out,
+       &tegra_spdif_in,
+       &tegra_pwm,
+       &tegra_spi,
+       &tegra_xio,
+       &tegra_twc,
+       &tegra_sbc1,
+       &tegra_sbc2,
+       &tegra_sbc3,
+       &tegra_sbc4,
+       &tegra_ide,
+       &tegra_ndflash,
+       &tegra_vfir,
+       &tegra_sdmmc1,
+       &tegra_sdmmc2,
+       &tegra_sdmmc3,
+       &tegra_sdmmc4,
+       &tegra_vcp,
+       &tegra_bsea,
+       &tegra_bsev,
+       &tegra_vde,
+       &tegra_csite,
+       &tegra_la,
+       &tegra_owr,
+       &tegra_nor,
+       &tegra_mipi,
+       &tegra_i2c1,
+       &tegra_i2c2,
+       &tegra_i2c3,
+       &tegra_dvc,
+       &tegra_uarta,
+       &tegra_uartb,
+       &tegra_uartc,
+       &tegra_uartd,
+       &tegra_uarte,
+       &tegra_3d,
+       &tegra_2d,
+       &tegra_vi,
+       &tegra_vi_sensor,
+       &tegra_epp,
+       &tegra_mpe,
+       &tegra_host1x,
+       &tegra_cve,
+       &tegra_tvo,
+       &tegra_hdmi,
+       &tegra_tvdac,
+       &tegra_disp1,
+       &tegra_disp2,
+       &tegra_usbd,
+       &tegra_usb2,
+       &tegra_usb3,
+       &tegra_dsi,
+       &tegra_csi,
+       &tegra_isp,
+       &tegra_csus,
+       &tegra_pex,
+       &tegra_afi,
+       &tegra_pcie_xclk,
+};
+
+#define CLK_DUPLICATE(_name, _dev, _con)       \
+       {                                       \
+               .name   = _name,                \
+               .lookup = {                     \
+                       .dev_id = _dev,         \
+                       .con_id = _con,         \
+               },                              \
+       }
+
+/* Some clocks may be used by different drivers depending on the board
+ * configuration.  List those here to register them twice in the clock lookup
+ * table under two names.
+ */
+static struct clk_duplicate tegra_clk_duplicates[] = {
+       CLK_DUPLICATE("uarta",  "serial8250.0", NULL),
+       CLK_DUPLICATE("uartb",  "serial8250.1", NULL),
+       CLK_DUPLICATE("uartc",  "serial8250.2", NULL),
+       CLK_DUPLICATE("uartd",  "serial8250.3", NULL),
+       CLK_DUPLICATE("uarte",  "serial8250.4", NULL),
+       CLK_DUPLICATE("usbd",   "utmip-pad",    NULL),
+       CLK_DUPLICATE("usbd",   "tegra-ehci.0", NULL),
+       CLK_DUPLICATE("usbd",   "tegra-otg",    NULL),
+       CLK_DUPLICATE("hdmi",   "tegradc.0",    "hdmi"),
+       CLK_DUPLICATE("hdmi",   "tegradc.1",    "hdmi"),
+       CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"),
+       CLK_DUPLICATE("2d",     "tegra_grhost", "gr2d"),
+       CLK_DUPLICATE("3d",     "tegra_grhost", "gr3d"),
+       CLK_DUPLICATE("epp",    "tegra_grhost", "epp"),
+       CLK_DUPLICATE("mpe",    "tegra_grhost", "mpe"),
+       CLK_DUPLICATE("cop",    "tegra-avp",    "cop"),
+       CLK_DUPLICATE("vde",    "tegra-aes",    "vde"),
+       CLK_DUPLICATE("cclk",   NULL,           "cpu"),
+       CLK_DUPLICATE("twd",    "smp_twd",      NULL),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.0", "fast-clk"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"),
+};
+
+#define CLK(dev, con, ck)      \
+       {                       \
+               .dev_id = dev,  \
+               .con_id = con,  \
+               .clk    = ck,   \
+       }
+
+static struct clk *tegra_ptr_clks[] = {
+       &tegra_clk_32k,
+       &tegra_pll_s,
+       &tegra_clk_m,
+       &tegra_pll_m,
+       &tegra_pll_m_out1,
+       &tegra_pll_c,
+       &tegra_pll_c_out1,
+       &tegra_pll_p,
+       &tegra_pll_p_out1,
+       &tegra_pll_p_out2,
+       &tegra_pll_p_out3,
+       &tegra_pll_p_out4,
+       &tegra_pll_a,
+       &tegra_pll_a_out0,
+       &tegra_pll_d,
+       &tegra_pll_d_out0,
+       &tegra_pll_u,
+       &tegra_pll_x,
+       &tegra_pll_e,
+       &tegra_cclk,
+       &tegra_clk_twd,
+       &tegra_sclk,
+       &tegra_hclk,
+       &tegra_pclk,
+       &tegra_clk_d,
+       &tegra_cdev1,
+       &tegra_cdev2,
+       &tegra_blink,
+       &tegra_cop,
+       &tegra_emc,
+};
+
+static void tegra2_init_one_clock(struct clk *c)
+{
+       struct clk_tegra *clk = to_clk_tegra(c->hw);
+       int ret;
+
+       ret = __clk_init(NULL, c);
+       if (ret)
+               pr_err("clk init failed %s\n", __clk_get_name(c));
+
+       INIT_LIST_HEAD(&clk->shared_bus_list);
+       if (!clk->lookup.dev_id && !clk->lookup.con_id)
+               clk->lookup.con_id = c->name;
+       clk->lookup.clk = c;
+       clkdev_add(&clk->lookup);
+       tegra_clk_add(c);
+}
+
+void __init tegra2_init_clocks(void)
+{
+       int i;
+       struct clk *c;
+
+       for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
+               tegra2_init_one_clock(tegra_ptr_clks[i]);
+
+       for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
+               tegra2_init_one_clock(tegra_list_clks[i]);
+
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
+               c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
+               if (!c) {
+                       pr_err("%s: Unknown duplicate clock %s\n", __func__,
+                               tegra_clk_duplicates[i].name);
+                       continue;
+               }
+
+               tegra_clk_duplicates[i].lookup.clk = c;
+               clkdev_add(&tegra_clk_duplicates[i].lookup);
+       }
+
+       init_audio_sync_clock_mux();
+}
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
deleted file mode 100644 (file)
index a703844..0000000
+++ /dev/null
@@ -1,2484 +0,0 @@
-/*
- * arch/arm/mach-tegra/tegra2_clocks.c
- *
- * Copyright (C) 2010 Google, Inc.
- *
- * Author:
- *     Colin Cross <ccross@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-#include <linux/clk.h>
-
-#include <mach/iomap.h>
-#include <mach/suspend.h>
-
-#include "clock.h"
-#include "fuse.h"
-#include "tegra2_emc.h"
-
-#define RST_DEVICES                    0x004
-#define RST_DEVICES_SET                        0x300
-#define RST_DEVICES_CLR                        0x304
-#define RST_DEVICES_NUM                        3
-
-#define CLK_OUT_ENB                    0x010
-#define CLK_OUT_ENB_SET                        0x320
-#define CLK_OUT_ENB_CLR                        0x324
-#define CLK_OUT_ENB_NUM                        3
-
-#define CLK_MASK_ARM                   0x44
-#define MISC_CLK_ENB                   0x48
-
-#define OSC_CTRL                       0x50
-#define OSC_CTRL_OSC_FREQ_MASK         (3<<30)
-#define OSC_CTRL_OSC_FREQ_13MHZ                (0<<30)
-#define OSC_CTRL_OSC_FREQ_19_2MHZ      (1<<30)
-#define OSC_CTRL_OSC_FREQ_12MHZ                (2<<30)
-#define OSC_CTRL_OSC_FREQ_26MHZ                (3<<30)
-#define OSC_CTRL_MASK                  (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
-
-#define OSC_FREQ_DET                   0x58
-#define OSC_FREQ_DET_TRIG              (1<<31)
-
-#define OSC_FREQ_DET_STATUS            0x5C
-#define OSC_FREQ_DET_BUSY              (1<<31)
-#define OSC_FREQ_DET_CNT_MASK          0xFFFF
-
-#define PERIPH_CLK_SOURCE_I2S1         0x100
-#define PERIPH_CLK_SOURCE_EMC          0x19c
-#define PERIPH_CLK_SOURCE_OSC          0x1fc
-#define PERIPH_CLK_SOURCE_NUM \
-       ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
-
-#define PERIPH_CLK_SOURCE_MASK         (3<<30)
-#define PERIPH_CLK_SOURCE_SHIFT                30
-#define PERIPH_CLK_SOURCE_PWM_MASK     (7<<28)
-#define PERIPH_CLK_SOURCE_PWM_SHIFT    28
-#define PERIPH_CLK_SOURCE_ENABLE       (1<<28)
-#define PERIPH_CLK_SOURCE_DIVU71_MASK  0xFF
-#define PERIPH_CLK_SOURCE_DIVU16_MASK  0xFFFF
-#define PERIPH_CLK_SOURCE_DIV_SHIFT    0
-
-#define SDMMC_CLK_INT_FB_SEL           (1 << 23)
-#define SDMMC_CLK_INT_FB_DLY_SHIFT     16
-#define SDMMC_CLK_INT_FB_DLY_MASK      (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
-
-#define PLL_BASE                       0x0
-#define PLL_BASE_BYPASS                        (1<<31)
-#define PLL_BASE_ENABLE                        (1<<30)
-#define PLL_BASE_REF_ENABLE            (1<<29)
-#define PLL_BASE_OVERRIDE              (1<<28)
-#define PLL_BASE_DIVP_MASK             (0x7<<20)
-#define PLL_BASE_DIVP_SHIFT            20
-#define PLL_BASE_DIVN_MASK             (0x3FF<<8)
-#define PLL_BASE_DIVN_SHIFT            8
-#define PLL_BASE_DIVM_MASK             (0x1F)
-#define PLL_BASE_DIVM_SHIFT            0
-
-#define PLL_OUT_RATIO_MASK             (0xFF<<8)
-#define PLL_OUT_RATIO_SHIFT            8
-#define PLL_OUT_OVERRIDE               (1<<2)
-#define PLL_OUT_CLKEN                  (1<<1)
-#define PLL_OUT_RESET_DISABLE          (1<<0)
-
-#define PLL_MISC(c)                    (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
-
-#define PLL_MISC_DCCON_SHIFT           20
-#define PLL_MISC_CPCON_SHIFT           8
-#define PLL_MISC_CPCON_MASK            (0xF<<PLL_MISC_CPCON_SHIFT)
-#define PLL_MISC_LFCON_SHIFT           4
-#define PLL_MISC_LFCON_MASK            (0xF<<PLL_MISC_LFCON_SHIFT)
-#define PLL_MISC_VCOCON_SHIFT          0
-#define PLL_MISC_VCOCON_MASK           (0xF<<PLL_MISC_VCOCON_SHIFT)
-
-#define PLLU_BASE_POST_DIV             (1<<20)
-
-#define PLLD_MISC_CLKENABLE            (1<<30)
-#define PLLD_MISC_DIV_RST              (1<<23)
-#define PLLD_MISC_DCCON_SHIFT          12
-
-#define PLLE_MISC_READY                        (1 << 15)
-
-#define PERIPH_CLK_TO_ENB_REG(c)       ((c->u.periph.clk_num / 32) * 4)
-#define PERIPH_CLK_TO_ENB_SET_REG(c)   ((c->u.periph.clk_num / 32) * 8)
-#define PERIPH_CLK_TO_ENB_BIT(c)       (1 << (c->u.periph.clk_num % 32))
-
-#define SUPER_CLK_MUX                  0x00
-#define SUPER_STATE_SHIFT              28
-#define SUPER_STATE_MASK               (0xF << SUPER_STATE_SHIFT)
-#define SUPER_STATE_STANDBY            (0x0 << SUPER_STATE_SHIFT)
-#define SUPER_STATE_IDLE               (0x1 << SUPER_STATE_SHIFT)
-#define SUPER_STATE_RUN                        (0x2 << SUPER_STATE_SHIFT)
-#define SUPER_STATE_IRQ                        (0x3 << SUPER_STATE_SHIFT)
-#define SUPER_STATE_FIQ                        (0x4 << SUPER_STATE_SHIFT)
-#define SUPER_SOURCE_MASK              0xF
-#define        SUPER_FIQ_SOURCE_SHIFT          12
-#define        SUPER_IRQ_SOURCE_SHIFT          8
-#define        SUPER_RUN_SOURCE_SHIFT          4
-#define        SUPER_IDLE_SOURCE_SHIFT         0
-
-#define SUPER_CLK_DIVIDER              0x04
-
-#define BUS_CLK_DISABLE                        (1<<3)
-#define BUS_CLK_DIV_MASK               0x3
-
-#define PMC_CTRL                       0x0
- #define PMC_CTRL_BLINK_ENB            (1 << 7)
-
-#define PMC_DPD_PADS_ORIDE             0x1c
- #define PMC_DPD_PADS_ORIDE_BLINK_ENB  (1 << 20)
-
-#define PMC_BLINK_TIMER_DATA_ON_SHIFT  0
-#define PMC_BLINK_TIMER_DATA_ON_MASK   0x7fff
-#define PMC_BLINK_TIMER_ENB            (1 << 15)
-#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
-#define PMC_BLINK_TIMER_DATA_OFF_MASK  0xffff
-
-static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
-static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
-/*
- * Some clocks share a register with other clocks.  Any clock op that
- * non-atomically modifies a register used by another clock must lock
- * clock_register_lock first.
- */
-static DEFINE_SPINLOCK(clock_register_lock);
-
-/*
- * Some peripheral clocks share an enable bit, so refcount the enable bits
- * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
- */
-static int tegra_periph_clk_enable_refcount[3 * 32];
-
-#define clk_writel(value, reg) \
-       __raw_writel(value, reg_clk_base + (reg))
-#define clk_readl(reg) \
-       __raw_readl(reg_clk_base + (reg))
-#define pmc_writel(value, reg) \
-       __raw_writel(value, reg_pmc_base + (reg))
-#define pmc_readl(reg) \
-       __raw_readl(reg_pmc_base + (reg))
-
-static unsigned long clk_measure_input_freq(void)
-{
-       u32 clock_autodetect;
-       clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
-       do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
-       clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
-       if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
-               return 12000000;
-       } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
-               return 13000000;
-       } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
-               return 19200000;
-       } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
-               return 26000000;
-       } else {
-               pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
-               BUG();
-               return 0;
-       }
-}
-
-static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
-{
-       s64 divider_u71 = parent_rate * 2;
-       divider_u71 += rate - 1;
-       do_div(divider_u71, rate);
-
-       if (divider_u71 - 2 < 0)
-               return 0;
-
-       if (divider_u71 - 2 > 255)
-               return -EINVAL;
-
-       return divider_u71 - 2;
-}
-
-static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
-{
-       s64 divider_u16;
-
-       divider_u16 = parent_rate;
-       divider_u16 += rate - 1;
-       do_div(divider_u16, rate);
-
-       if (divider_u16 - 1 < 0)
-               return 0;
-
-       if (divider_u16 - 1 > 255)
-               return -EINVAL;
-
-       return divider_u16 - 1;
-}
-
-/* clk_m functions */
-static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
-{
-       u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
-
-       c->rate = clk_measure_input_freq();
-       switch (c->rate) {
-       case 12000000:
-               auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
-               break;
-       case 13000000:
-               auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
-               break;
-       case 19200000:
-               auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
-               break;
-       case 26000000:
-               auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
-               break;
-       default:
-               pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
-               BUG();
-       }
-       clk_writel(auto_clock_control, OSC_CTRL);
-       return c->rate;
-}
-
-static void tegra2_clk_m_init(struct clk *c)
-{
-       pr_debug("%s on clock %s\n", __func__, c->name);
-       tegra2_clk_m_autodetect_rate(c);
-}
-
-static int tegra2_clk_m_enable(struct clk *c)
-{
-       pr_debug("%s on clock %s\n", __func__, c->name);
-       return 0;
-}
-
-static void tegra2_clk_m_disable(struct clk *c)
-{
-       pr_debug("%s on clock %s\n", __func__, c->name);
-       BUG();
-}
-
-static struct clk_ops tegra_clk_m_ops = {
-       .init           = tegra2_clk_m_init,
-       .enable         = tegra2_clk_m_enable,
-       .disable        = tegra2_clk_m_disable,
-};
-
-/* super clock functions */
-/* "super clocks" on tegra have two-stage muxes and a clock skipping
- * super divider.  We will ignore the clock skipping divider, since we
- * can't lower the voltage when using the clock skip, but we can if we
- * lower the PLL frequency.
- */
-static void tegra2_super_clk_init(struct clk *c)
-{
-       u32 val;
-       int source;
-       int shift;
-       const struct clk_mux_sel *sel;
-       val = clk_readl(c->reg + SUPER_CLK_MUX);
-       c->state = ON;
-       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
-               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
-       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
-               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
-       source = (val >> shift) & SUPER_SOURCE_MASK;
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->value == source)
-                       break;
-       }
-       BUG_ON(sel->input == NULL);
-       c->parent = sel->input;
-}
-
-static int tegra2_super_clk_enable(struct clk *c)
-{
-       clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
-       return 0;
-}
-
-static void tegra2_super_clk_disable(struct clk *c)
-{
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
-       /* oops - don't disable the CPU clock! */
-       BUG();
-}
-
-static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
-{
-       u32 val;
-       const struct clk_mux_sel *sel;
-       int shift;
-
-       val = clk_readl(c->reg + SUPER_CLK_MUX);
-       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
-               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
-       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
-               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       val &= ~(SUPER_SOURCE_MASK << shift);
-                       val |= sel->value << shift;
-
-                       if (c->refcnt)
-                               clk_enable(p);
-
-                       clk_writel(val, c->reg);
-
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
-
-                       clk_reparent(c, p);
-                       return 0;
-               }
-       }
-       return -EINVAL;
-}
-
-/*
- * Super clocks have "clock skippers" instead of dividers.  Dividing using
- * a clock skipper does not allow the voltage to be scaled down, so instead
- * adjust the rate of the parent clock.  This requires that the parent of a
- * super clock have no other children, otherwise the rate will change
- * underneath the other children.
- */
-static int tegra2_super_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       return clk_set_rate(c->parent, rate);
-}
-
-static struct clk_ops tegra_super_ops = {
-       .init                   = tegra2_super_clk_init,
-       .enable                 = tegra2_super_clk_enable,
-       .disable                = tegra2_super_clk_disable,
-       .set_parent             = tegra2_super_clk_set_parent,
-       .set_rate               = tegra2_super_clk_set_rate,
-};
-
-/* virtual cpu clock functions */
-/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
-   To change the frequency of these clocks, the parent pll may need to be
-   reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
-   and then the clock moved back to the pll.  To hide this sequence, a virtual
-   clock handles it.
- */
-static void tegra2_cpu_clk_init(struct clk *c)
-{
-}
-
-static int tegra2_cpu_clk_enable(struct clk *c)
-{
-       return 0;
-}
-
-static void tegra2_cpu_clk_disable(struct clk *c)
-{
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
-       /* oops - don't disable the CPU clock! */
-       BUG();
-}
-
-static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       int ret;
-       /*
-        * Take an extra reference to the main pll so it doesn't turn
-        * off when we move the cpu off of it
-        */
-       clk_enable(c->u.cpu.main);
-
-       ret = clk_set_parent(c->parent, c->u.cpu.backup);
-       if (ret) {
-               pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name);
-               goto out;
-       }
-
-       if (rate == clk_get_rate(c->u.cpu.backup))
-               goto out;
-
-       ret = clk_set_rate(c->u.cpu.main, rate);
-       if (ret) {
-               pr_err("Failed to change cpu pll to %lu\n", rate);
-               goto out;
-       }
-
-       ret = clk_set_parent(c->parent, c->u.cpu.main);
-       if (ret) {
-               pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
-               goto out;
-       }
-
-out:
-       clk_disable(c->u.cpu.main);
-       return ret;
-}
-
-static struct clk_ops tegra_cpu_ops = {
-       .init     = tegra2_cpu_clk_init,
-       .enable   = tegra2_cpu_clk_enable,
-       .disable  = tegra2_cpu_clk_disable,
-       .set_rate = tegra2_cpu_clk_set_rate,
-};
-
-/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
- * reset the COP block (i.e. AVP) */
-static void tegra2_cop_clk_reset(struct clk *c, bool assert)
-{
-       unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
-
-       pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
-       clk_writel(1 << 1, reg);
-}
-
-static struct clk_ops tegra_cop_ops = {
-       .reset    = tegra2_cop_clk_reset,
-};
-
-/* bus clock functions */
-static void tegra2_bus_clk_init(struct clk *c)
-{
-       u32 val = clk_readl(c->reg);
-       c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
-       c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
-       c->mul = 1;
-}
-
-static int tegra2_bus_clk_enable(struct clk *c)
-{
-       u32 val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&clock_register_lock, flags);
-
-       val = clk_readl(c->reg);
-       val &= ~(BUS_CLK_DISABLE << c->reg_shift);
-       clk_writel(val, c->reg);
-
-       spin_unlock_irqrestore(&clock_register_lock, flags);
-
-       return 0;
-}
-
-static void tegra2_bus_clk_disable(struct clk *c)
-{
-       u32 val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&clock_register_lock, flags);
-
-       val = clk_readl(c->reg);
-       val |= BUS_CLK_DISABLE << c->reg_shift;
-       clk_writel(val, c->reg);
-
-       spin_unlock_irqrestore(&clock_register_lock, flags);
-}
-
-static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       u32 val;
-       unsigned long parent_rate = clk_get_rate(c->parent);
-       unsigned long flags;
-       int ret = -EINVAL;
-       int i;
-
-       spin_lock_irqsave(&clock_register_lock, flags);
-
-       val = clk_readl(c->reg);
-       for (i = 1; i <= 4; i++) {
-               if (rate == parent_rate / i) {
-                       val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
-                       val |= (i - 1) << c->reg_shift;
-                       clk_writel(val, c->reg);
-                       c->div = i;
-                       c->mul = 1;
-                       ret = 0;
-                       break;
-               }
-       }
-
-       spin_unlock_irqrestore(&clock_register_lock, flags);
-
-       return ret;
-}
-
-static struct clk_ops tegra_bus_ops = {
-       .init                   = tegra2_bus_clk_init,
-       .enable                 = tegra2_bus_clk_enable,
-       .disable                = tegra2_bus_clk_disable,
-       .set_rate               = tegra2_bus_clk_set_rate,
-};
-
-/* Blink output functions */
-
-static void tegra2_blink_clk_init(struct clk *c)
-{
-       u32 val;
-
-       val = pmc_readl(PMC_CTRL);
-       c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
-       c->mul = 1;
-       val = pmc_readl(c->reg);
-
-       if (val & PMC_BLINK_TIMER_ENB) {
-               unsigned int on_off;
-
-               on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
-                       PMC_BLINK_TIMER_DATA_ON_MASK;
-               val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
-               val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
-               on_off += val;
-               /* each tick in the blink timer is 4 32KHz clocks */
-               c->div = on_off * 4;
-       } else {
-               c->div = 1;
-       }
-}
-
-static int tegra2_blink_clk_enable(struct clk *c)
-{
-       u32 val;
-
-       val = pmc_readl(PMC_DPD_PADS_ORIDE);
-       pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
-
-       val = pmc_readl(PMC_CTRL);
-       pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
-
-       return 0;
-}
-
-static void tegra2_blink_clk_disable(struct clk *c)
-{
-       u32 val;
-
-       val = pmc_readl(PMC_CTRL);
-       pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
-
-       val = pmc_readl(PMC_DPD_PADS_ORIDE);
-       pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
-}
-
-static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(c->parent);
-       if (rate >= parent_rate) {
-               c->div = 1;
-               pmc_writel(0, c->reg);
-       } else {
-               unsigned int on_off;
-               u32 val;
-
-               on_off = DIV_ROUND_UP(parent_rate / 8, rate);
-               c->div = on_off * 8;
-
-               val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
-                       PMC_BLINK_TIMER_DATA_ON_SHIFT;
-               on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
-               on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
-               val |= on_off;
-               val |= PMC_BLINK_TIMER_ENB;
-               pmc_writel(val, c->reg);
-       }
-
-       return 0;
-}
-
-static struct clk_ops tegra_blink_clk_ops = {
-       .init                   = &tegra2_blink_clk_init,
-       .enable                 = &tegra2_blink_clk_enable,
-       .disable                = &tegra2_blink_clk_disable,
-       .set_rate               = &tegra2_blink_clk_set_rate,
-};
-
-/* PLL Functions */
-static int tegra2_pll_clk_wait_for_lock(struct clk *c)
-{
-       udelay(c->u.pll.lock_delay);
-
-       return 0;
-}
-
-static void tegra2_pll_clk_init(struct clk *c)
-{
-       u32 val = clk_readl(c->reg + PLL_BASE);
-
-       c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
-
-       if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
-               pr_warning("Clock %s has unknown fixed frequency\n", c->name);
-               c->mul = 1;
-               c->div = 1;
-       } else if (val & PLL_BASE_BYPASS) {
-               c->mul = 1;
-               c->div = 1;
-       } else {
-               c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
-               c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
-               if (c->flags & PLLU)
-                       c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
-               else
-                       c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
-       }
-}
-
-static int tegra2_pll_clk_enable(struct clk *c)
-{
-       u32 val;
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
-       val = clk_readl(c->reg + PLL_BASE);
-       val &= ~PLL_BASE_BYPASS;
-       val |= PLL_BASE_ENABLE;
-       clk_writel(val, c->reg + PLL_BASE);
-
-       tegra2_pll_clk_wait_for_lock(c);
-
-       return 0;
-}
-
-static void tegra2_pll_clk_disable(struct clk *c)
-{
-       u32 val;
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
-       val = clk_readl(c->reg);
-       val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
-       clk_writel(val, c->reg);
-}
-
-static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       u32 val;
-       unsigned long input_rate;
-       const struct clk_pll_freq_table *sel;
-
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
-
-       input_rate = clk_get_rate(c->parent);
-       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
-               if (sel->input_rate == input_rate && sel->output_rate == rate) {
-                       c->mul = sel->n;
-                       c->div = sel->m * sel->p;
-
-                       val = clk_readl(c->reg + PLL_BASE);
-                       if (c->flags & PLL_FIXED)
-                               val |= PLL_BASE_OVERRIDE;
-                       val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
-                                PLL_BASE_DIVM_MASK);
-                       val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
-                               (sel->n << PLL_BASE_DIVN_SHIFT);
-                       BUG_ON(sel->p < 1 || sel->p > 2);
-                       if (c->flags & PLLU) {
-                               if (sel->p == 1)
-                                       val |= PLLU_BASE_POST_DIV;
-                       } else {
-                               if (sel->p == 2)
-                                       val |= 1 << PLL_BASE_DIVP_SHIFT;
-                       }
-                       clk_writel(val, c->reg + PLL_BASE);
-
-                       if (c->flags & PLL_HAS_CPCON) {
-                               val = clk_readl(c->reg + PLL_MISC(c));
-                               val &= ~PLL_MISC_CPCON_MASK;
-                               val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
-                               clk_writel(val, c->reg + PLL_MISC(c));
-                       }
-
-                       if (c->state == ON)
-                               tegra2_pll_clk_enable(c);
-
-                       return 0;
-               }
-       }
-       return -EINVAL;
-}
-
-static struct clk_ops tegra_pll_ops = {
-       .init                   = tegra2_pll_clk_init,
-       .enable                 = tegra2_pll_clk_enable,
-       .disable                = tegra2_pll_clk_disable,
-       .set_rate               = tegra2_pll_clk_set_rate,
-};
-
-static void tegra2_pllx_clk_init(struct clk *c)
-{
-       tegra2_pll_clk_init(c);
-
-       if (tegra_sku_id == 7)
-               c->max_rate = 750000000;
-}
-
-static struct clk_ops tegra_pllx_ops = {
-       .init     = tegra2_pllx_clk_init,
-       .enable   = tegra2_pll_clk_enable,
-       .disable  = tegra2_pll_clk_disable,
-       .set_rate = tegra2_pll_clk_set_rate,
-};
-
-static int tegra2_plle_clk_enable(struct clk *c)
-{
-       u32 val;
-
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
-       mdelay(1);
-
-       val = clk_readl(c->reg + PLL_BASE);
-       if (!(val & PLLE_MISC_READY))
-               return -EBUSY;
-
-       val = clk_readl(c->reg + PLL_BASE);
-       val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
-       clk_writel(val, c->reg + PLL_BASE);
-
-       return 0;
-}
-
-static struct clk_ops tegra_plle_ops = {
-       .init       = tegra2_pll_clk_init,
-       .enable     = tegra2_plle_clk_enable,
-       .set_rate   = tegra2_pll_clk_set_rate,
-};
-
-/* Clock divider ops */
-static void tegra2_pll_div_clk_init(struct clk *c)
-{
-       u32 val = clk_readl(c->reg);
-       u32 divu71;
-       val >>= c->reg_shift;
-       c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
-       if (!(val & PLL_OUT_RESET_DISABLE))
-               c->state = OFF;
-
-       if (c->flags & DIV_U71) {
-               divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
-               c->div = (divu71 + 2);
-               c->mul = 2;
-       } else if (c->flags & DIV_2) {
-               c->div = 2;
-               c->mul = 1;
-       } else {
-               c->div = 1;
-               c->mul = 1;
-       }
-}
-
-static int tegra2_pll_div_clk_enable(struct clk *c)
-{
-       u32 val;
-       u32 new_val;
-       unsigned long flags;
-
-       pr_debug("%s: %s\n", __func__, c->name);
-       if (c->flags & DIV_U71) {
-               spin_lock_irqsave(&clock_register_lock, flags);
-               val = clk_readl(c->reg);
-               new_val = val >> c->reg_shift;
-               new_val &= 0xFFFF;
-
-               new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
-
-               val &= ~(0xFFFF << c->reg_shift);
-               val |= new_val << c->reg_shift;
-               clk_writel(val, c->reg);
-               spin_unlock_irqrestore(&clock_register_lock, flags);
-               return 0;
-       } else if (c->flags & DIV_2) {
-               BUG_ON(!(c->flags & PLLD));
-               spin_lock_irqsave(&clock_register_lock, flags);
-               val = clk_readl(c->reg);
-               val &= ~PLLD_MISC_DIV_RST;
-               clk_writel(val, c->reg);
-               spin_unlock_irqrestore(&clock_register_lock, flags);
-               return 0;
-       }
-       return -EINVAL;
-}
-
-static void tegra2_pll_div_clk_disable(struct clk *c)
-{
-       u32 val;
-       u32 new_val;
-       unsigned long flags;
-
-       pr_debug("%s: %s\n", __func__, c->name);
-       if (c->flags & DIV_U71) {
-               spin_lock_irqsave(&clock_register_lock, flags);
-               val = clk_readl(c->reg);
-               new_val = val >> c->reg_shift;
-               new_val &= 0xFFFF;
-
-               new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
-
-               val &= ~(0xFFFF << c->reg_shift);
-               val |= new_val << c->reg_shift;
-               clk_writel(val, c->reg);
-               spin_unlock_irqrestore(&clock_register_lock, flags);
-       } else if (c->flags & DIV_2) {
-               BUG_ON(!(c->flags & PLLD));
-               spin_lock_irqsave(&clock_register_lock, flags);
-               val = clk_readl(c->reg);
-               val |= PLLD_MISC_DIV_RST;
-               clk_writel(val, c->reg);
-               spin_unlock_irqrestore(&clock_register_lock, flags);
-       }
-}
-
-static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       u32 val;
-       u32 new_val;
-       int divider_u71;
-       unsigned long parent_rate = clk_get_rate(c->parent);
-       unsigned long flags;
-
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
-       if (c->flags & DIV_U71) {
-               divider_u71 = clk_div71_get_divider(parent_rate, rate);
-               if (divider_u71 >= 0) {
-                       spin_lock_irqsave(&clock_register_lock, flags);
-                       val = clk_readl(c->reg);
-                       new_val = val >> c->reg_shift;
-                       new_val &= 0xFFFF;
-                       if (c->flags & DIV_U71_FIXED)
-                               new_val |= PLL_OUT_OVERRIDE;
-                       new_val &= ~PLL_OUT_RATIO_MASK;
-                       new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
-
-                       val &= ~(0xFFFF << c->reg_shift);
-                       val |= new_val << c->reg_shift;
-                       clk_writel(val, c->reg);
-                       c->div = divider_u71 + 2;
-                       c->mul = 2;
-                       spin_unlock_irqrestore(&clock_register_lock, flags);
-                       return 0;
-               }
-       } else if (c->flags & DIV_2) {
-               if (parent_rate == rate * 2)
-                       return 0;
-       }
-       return -EINVAL;
-}
-
-static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
-{
-       int divider;
-       unsigned long parent_rate = clk_get_rate(c->parent);
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
-
-       if (c->flags & DIV_U71) {
-               divider = clk_div71_get_divider(parent_rate, rate);
-               if (divider < 0)
-                       return divider;
-               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
-       } else if (c->flags & DIV_2) {
-               return DIV_ROUND_UP(parent_rate, 2);
-       }
-       return -EINVAL;
-}
-
-static struct clk_ops tegra_pll_div_ops = {
-       .init                   = tegra2_pll_div_clk_init,
-       .enable                 = tegra2_pll_div_clk_enable,
-       .disable                = tegra2_pll_div_clk_disable,
-       .set_rate               = tegra2_pll_div_clk_set_rate,
-       .round_rate             = tegra2_pll_div_clk_round_rate,
-};
-
-/* Periph clk ops */
-
-static void tegra2_periph_clk_init(struct clk *c)
-{
-       u32 val = clk_readl(c->reg);
-       const struct clk_mux_sel *mux = NULL;
-       const struct clk_mux_sel *sel;
-       u32 shift;
-       u32 mask;
-
-       if (c->flags & MUX_PWM) {
-               shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
-               mask = PERIPH_CLK_SOURCE_PWM_MASK;
-       } else {
-               shift = PERIPH_CLK_SOURCE_SHIFT;
-               mask = PERIPH_CLK_SOURCE_MASK;
-       }
-
-       if (c->flags & MUX) {
-               for (sel = c->inputs; sel->input != NULL; sel++) {
-                       if ((val & mask) >> shift == sel->value)
-                               mux = sel;
-               }
-               BUG_ON(!mux);
-
-               c->parent = mux->input;
-       } else {
-               c->parent = c->inputs[0].input;
-       }
-
-       if (c->flags & DIV_U71) {
-               u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
-               c->div = divu71 + 2;
-               c->mul = 2;
-       } else if (c->flags & DIV_U16) {
-               u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
-               c->div = divu16 + 1;
-               c->mul = 1;
-       } else {
-               c->div = 1;
-               c->mul = 1;
-       }
-
-       c->state = ON;
-
-       if (!c->u.periph.clk_num)
-               return;
-
-       if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
-                       PERIPH_CLK_TO_ENB_BIT(c)))
-               c->state = OFF;
-
-       if (!(c->flags & PERIPH_NO_RESET))
-               if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
-                               PERIPH_CLK_TO_ENB_BIT(c))
-                       c->state = OFF;
-}
-
-static int tegra2_periph_clk_enable(struct clk *c)
-{
-       u32 val;
-       unsigned long flags;
-       int refcount;
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
-       if (!c->u.periph.clk_num)
-               return 0;
-
-       spin_lock_irqsave(&clock_register_lock, flags);
-
-       refcount = tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
-
-       if (refcount > 1)
-               goto out;
-
-       clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
-               CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
-       if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
-               clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
-                       RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
-       if (c->flags & PERIPH_EMC_ENB) {
-               /* The EMC peripheral clock has 2 extra enable bits */
-               /* FIXME: Do they need to be disabled? */
-               val = clk_readl(c->reg);
-               val |= 0x3 << 24;
-               clk_writel(val, c->reg);
-       }
-
-out:
-       spin_unlock_irqrestore(&clock_register_lock, flags);
-
-       return 0;
-}
-
-static void tegra2_periph_clk_disable(struct clk *c)
-{
-       unsigned long flags;
-
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
-       if (!c->u.periph.clk_num)
-               return;
-
-       spin_lock_irqsave(&clock_register_lock, flags);
-
-       if (c->refcnt)
-               tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
-
-       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0)
-               clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
-                       CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
-
-       spin_unlock_irqrestore(&clock_register_lock, flags);
-}
-
-static void tegra2_periph_clk_reset(struct clk *c, bool assert)
-{
-       unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
-
-       pr_debug("%s %s on clock %s\n", __func__,
-                assert ? "assert" : "deassert", c->name);
-
-       BUG_ON(!c->u.periph.clk_num);
-
-       if (!(c->flags & PERIPH_NO_RESET))
-               clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
-                          base + PERIPH_CLK_TO_ENB_SET_REG(c));
-}
-
-static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
-{
-       u32 val;
-       const struct clk_mux_sel *sel;
-       u32 mask, shift;
-
-       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
-
-       if (c->flags & MUX_PWM) {
-               shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
-               mask = PERIPH_CLK_SOURCE_PWM_MASK;
-       } else {
-               shift = PERIPH_CLK_SOURCE_SHIFT;
-               mask = PERIPH_CLK_SOURCE_MASK;
-       }
-
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       val = clk_readl(c->reg);
-                       val &= ~mask;
-                       val |= (sel->value) << shift;
-
-                       if (c->refcnt)
-                               clk_enable(p);
-
-                       clk_writel(val, c->reg);
-
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
-
-                       clk_reparent(c, p);
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       u32 val;
-       int divider;
-       unsigned long parent_rate = clk_get_rate(c->parent);
-
-       if (c->flags & DIV_U71) {
-               divider = clk_div71_get_divider(parent_rate, rate);
-               if (divider >= 0) {
-                       val = clk_readl(c->reg);
-                       val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
-                       val |= divider;
-                       clk_writel(val, c->reg);
-                       c->div = divider + 2;
-                       c->mul = 2;
-                       return 0;
-               }
-       } else if (c->flags & DIV_U16) {
-               divider = clk_div16_get_divider(parent_rate, rate);
-               if (divider >= 0) {
-                       val = clk_readl(c->reg);
-                       val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
-                       val |= divider;
-                       clk_writel(val, c->reg);
-                       c->div = divider + 1;
-                       c->mul = 1;
-                       return 0;
-               }
-       } else if (parent_rate <= rate) {
-               c->div = 1;
-               c->mul = 1;
-               return 0;
-       }
-       return -EINVAL;
-}
-
-static long tegra2_periph_clk_round_rate(struct clk *c,
-       unsigned long rate)
-{
-       int divider;
-       unsigned long parent_rate = clk_get_rate(c->parent);
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
-
-       if (c->flags & DIV_U71) {
-               divider = clk_div71_get_divider(parent_rate, rate);
-               if (divider < 0)
-                       return divider;
-
-               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
-       } else if (c->flags & DIV_U16) {
-               divider = clk_div16_get_divider(parent_rate, rate);
-               if (divider < 0)
-                       return divider;
-               return DIV_ROUND_UP(parent_rate, divider + 1);
-       }
-       return -EINVAL;
-}
-
-static struct clk_ops tegra_periph_clk_ops = {
-       .init                   = &tegra2_periph_clk_init,
-       .enable                 = &tegra2_periph_clk_enable,
-       .disable                = &tegra2_periph_clk_disable,
-       .set_parent             = &tegra2_periph_clk_set_parent,
-       .set_rate               = &tegra2_periph_clk_set_rate,
-       .round_rate             = &tegra2_periph_clk_round_rate,
-       .reset                  = &tegra2_periph_clk_reset,
-};
-
-/* The SDMMC controllers have extra bits in the clock source register that
- * adjust the delay between the clock and data to compenstate for delays
- * on the PCB. */
-void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
-{
-       u32 reg;
-       unsigned long flags;
-
-       spin_lock_irqsave(&c->spinlock, flags);
-
-       delay = clamp(delay, 0, 15);
-       reg = clk_readl(c->reg);
-       reg &= ~SDMMC_CLK_INT_FB_DLY_MASK;
-       reg |= SDMMC_CLK_INT_FB_SEL;
-       reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
-       clk_writel(reg, c->reg);
-
-       spin_unlock_irqrestore(&c->spinlock, flags);
-}
-
-/* External memory controller clock ops */
-static void tegra2_emc_clk_init(struct clk *c)
-{
-       tegra2_periph_clk_init(c);
-       c->max_rate = clk_get_rate_locked(c);
-}
-
-static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
-{
-       long emc_rate;
-       long clk_rate;
-
-       /*
-        * The slowest entry in the EMC clock table that is at least as
-        * fast as rate.
-        */
-       emc_rate = tegra_emc_round_rate(rate);
-       if (emc_rate < 0)
-               return c->max_rate;
-
-       /*
-        * The fastest rate the PLL will generate that is at most the
-        * requested rate.
-        */
-       clk_rate = tegra2_periph_clk_round_rate(c, emc_rate);
-
-       /*
-        * If this fails, and emc_rate > clk_rate, it's because the maximum
-        * rate in the EMC tables is larger than the maximum rate of the EMC
-        * clock. The EMC clock's max rate is the rate it was running when the
-        * kernel booted. Such a mismatch is probably due to using the wrong
-        * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25.
-        */
-       WARN_ONCE(emc_rate != clk_rate,
-               "emc_rate %ld != clk_rate %ld",
-               emc_rate, clk_rate);
-
-       return emc_rate;
-}
-
-static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
-{
-       int ret;
-       /*
-        * The Tegra2 memory controller has an interlock with the clock
-        * block that allows memory shadowed registers to be updated,
-        * and then transfer them to the main registers at the same
-        * time as the clock update without glitches.
-        */
-       ret = tegra_emc_set_rate(rate);
-       if (ret < 0)
-               return ret;
-
-       ret = tegra2_periph_clk_set_rate(c, rate);
-       udelay(1);
-
-       return ret;
-}
-
-static struct clk_ops tegra_emc_clk_ops = {
-       .init                   = &tegra2_emc_clk_init,
-       .enable                 = &tegra2_periph_clk_enable,
-       .disable                = &tegra2_periph_clk_disable,
-       .set_parent             = &tegra2_periph_clk_set_parent,
-       .set_rate               = &tegra2_emc_clk_set_rate,
-       .round_rate             = &tegra2_emc_clk_round_rate,
-       .reset                  = &tegra2_periph_clk_reset,
-};
-
-/* Clock doubler ops */
-static void tegra2_clk_double_init(struct clk *c)
-{
-       c->mul = 2;
-       c->div = 1;
-       c->state = ON;
-
-       if (!c->u.periph.clk_num)
-               return;
-
-       if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
-                       PERIPH_CLK_TO_ENB_BIT(c)))
-               c->state = OFF;
-};
-
-static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
-{
-       if (rate != 2 * clk_get_rate(c->parent))
-               return -EINVAL;
-       c->mul = 2;
-       c->div = 1;
-       return 0;
-}
-
-static struct clk_ops tegra_clk_double_ops = {
-       .init                   = &tegra2_clk_double_init,
-       .enable                 = &tegra2_periph_clk_enable,
-       .disable                = &tegra2_periph_clk_disable,
-       .set_rate               = &tegra2_clk_double_set_rate,
-};
-
-/* Audio sync clock ops */
-static void tegra2_audio_sync_clk_init(struct clk *c)
-{
-       int source;
-       const struct clk_mux_sel *sel;
-       u32 val = clk_readl(c->reg);
-       c->state = (val & (1<<4)) ? OFF : ON;
-       source = val & 0xf;
-       for (sel = c->inputs; sel->input != NULL; sel++)
-               if (sel->value == source)
-                       break;
-       BUG_ON(sel->input == NULL);
-       c->parent = sel->input;
-}
-
-static int tegra2_audio_sync_clk_enable(struct clk *c)
-{
-       clk_writel(0, c->reg);
-       return 0;
-}
-
-static void tegra2_audio_sync_clk_disable(struct clk *c)
-{
-       clk_writel(1, c->reg);
-}
-
-static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
-{
-       u32 val;
-       const struct clk_mux_sel *sel;
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       val = clk_readl(c->reg);
-                       val &= ~0xf;
-                       val |= sel->value;
-
-                       if (c->refcnt)
-                               clk_enable(p);
-
-                       clk_writel(val, c->reg);
-
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
-
-                       clk_reparent(c, p);
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static struct clk_ops tegra_audio_sync_clk_ops = {
-       .init       = tegra2_audio_sync_clk_init,
-       .enable     = tegra2_audio_sync_clk_enable,
-       .disable    = tegra2_audio_sync_clk_disable,
-       .set_parent = tegra2_audio_sync_clk_set_parent,
-};
-
-/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
-
-static void tegra2_cdev_clk_init(struct clk *c)
-{
-       /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
-        * currently done in the pinmux code. */
-       c->state = ON;
-
-       BUG_ON(!c->u.periph.clk_num);
-
-       if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
-                       PERIPH_CLK_TO_ENB_BIT(c)))
-               c->state = OFF;
-}
-
-static int tegra2_cdev_clk_enable(struct clk *c)
-{
-       BUG_ON(!c->u.periph.clk_num);
-
-       clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
-               CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
-       return 0;
-}
-
-static void tegra2_cdev_clk_disable(struct clk *c)
-{
-       BUG_ON(!c->u.periph.clk_num);
-
-       clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
-               CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
-}
-
-static struct clk_ops tegra_cdev_clk_ops = {
-       .init                   = &tegra2_cdev_clk_init,
-       .enable                 = &tegra2_cdev_clk_enable,
-       .disable                = &tegra2_cdev_clk_disable,
-};
-
-/* shared bus ops */
-/*
- * Some clocks may have multiple downstream users that need to request a
- * higher clock rate.  Shared bus clocks provide a unique shared_bus_user
- * clock to each user.  The frequency of the bus is set to the highest
- * enabled shared_bus_user clock, with a minimum value set by the
- * shared bus.
- */
-static int tegra_clk_shared_bus_update(struct clk *bus)
-{
-       struct clk *c;
-       unsigned long rate = bus->min_rate;
-
-       list_for_each_entry(c, &bus->shared_bus_list, u.shared_bus_user.node)
-               if (c->u.shared_bus_user.enabled)
-                       rate = max(c->u.shared_bus_user.rate, rate);
-
-       if (rate == clk_get_rate_locked(bus))
-               return 0;
-
-       return clk_set_rate_locked(bus, rate);
-};
-
-static void tegra_clk_shared_bus_init(struct clk *c)
-{
-       unsigned long flags;
-
-       c->max_rate = c->parent->max_rate;
-       c->u.shared_bus_user.rate = c->parent->max_rate;
-       c->state = OFF;
-       c->set = true;
-
-       spin_lock_irqsave(&c->parent->spinlock, flags);
-
-       list_add_tail(&c->u.shared_bus_user.node,
-               &c->parent->shared_bus_list);
-
-       spin_unlock_irqrestore(&c->parent->spinlock, flags);
-}
-
-static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
-{
-       unsigned long flags;
-       int ret;
-       long new_rate = rate;
-
-       new_rate = clk_round_rate(c->parent, new_rate);
-       if (new_rate < 0)
-               return new_rate;
-
-       spin_lock_irqsave(&c->parent->spinlock, flags);
-
-       c->u.shared_bus_user.rate = new_rate;
-       ret = tegra_clk_shared_bus_update(c->parent);
-
-       spin_unlock_irqrestore(&c->parent->spinlock, flags);
-
-       return ret;
-}
-
-static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
-{
-       return clk_round_rate(c->parent, rate);
-}
-
-static int tegra_clk_shared_bus_enable(struct clk *c)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&c->parent->spinlock, flags);
-
-       c->u.shared_bus_user.enabled = true;
-       ret = tegra_clk_shared_bus_update(c->parent);
-
-       spin_unlock_irqrestore(&c->parent->spinlock, flags);
-
-       return ret;
-}
-
-static void tegra_clk_shared_bus_disable(struct clk *c)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&c->parent->spinlock, flags);
-
-       c->u.shared_bus_user.enabled = false;
-       ret = tegra_clk_shared_bus_update(c->parent);
-       WARN_ON_ONCE(ret);
-
-       spin_unlock_irqrestore(&c->parent->spinlock, flags);
-}
-
-static struct clk_ops tegra_clk_shared_bus_ops = {
-       .init = tegra_clk_shared_bus_init,
-       .enable = tegra_clk_shared_bus_enable,
-       .disable = tegra_clk_shared_bus_disable,
-       .set_rate = tegra_clk_shared_bus_set_rate,
-       .round_rate = tegra_clk_shared_bus_round_rate,
-};
-
-
-/* Clock definitions */
-static struct clk tegra_clk_32k = {
-       .name = "clk_32k",
-       .rate = 32768,
-       .ops  = NULL,
-       .max_rate = 32768,
-};
-
-static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
-       {32768, 12000000, 366, 1, 1, 0},
-       {32768, 13000000, 397, 1, 1, 0},
-       {32768, 19200000, 586, 1, 1, 0},
-       {32768, 26000000, 793, 1, 1, 0},
-       {0, 0, 0, 0, 0, 0},
-};
-
-static struct clk tegra_pll_s = {
-       .name      = "pll_s",
-       .flags     = PLL_ALT_MISC_REG,
-       .ops       = &tegra_pll_ops,
-       .parent    = &tegra_clk_32k,
-       .max_rate  = 26000000,
-       .reg       = 0xf0,
-       .u.pll = {
-               .input_min = 32768,
-               .input_max = 32768,
-               .cf_min    = 0, /* FIXME */
-               .cf_max    = 0, /* FIXME */
-               .vco_min   = 12000000,
-               .vco_max   = 26000000,
-               .freq_table = tegra_pll_s_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk_mux_sel tegra_clk_m_sel[] = {
-       { .input = &tegra_clk_32k, .value = 0},
-       { .input = &tegra_pll_s,  .value = 1},
-       { NULL , 0},
-};
-
-static struct clk tegra_clk_m = {
-       .name      = "clk_m",
-       .flags     = ENABLE_ON_INIT,
-       .ops       = &tegra_clk_m_ops,
-       .inputs    = tegra_clk_m_sel,
-       .reg       = 0x1fc,
-       .reg_shift = 28,
-       .max_rate  = 26000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
-       { 12000000, 600000000, 600, 12, 1, 8 },
-       { 13000000, 600000000, 600, 13, 1, 8 },
-       { 19200000, 600000000, 500, 16, 1, 6 },
-       { 26000000, 600000000, 600, 26, 1, 8 },
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_c = {
-       .name      = "pll_c",
-       .flags     = PLL_HAS_CPCON,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0x80,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 600000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1400000000,
-               .freq_table = tegra_pll_c_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_c_out1 = {
-       .name      = "pll_c_out1",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_U71,
-       .parent    = &tegra_pll_c,
-       .reg       = 0x84,
-       .reg_shift = 0,
-       .max_rate  = 600000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
-       { 12000000, 666000000, 666, 12, 1, 8},
-       { 13000000, 666000000, 666, 13, 1, 8},
-       { 19200000, 666000000, 555, 16, 1, 8},
-       { 26000000, 666000000, 666, 26, 1, 8},
-       { 12000000, 600000000, 600, 12, 1, 8},
-       { 13000000, 600000000, 600, 13, 1, 8},
-       { 19200000, 600000000, 375, 12, 1, 6},
-       { 26000000, 600000000, 600, 26, 1, 8},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_m = {
-       .name      = "pll_m",
-       .flags     = PLL_HAS_CPCON,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0x90,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 800000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1200000000,
-               .freq_table = tegra_pll_m_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_m_out1 = {
-       .name      = "pll_m_out1",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_U71,
-       .parent    = &tegra_pll_m,
-       .reg       = 0x94,
-       .reg_shift = 0,
-       .max_rate  = 600000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
-       { 12000000, 216000000, 432, 12, 2, 8},
-       { 13000000, 216000000, 432, 13, 2, 8},
-       { 19200000, 216000000, 90,   4, 2, 1},
-       { 26000000, 216000000, 432, 26, 2, 8},
-       { 12000000, 432000000, 432, 12, 1, 8},
-       { 13000000, 432000000, 432, 13, 1, 8},
-       { 19200000, 432000000, 90,   4, 1, 1},
-       { 26000000, 432000000, 432, 26, 1, 8},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_p = {
-       .name      = "pll_p",
-       .flags     = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xa0,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 432000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1400000000,
-               .freq_table = tegra_pll_p_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_p_out1 = {
-       .name      = "pll_p_out1",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa4,
-       .reg_shift = 0,
-       .max_rate  = 432000000,
-};
-
-static struct clk tegra_pll_p_out2 = {
-       .name      = "pll_p_out2",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa4,
-       .reg_shift = 16,
-       .max_rate  = 432000000,
-};
-
-static struct clk tegra_pll_p_out3 = {
-       .name      = "pll_p_out3",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa8,
-       .reg_shift = 0,
-       .max_rate  = 432000000,
-};
-
-static struct clk tegra_pll_p_out4 = {
-       .name      = "pll_p_out4",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa8,
-       .reg_shift = 16,
-       .max_rate  = 432000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
-       { 28800000, 56448000, 49, 25, 1, 1},
-       { 28800000, 73728000, 64, 25, 1, 1},
-       { 28800000, 24000000,  5,  6, 1, 1},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_a = {
-       .name      = "pll_a",
-       .flags     = PLL_HAS_CPCON,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xb0,
-       .parent    = &tegra_pll_p_out1,
-       .max_rate  = 73728000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1400000000,
-               .freq_table = tegra_pll_a_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_a_out0 = {
-       .name      = "pll_a_out0",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_U71,
-       .parent    = &tegra_pll_a,
-       .reg       = 0xb4,
-       .reg_shift = 0,
-       .max_rate  = 73728000,
-};
-
-static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
-       { 12000000, 216000000, 216, 12, 1, 4},
-       { 13000000, 216000000, 216, 13, 1, 4},
-       { 19200000, 216000000, 135, 12, 1, 3},
-       { 26000000, 216000000, 216, 26, 1, 4},
-
-       { 12000000, 594000000, 594, 12, 1, 8},
-       { 13000000, 594000000, 594, 13, 1, 8},
-       { 19200000, 594000000, 495, 16, 1, 8},
-       { 26000000, 594000000, 594, 26, 1, 8},
-
-       { 12000000, 1000000000, 1000, 12, 1, 12},
-       { 13000000, 1000000000, 1000, 13, 1, 12},
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 12},
-
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_d = {
-       .name      = "pll_d",
-       .flags     = PLL_HAS_CPCON | PLLD,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xd0,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 1000000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 40000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 40000000,
-               .vco_max   = 1000000000,
-               .freq_table = tegra_pll_d_freq_table,
-               .lock_delay = 1000,
-       },
-};
-
-static struct clk tegra_pll_d_out0 = {
-       .name      = "pll_d_out0",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_2 | PLLD,
-       .parent    = &tegra_pll_d,
-       .max_rate  = 500000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
-       { 12000000, 480000000, 960, 12, 2, 0},
-       { 13000000, 480000000, 960, 13, 2, 0},
-       { 19200000, 480000000, 200, 4,  2, 0},
-       { 26000000, 480000000, 960, 26, 2, 0},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_u = {
-       .name      = "pll_u",
-       .flags     = PLLU,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xc0,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 480000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 40000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 480000000,
-               .vco_max   = 960000000,
-               .freq_table = tegra_pll_u_freq_table,
-               .lock_delay = 1000,
-       },
-};
-
-static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
-       /* 1 GHz */
-       { 12000000, 1000000000, 1000, 12, 1, 12},
-       { 13000000, 1000000000, 1000, 13, 1, 12},
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 12},
-
-       /* 912 MHz */
-       { 12000000, 912000000,  912,  12, 1, 12},
-       { 13000000, 912000000,  912,  13, 1, 12},
-       { 19200000, 912000000,  760,  16, 1, 8},
-       { 26000000, 912000000,  912,  26, 1, 12},
-
-       /* 816 MHz */
-       { 12000000, 816000000,  816,  12, 1, 12},
-       { 13000000, 816000000,  816,  13, 1, 12},
-       { 19200000, 816000000,  680,  16, 1, 8},
-       { 26000000, 816000000,  816,  26, 1, 12},
-
-       /* 760 MHz */
-       { 12000000, 760000000,  760,  12, 1, 12},
-       { 13000000, 760000000,  760,  13, 1, 12},
-       { 19200000, 760000000,  950,  24, 1, 8},
-       { 26000000, 760000000,  760,  26, 1, 12},
-
-       /* 750 MHz */
-       { 12000000, 750000000,  750,  12, 1, 12},
-       { 13000000, 750000000,  750,  13, 1, 12},
-       { 19200000, 750000000,  625,  16, 1, 8},
-       { 26000000, 750000000,  750,  26, 1, 12},
-
-       /* 608 MHz */
-       { 12000000, 608000000,  608,  12, 1, 12},
-       { 13000000, 608000000,  608,  13, 1, 12},
-       { 19200000, 608000000,  380,  12, 1, 8},
-       { 26000000, 608000000,  608,  26, 1, 12},
-
-       /* 456 MHz */
-       { 12000000, 456000000,  456,  12, 1, 12},
-       { 13000000, 456000000,  456,  13, 1, 12},
-       { 19200000, 456000000,  380,  16, 1, 8},
-       { 26000000, 456000000,  456,  26, 1, 12},
-
-       /* 312 MHz */
-       { 12000000, 312000000,  312,  12, 1, 12},
-       { 13000000, 312000000,  312,  13, 1, 12},
-       { 19200000, 312000000,  260,  16, 1, 8},
-       { 26000000, 312000000,  312,  26, 1, 12},
-
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_x = {
-       .name      = "pll_x",
-       .flags     = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
-       .ops       = &tegra_pllx_ops,
-       .reg       = 0xe0,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 1000000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1200000000,
-               .freq_table = tegra_pll_x_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
-       { 12000000, 100000000,  200,  24, 1, 0 },
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_e = {
-       .name      = "pll_e",
-       .flags     = PLL_ALT_MISC_REG,
-       .ops       = &tegra_plle_ops,
-       .parent    = &tegra_clk_m,
-       .reg       = 0xe8,
-       .max_rate  = 100000000,
-       .u.pll = {
-               .input_min = 12000000,
-               .input_max = 12000000,
-               .freq_table = tegra_pll_e_freq_table,
-       },
-};
-
-static struct clk tegra_clk_d = {
-       .name      = "clk_d",
-       .flags     = PERIPH_NO_RESET,
-       .ops       = &tegra_clk_double_ops,
-       .reg       = 0x34,
-       .reg_shift = 12,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 52000000,
-       .u.periph  = {
-               .clk_num = 90,
-       },
-};
-
-/* dap_mclk1, belongs to the cdev1 pingroup. */
-static struct clk tegra_clk_cdev1 = {
-       .name      = "cdev1",
-       .ops       = &tegra_cdev_clk_ops,
-       .rate      = 26000000,
-       .max_rate  = 26000000,
-       .u.periph  = {
-               .clk_num = 94,
-       },
-};
-
-/* dap_mclk2, belongs to the cdev2 pingroup. */
-static struct clk tegra_clk_cdev2 = {
-       .name      = "cdev2",
-       .ops       = &tegra_cdev_clk_ops,
-       .rate      = 26000000,
-       .max_rate  = 26000000,
-       .u.periph  = {
-               .clk_num   = 93,
-       },
-};
-
-/* initialized before peripheral clocks */
-static struct clk_mux_sel mux_audio_sync_clk[8+1];
-static const struct audio_sources {
-       const char *name;
-       int value;
-} mux_audio_sync_clk_sources[] = {
-       { .name = "spdif_in", .value = 0 },
-       { .name = "i2s1", .value = 1 },
-       { .name = "i2s2", .value = 2 },
-       { .name = "pll_a_out0", .value = 4 },
-#if 0 /* FIXME: not implemented */
-       { .name = "ac97", .value = 3 },
-       { .name = "ext_audio_clk2", .value = 5 },
-       { .name = "ext_audio_clk1", .value = 6 },
-       { .name = "ext_vimclk", .value = 7 },
-#endif
-       { NULL, 0 }
-};
-
-static struct clk tegra_clk_audio = {
-       .name      = "audio",
-       .inputs    = mux_audio_sync_clk,
-       .reg       = 0x38,
-       .max_rate  = 73728000,
-       .ops       = &tegra_audio_sync_clk_ops
-};
-
-static struct clk tegra_clk_audio_2x = {
-       .name      = "audio_2x",
-       .flags     = PERIPH_NO_RESET,
-       .max_rate  = 48000000,
-       .ops       = &tegra_clk_double_ops,
-       .reg       = 0x34,
-       .reg_shift = 8,
-       .parent    = &tegra_clk_audio,
-       .u.periph = {
-               .clk_num = 89,
-       },
-};
-
-static struct clk_lookup tegra_audio_clk_lookups[] = {
-       { .con_id = "audio", .clk = &tegra_clk_audio },
-       { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
-};
-
-/* This is called after peripheral clocks are initialized, as the
- * audio_sync clock depends on some of the peripheral clocks.
- */
-
-static void init_audio_sync_clock_mux(void)
-{
-       int i;
-       struct clk_mux_sel *sel = mux_audio_sync_clk;
-       const struct audio_sources *src = mux_audio_sync_clk_sources;
-       struct clk_lookup *lookup;
-
-       for (i = 0; src->name; i++, sel++, src++) {
-               sel->input = tegra_get_clock_by_name(src->name);
-               if (!sel->input)
-                       pr_err("%s: could not find clk %s\n", __func__,
-                               src->name);
-               sel->value = src->value;
-       }
-
-       lookup = tegra_audio_clk_lookups;
-       for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
-               clk_init(lookup->clk);
-               clkdev_add(lookup);
-       }
-}
-
-static struct clk_mux_sel mux_cclk[] = {
-       { .input = &tegra_clk_m,        .value = 0},
-       { .input = &tegra_pll_c,        .value = 1},
-       { .input = &tegra_clk_32k,      .value = 2},
-       { .input = &tegra_pll_m,        .value = 3},
-       { .input = &tegra_pll_p,        .value = 4},
-       { .input = &tegra_pll_p_out4,   .value = 5},
-       { .input = &tegra_pll_p_out3,   .value = 6},
-       { .input = &tegra_clk_d,        .value = 7},
-       { .input = &tegra_pll_x,        .value = 8},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_sclk[] = {
-       { .input = &tegra_clk_m,        .value = 0},
-       { .input = &tegra_pll_c_out1,   .value = 1},
-       { .input = &tegra_pll_p_out4,   .value = 2},
-       { .input = &tegra_pll_p_out3,   .value = 3},
-       { .input = &tegra_pll_p_out2,   .value = 4},
-       { .input = &tegra_clk_d,        .value = 5},
-       { .input = &tegra_clk_32k,      .value = 6},
-       { .input = &tegra_pll_m_out1,   .value = 7},
-       { NULL, 0},
-};
-
-static struct clk tegra_clk_cclk = {
-       .name   = "cclk",
-       .inputs = mux_cclk,
-       .reg    = 0x20,
-       .ops    = &tegra_super_ops,
-       .max_rate = 1000000000,
-};
-
-static struct clk tegra_clk_sclk = {
-       .name   = "sclk",
-       .inputs = mux_sclk,
-       .reg    = 0x28,
-       .ops    = &tegra_super_ops,
-       .max_rate = 240000000,
-       .min_rate = 120000000,
-};
-
-static struct clk tegra_clk_virtual_cpu = {
-       .name      = "cpu",
-       .parent    = &tegra_clk_cclk,
-       .ops       = &tegra_cpu_ops,
-       .max_rate  = 1000000000,
-       .u.cpu = {
-               .main      = &tegra_pll_x,
-               .backup    = &tegra_pll_p,
-       },
-};
-
-static struct clk tegra_clk_cop = {
-       .name      = "cop",
-       .parent    = &tegra_clk_sclk,
-       .ops       = &tegra_cop_ops,
-       .max_rate  = 240000000,
-};
-
-static struct clk tegra_clk_hclk = {
-       .name           = "hclk",
-       .flags          = DIV_BUS,
-       .parent         = &tegra_clk_sclk,
-       .reg            = 0x30,
-       .reg_shift      = 4,
-       .ops            = &tegra_bus_ops,
-       .max_rate       = 240000000,
-};
-
-static struct clk tegra_clk_pclk = {
-       .name           = "pclk",
-       .flags          = DIV_BUS,
-       .parent         = &tegra_clk_hclk,
-       .reg            = 0x30,
-       .reg_shift      = 0,
-       .ops            = &tegra_bus_ops,
-       .max_rate       = 120000000,
-};
-
-static struct clk tegra_clk_blink = {
-       .name           = "blink",
-       .parent         = &tegra_clk_32k,
-       .reg            = 0x40,
-       .ops            = &tegra_blink_clk_ops,
-       .max_rate       = 32768,
-};
-
-static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
-       { .input = &tegra_pll_m, .value = 0},
-       { .input = &tegra_pll_c, .value = 1},
-       { .input = &tegra_pll_p, .value = 2},
-       { .input = &tegra_pll_a_out0, .value = 3},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
-       { .input = &tegra_pll_m, .value = 0},
-       { .input = &tegra_pll_c, .value = 1},
-       { .input = &tegra_pll_p, .value = 2},
-       { .input = &tegra_clk_m, .value = 3},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
-       { .input = &tegra_pll_p, .value = 0},
-       { .input = &tegra_pll_c, .value = 1},
-       { .input = &tegra_pll_m, .value = 2},
-       { .input = &tegra_clk_m, .value = 3},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
-       {.input = &tegra_pll_a_out0, .value = 0},
-       {.input = &tegra_clk_audio_2x, .value = 1},
-       {.input = &tegra_pll_p, .value = 2},
-       {.input = &tegra_clk_m, .value = 3},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
-       {.input = &tegra_pll_p, .value = 0},
-       {.input = &tegra_pll_d_out0, .value = 1},
-       {.input = &tegra_pll_c, .value = 2},
-       {.input = &tegra_clk_m, .value = 3},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
-       {.input = &tegra_pll_p,     .value = 0},
-       {.input = &tegra_pll_c,     .value = 1},
-       {.input = &tegra_clk_audio,     .value = 2},
-       {.input = &tegra_clk_m,     .value = 3},
-       {.input = &tegra_clk_32k,   .value = 4},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
-       {.input = &tegra_pll_p,     .value = 0},
-       {.input = &tegra_pll_c,     .value = 1},
-       {.input = &tegra_pll_m,     .value = 2},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_clk_m[] = {
-       { .input = &tegra_clk_m, .value = 0},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pllp_out3[] = {
-       { .input = &tegra_pll_p_out3, .value = 0},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_plld[] = {
-       { .input = &tegra_pll_d, .value = 0},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_clk_32k[] = {
-       { .input = &tegra_clk_32k, .value = 0},
-       { NULL, 0},
-};
-
-static struct clk_mux_sel mux_pclk[] = {
-       { .input = &tegra_clk_pclk, .value = 0},
-       { NULL, 0},
-};
-
-static struct clk tegra_clk_emc = {
-       .name = "emc",
-       .ops = &tegra_emc_clk_ops,
-       .reg = 0x19c,
-       .max_rate = 800000000,
-       .inputs = mux_pllm_pllc_pllp_clkm,
-       .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
-       .u.periph = {
-               .clk_num = 57,
-       },
-};
-
-#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
-       {                                               \
-               .name      = _name,                     \
-               .lookup    = {                          \
-                       .dev_id    = _dev,              \
-                       .con_id    = _con,              \
-               },                                      \
-               .ops       = &tegra_periph_clk_ops,     \
-               .reg       = _reg,                      \
-               .inputs    = _inputs,                   \
-               .flags     = _flags,                    \
-               .max_rate  = _max,                      \
-               .u.periph = {                           \
-                       .clk_num   = _clk_num,          \
-               },                                      \
-       }
-
-#define SHARED_CLK(_name, _dev, _con, _parent)         \
-       {                                               \
-               .name      = _name,                     \
-               .lookup    = {                          \
-                       .dev_id    = _dev,              \
-                       .con_id    = _con,              \
-               },                                      \
-               .ops       = &tegra_clk_shared_bus_ops, \
-               .parent = _parent,                      \
-       }
-
-static struct clk tegra_list_clks[] = {
-       PERIPH_CLK("apbdma",    "tegra-apbdma",         NULL,   34,     0,      108000000, mux_pclk,                    0),
-       PERIPH_CLK("rtc",       "rtc-tegra",            NULL,   4,      0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET),
-       PERIPH_CLK("timer",     "timer",                NULL,   5,      0,      26000000,  mux_clk_m,                   0),
-       PERIPH_CLK("i2s1",      "tegra20-i2s.0",        NULL,   11,     0x100,  26000000,  mux_pllaout0_audio2x_pllp_clkm,      MUX | DIV_U71),
-       PERIPH_CLK("i2s2",      "tegra20-i2s.1",        NULL,   18,     0x104,  26000000,  mux_pllaout0_audio2x_pllp_clkm,      MUX | DIV_U71),
-       PERIPH_CLK("spdif_out", "spdif_out",            NULL,   10,     0x108,  100000000, mux_pllaout0_audio2x_pllp_clkm,      MUX | DIV_U71),
-       PERIPH_CLK("spdif_in",  "spdif_in",             NULL,   10,     0x10c,  100000000, mux_pllp_pllc_pllm,          MUX | DIV_U71),
-       PERIPH_CLK("pwm",       "tegra-pwm",            NULL,   17,     0x110,  432000000, mux_pllp_pllc_audio_clkm_clk32,      MUX | DIV_U71 | MUX_PWM),
-       PERIPH_CLK("spi",       "spi",                  NULL,   43,     0x114,  40000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("xio",       "xio",                  NULL,   45,     0x120,  150000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("twc",       "twc",                  NULL,   16,     0x12c,  150000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("sbc1",      "spi_tegra.0",          NULL,   41,     0x134,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("sbc2",      "spi_tegra.1",          NULL,   44,     0x118,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("sbc3",      "spi_tegra.2",          NULL,   46,     0x11c,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("sbc4",      "spi_tegra.3",          NULL,   68,     0x1b4,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("ide",       "ide",                  NULL,   25,     0x144,  100000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("ndflash",   "tegra_nand",           NULL,   13,     0x160,  164000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("vfir",      "vfir",                 NULL,   7,      0x168,  72000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("sdmmc1",    "sdhci-tegra.0",        NULL,   14,     0x150,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("sdmmc2",    "sdhci-tegra.1",        NULL,   9,      0x154,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("sdmmc3",    "sdhci-tegra.2",        NULL,   69,     0x1bc,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("sdmmc4",    "sdhci-tegra.3",        NULL,   15,     0x164,  52000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("vcp",       "tegra-avp",            "vcp",  29,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("bsea",      "tegra-avp",            "bsea", 62,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("bsev",      "tegra-aes",            "bsev", 63,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("vde",       "tegra-avp",            "vde",  61,     0x1c8,  250000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage and process_id */
-       PERIPH_CLK("csite",     "csite",                NULL,   73,     0x1d4,  144000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* max rate ??? */
-       /* FIXME: what is la? */
-       PERIPH_CLK("la",        "la",                   NULL,   76,     0x1f8,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("owr",       "tegra_w1",             NULL,   71,     0x1cc,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("nor",       "nor",                  NULL,   42,     0x1d0,  92000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("mipi",      "mipi",                 NULL,   50,     0x174,  60000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("i2c1",      "tegra-i2c.0",          NULL,   12,     0x124,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16),
-       PERIPH_CLK("i2c2",      "tegra-i2c.1",          NULL,   54,     0x198,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16),
-       PERIPH_CLK("i2c3",      "tegra-i2c.2",          NULL,   67,     0x1b8,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16),
-       PERIPH_CLK("dvc",       "tegra-i2c.3",          NULL,   47,     0x128,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U16),
-       PERIPH_CLK("i2c1_i2c",  "tegra-i2c.0",          "i2c",  0,      0,      72000000,  mux_pllp_out3,                       0),
-       PERIPH_CLK("i2c2_i2c",  "tegra-i2c.1",          "i2c",  0,      0,      72000000,  mux_pllp_out3,                       0),
-       PERIPH_CLK("i2c3_i2c",  "tegra-i2c.2",          "i2c",  0,      0,      72000000,  mux_pllp_out3,                       0),
-       PERIPH_CLK("dvc_i2c",   "tegra-i2c.3",          "i2c",  0,      0,      72000000,  mux_pllp_out3,                       0),
-       PERIPH_CLK("uarta",     "tegra-uart.0",         NULL,   6,      0x178,  600000000, mux_pllp_pllc_pllm_clkm,     MUX),
-       PERIPH_CLK("uartb",     "tegra-uart.1",         NULL,   7,      0x17c,  600000000, mux_pllp_pllc_pllm_clkm,     MUX),
-       PERIPH_CLK("uartc",     "tegra-uart.2",         NULL,   55,     0x1a0,  600000000, mux_pllp_pllc_pllm_clkm,     MUX),
-       PERIPH_CLK("uartd",     "tegra-uart.3",         NULL,   65,     0x1c0,  600000000, mux_pllp_pllc_pllm_clkm,     MUX),
-       PERIPH_CLK("uarte",     "tegra-uart.4",         NULL,   66,     0x1c4,  600000000, mux_pllp_pllc_pllm_clkm,     MUX),
-       PERIPH_CLK("3d",        "3d",                   NULL,   24,     0x158,  300000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */
-       PERIPH_CLK("2d",        "2d",                   NULL,   21,     0x15c,  300000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71), /* scales with voltage and process_id */
-       PERIPH_CLK("vi",        "tegra_camera",         "vi",   20,     0x148,  150000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71), /* scales with voltage and process_id */
-       PERIPH_CLK("vi_sensor", "tegra_camera",         "vi_sensor",    20,     0x1a8,  150000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
-       PERIPH_CLK("epp",       "epp",                  NULL,   19,     0x16c,  300000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71), /* scales with voltage and process_id */
-       PERIPH_CLK("mpe",       "mpe",                  NULL,   60,     0x170,  250000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71), /* scales with voltage and process_id */
-       PERIPH_CLK("host1x",    "host1x",               NULL,   28,     0x180,  166000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71), /* scales with voltage and process_id */
-       PERIPH_CLK("cve",       "cve",                  NULL,   49,     0x140,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("tvo",       "tvo",                  NULL,   49,     0x188,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("hdmi",      "hdmi",                 NULL,   51,     0x18c,  600000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("tvdac",     "tvdac",                NULL,   53,     0x194,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("disp1",     "tegradc.0",            NULL,   27,     0x138,  600000000, mux_pllp_plld_pllc_clkm,     MUX), /* scales with voltage and process_id */
-       PERIPH_CLK("disp2",     "tegradc.1",            NULL,   26,     0x13c,  600000000, mux_pllp_plld_pllc_clkm,     MUX), /* scales with voltage and process_id */
-       PERIPH_CLK("usbd",      "fsl-tegra-udc",        NULL,   22,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
-       PERIPH_CLK("usb2",      "tegra-ehci.1",         NULL,   58,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
-       PERIPH_CLK("usb3",      "tegra-ehci.2",         NULL,   59,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
-       PERIPH_CLK("dsi",       "dsi",                  NULL,   48,     0,      500000000, mux_plld,                    0), /* scales with voltage */
-       PERIPH_CLK("csi",       "tegra_camera",         "csi",  52,     0,      72000000,  mux_pllp_out3,               0),
-       PERIPH_CLK("isp",       "tegra_camera",         "isp",  23,     0,      150000000, mux_clk_m,                   0), /* same frequency as VI */
-       PERIPH_CLK("csus",      "tegra_camera",         "csus", 92,     0,      150000000, mux_clk_m,                   PERIPH_NO_RESET),
-       PERIPH_CLK("pex",       NULL,                   "pex",  70,     0,      26000000,  mux_clk_m,                   PERIPH_MANUAL_RESET),
-       PERIPH_CLK("afi",       NULL,                   "afi",  72,     0,      26000000,  mux_clk_m,                   PERIPH_MANUAL_RESET),
-       PERIPH_CLK("pcie_xclk", NULL,             "pcie_xclk",  74,     0,      26000000,  mux_clk_m,                   PERIPH_MANUAL_RESET),
-
-       SHARED_CLK("avp.sclk",  "tegra-avp",            "sclk", &tegra_clk_sclk),
-       SHARED_CLK("avp.emc",   "tegra-avp",            "emc",  &tegra_clk_emc),
-       SHARED_CLK("cpu.emc",   "cpu",                  "emc",  &tegra_clk_emc),
-       SHARED_CLK("disp1.emc", "tegradc.0",            "emc",  &tegra_clk_emc),
-       SHARED_CLK("disp2.emc", "tegradc.1",            "emc",  &tegra_clk_emc),
-       SHARED_CLK("hdmi.emc",  "hdmi",                 "emc",  &tegra_clk_emc),
-       SHARED_CLK("host.emc",  "tegra_grhost",         "emc",  &tegra_clk_emc),
-       SHARED_CLK("usbd.emc",  "fsl-tegra-udc",        "emc",  &tegra_clk_emc),
-       SHARED_CLK("usb1.emc",  "tegra-ehci.0",         "emc",  &tegra_clk_emc),
-       SHARED_CLK("usb2.emc",  "tegra-ehci.1",         "emc",  &tegra_clk_emc),
-       SHARED_CLK("usb3.emc",  "tegra-ehci.2",         "emc",  &tegra_clk_emc),
-};
-
-#define CLK_DUPLICATE(_name, _dev, _con)               \
-       {                                               \
-               .name   = _name,                        \
-               .lookup = {                             \
-                       .dev_id = _dev,                 \
-                       .con_id         = _con,         \
-               },                                      \
-       }
-
-/* Some clocks may be used by different drivers depending on the board
- * configuration.  List those here to register them twice in the clock lookup
- * table under two names.
- */
-static struct clk_duplicate tegra_clk_duplicates[] = {
-       CLK_DUPLICATE("uarta",  "serial8250.0", NULL),
-       CLK_DUPLICATE("uartb",  "serial8250.1", NULL),
-       CLK_DUPLICATE("uartc",  "serial8250.2", NULL),
-       CLK_DUPLICATE("uartd",  "serial8250.3", NULL),
-       CLK_DUPLICATE("uarte",  "serial8250.4", NULL),
-       CLK_DUPLICATE("usbd", "utmip-pad", NULL),
-       CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
-       CLK_DUPLICATE("usbd", "tegra-otg", NULL),
-       CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
-       CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
-       CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"),
-       CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
-       CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
-       CLK_DUPLICATE("epp", "tegra_grhost", "epp"),
-       CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"),
-       CLK_DUPLICATE("cop", "tegra-avp", "cop"),
-       CLK_DUPLICATE("vde", "tegra-aes", "vde"),
-};
-
-#define CLK(dev, con, ck)      \
-       {                       \
-               .dev_id = dev,  \
-               .con_id = con,  \
-               .clk = ck,      \
-       }
-
-static struct clk *tegra_ptr_clks[] = {
-       &tegra_clk_32k,
-       &tegra_pll_s,
-       &tegra_clk_m,
-       &tegra_pll_m,
-       &tegra_pll_m_out1,
-       &tegra_pll_c,
-       &tegra_pll_c_out1,
-       &tegra_pll_p,
-       &tegra_pll_p_out1,
-       &tegra_pll_p_out2,
-       &tegra_pll_p_out3,
-       &tegra_pll_p_out4,
-       &tegra_pll_a,
-       &tegra_pll_a_out0,
-       &tegra_pll_d,
-       &tegra_pll_d_out0,
-       &tegra_pll_u,
-       &tegra_pll_x,
-       &tegra_pll_e,
-       &tegra_clk_cclk,
-       &tegra_clk_sclk,
-       &tegra_clk_hclk,
-       &tegra_clk_pclk,
-       &tegra_clk_d,
-       &tegra_clk_cdev1,
-       &tegra_clk_cdev2,
-       &tegra_clk_virtual_cpu,
-       &tegra_clk_blink,
-       &tegra_clk_cop,
-       &tegra_clk_emc,
-};
-
-static void tegra2_init_one_clock(struct clk *c)
-{
-       clk_init(c);
-       INIT_LIST_HEAD(&c->shared_bus_list);
-       if (!c->lookup.dev_id && !c->lookup.con_id)
-               c->lookup.con_id = c->name;
-       c->lookup.clk = c;
-       clkdev_add(&c->lookup);
-}
-
-void __init tegra2_init_clocks(void)
-{
-       int i;
-       struct clk *c;
-
-       for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
-               tegra2_init_one_clock(tegra_ptr_clks[i]);
-
-       for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
-               tegra2_init_one_clock(&tegra_list_clks[i]);
-
-       for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
-               c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
-               if (!c) {
-                       pr_err("%s: Unknown duplicate clock %s\n", __func__,
-                               tegra_clk_duplicates[i].name);
-                       continue;
-               }
-
-               tegra_clk_duplicates[i].lookup.clk = c;
-               clkdev_add(&tegra_clk_duplicates[i].lookup);
-       }
-
-       init_audio_sync_clock_mux();
-}
-
-#ifdef CONFIG_PM
-static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
-                          PERIPH_CLK_SOURCE_NUM + 22];
-
-void tegra_clk_suspend(void)
-{
-       unsigned long off, i;
-       u32 *ctx = clk_rst_suspend;
-
-       *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
-       *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
-       *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
-       *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
-       *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
-       *ctx++ = clk_readl(tegra_pll_s.reg + PLL_BASE);
-       *ctx++ = clk_readl(tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
-       *ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE);
-       *ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
-       *ctx++ = clk_readl(tegra_pll_u.reg + PLL_BASE);
-       *ctx++ = clk_readl(tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
-
-       *ctx++ = clk_readl(tegra_pll_m_out1.reg);
-       *ctx++ = clk_readl(tegra_pll_a_out0.reg);
-       *ctx++ = clk_readl(tegra_pll_c_out1.reg);
-
-       *ctx++ = clk_readl(tegra_clk_cclk.reg);
-       *ctx++ = clk_readl(tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
-
-       *ctx++ = clk_readl(tegra_clk_sclk.reg);
-       *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
-       *ctx++ = clk_readl(tegra_clk_pclk.reg);
-
-       *ctx++ = clk_readl(tegra_clk_audio.reg);
-
-       for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
-                       off += 4) {
-               if (off == PERIPH_CLK_SOURCE_EMC)
-                       continue;
-               *ctx++ = clk_readl(off);
-       }
-
-       off = RST_DEVICES;
-       for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
-               *ctx++ = clk_readl(off);
-
-       off = CLK_OUT_ENB;
-       for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
-               *ctx++ = clk_readl(off);
-
-       *ctx++ = clk_readl(MISC_CLK_ENB);
-       *ctx++ = clk_readl(CLK_MASK_ARM);
-
-       BUG_ON(ctx - clk_rst_suspend != ARRAY_SIZE(clk_rst_suspend));
-}
-
-void tegra_clk_resume(void)
-{
-       unsigned long off, i;
-       const u32 *ctx = clk_rst_suspend;
-       u32 val;
-
-       val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
-       val |= *ctx++;
-       clk_writel(val, OSC_CTRL);
-
-       clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE);
-       clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
-       clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE);
-       clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
-       clk_writel(*ctx++, tegra_pll_s.reg + PLL_BASE);
-       clk_writel(*ctx++, tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
-       clk_writel(*ctx++, tegra_pll_d.reg + PLL_BASE);
-       clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
-       clk_writel(*ctx++, tegra_pll_u.reg + PLL_BASE);
-       clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
-       udelay(1000);
-
-       clk_writel(*ctx++, tegra_pll_m_out1.reg);
-       clk_writel(*ctx++, tegra_pll_a_out0.reg);
-       clk_writel(*ctx++, tegra_pll_c_out1.reg);
-
-       clk_writel(*ctx++, tegra_clk_cclk.reg);
-       clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
-
-       clk_writel(*ctx++, tegra_clk_sclk.reg);
-       clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
-       clk_writel(*ctx++, tegra_clk_pclk.reg);
-
-       clk_writel(*ctx++, tegra_clk_audio.reg);
-
-       /* enable all clocks before configuring clock sources */
-       clk_writel(0xbffffff9ul, CLK_OUT_ENB);
-       clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
-       clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
-       wmb();
-
-       for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
-                       off += 4) {
-               if (off == PERIPH_CLK_SOURCE_EMC)
-                       continue;
-               clk_writel(*ctx++, off);
-       }
-       wmb();
-
-       off = RST_DEVICES;
-       for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
-               clk_writel(*ctx++, off);
-       wmb();
-
-       off = CLK_OUT_ENB;
-       for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
-               clk_writel(*ctx++, off);
-       wmb();
-
-       clk_writel(*ctx++, MISC_CLK_ENB);
-       clk_writel(*ctx++, CLK_MASK_ARM);
-}
-#endif
index 6674f100e16f8076e804a508a488e6c5e36a8a9b..63615dadfbb20a8ed71ab3aa2aa7324065f7f882 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/tegra30_clocks.c
  *
- * Copyright (c) 2010-2011 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2010-2012 NVIDIA CORPORATION.  All rights reserved.
  *
  * 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
@@ -365,30 +365,32 @@ static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
 static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
 
 #define clk_writel(value, reg) \
-       __raw_writel(value, (u32)reg_clk_base + (reg))
+       __raw_writel(value, reg_clk_base + (reg))
 #define clk_readl(reg) \
-       __raw_readl((u32)reg_clk_base + (reg))
+       __raw_readl(reg_clk_base + (reg))
 #define pmc_writel(value, reg) \
-       __raw_writel(value, (u32)reg_pmc_base + (reg))
+       __raw_writel(value, reg_pmc_base + (reg))
 #define pmc_readl(reg) \
-       __raw_readl((u32)reg_pmc_base + (reg))
+       __raw_readl(reg_pmc_base + (reg))
 #define chipid_readl() \
-       __raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
+       __raw_readl(misc_gp_hidrev_base + MISC_GP_HIDREV)
 
 #define clk_writel_delay(value, reg)                                   \
        do {                                                            \
-               __raw_writel((value), (u32)reg_clk_base + (reg));       \
+               __raw_writel((value), reg_clk_base + (reg));    \
                udelay(2);                                              \
        } while (0)
 
-
-static inline int clk_set_div(struct clk *c, u32 n)
+static inline int clk_set_div(struct clk_tegra *c, u32 n)
 {
-       return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
+       struct clk *clk = c->hw.clk;
+
+       return clk_set_rate(clk,
+                       (__clk_get_rate(__clk_get_parent(clk)) + n - 1) / n);
 }
 
 static inline u32 periph_clk_to_reg(
-       struct clk *c, u32 reg_L, u32 reg_V, int offs)
+       struct clk_tegra *c, u32 reg_L, u32 reg_V, int offs)
 {
        u32 reg = c->u.periph.clk_num / 32;
        BUG_ON(reg >= RST_DEVICES_NUM);
@@ -470,15 +472,32 @@ static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
        return divider_u16 - 1;
 }
 
+static unsigned long tegra30_clk_fixed_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return to_clk_tegra(hw)->fixed_rate;
+}
+
+struct clk_ops tegra30_clk_32k_ops = {
+       .recalc_rate = tegra30_clk_fixed_recalc_rate,
+};
+
 /* clk_m functions */
-static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c)
+static unsigned long tegra30_clk_m_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       if (!to_clk_tegra(hw)->fixed_rate)
+               to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq();
+       return to_clk_tegra(hw)->fixed_rate;
+}
+
+static void tegra30_clk_m_init(struct clk_hw *hw)
 {
        u32 osc_ctrl = clk_readl(OSC_CTRL);
        u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
        u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
 
-       c->rate = clk_measure_input_freq();
-       switch (c->rate) {
+       switch (to_clk_tegra(hw)->fixed_rate) {
        case 12000000:
                auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
                BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
@@ -508,46 +527,44 @@ static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c)
                BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
                break;
        default:
-               pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
+               pr_err("%s: Unexpected clock rate %ld", __func__,
+                               to_clk_tegra(hw)->fixed_rate);
                BUG();
        }
        clk_writel(auto_clock_control, OSC_CTRL);
-       return c->rate;
 }
 
-static void tegra30_clk_m_init(struct clk *c)
-{
-       pr_debug("%s on clock %s\n", __func__, c->name);
-       tegra30_clk_m_autodetect_rate(c);
-}
+struct clk_ops tegra30_clk_m_ops = {
+       .init = tegra30_clk_m_init,
+       .recalc_rate = tegra30_clk_m_recalc_rate,
+};
 
-static int tegra30_clk_m_enable(struct clk *c)
+static unsigned long tegra30_clk_m_div_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
 {
-       pr_debug("%s on clock %s\n", __func__, c->name);
-       return 0;
-}
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
 
-static void tegra30_clk_m_disable(struct clk *c)
-{
-       pr_debug("%s on clock %s\n", __func__, c->name);
-       WARN(1, "Attempting to disable main SoC clock\n");
-}
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
 
-static struct clk_ops tegra_clk_m_ops = {
-       .init           = tegra30_clk_m_init,
-       .enable         = tegra30_clk_m_enable,
-       .disable        = tegra30_clk_m_disable,
-};
+       return rate;
+}
 
-static struct clk_ops tegra_clk_m_div_ops = {
-       .enable         = tegra30_clk_m_enable,
+struct clk_ops tegra_clk_m_div_ops = {
+       .recalc_rate = tegra30_clk_m_div_recalc_rate,
 };
 
 /* PLL reference divider functions */
-static void tegra30_pll_ref_init(struct clk *c)
+static unsigned long tegra30_pll_ref_recalc_rate(struct clk_hw *hw,
+                       unsigned long parent_rate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long rate = parent_rate;
        u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK;
-       pr_debug("%s on clock %s\n", __func__, c->name);
 
        switch (pll_ref_div) {
        case OSC_CTRL_PLL_REF_DIV_1:
@@ -564,13 +581,18 @@ static void tegra30_pll_ref_init(struct clk *c)
                BUG();
        }
        c->mul = 1;
-       c->state = ON;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
 }
 
-static struct clk_ops tegra_pll_ref_ops = {
-       .init           = tegra30_pll_ref_init,
-       .enable         = tegra30_clk_m_enable,
-       .disable        = tegra30_clk_m_disable,
+struct clk_ops tegra_pll_ref_ops = {
+       .recalc_rate = tegra30_pll_ref_recalc_rate,
 };
 
 /* super clock functions */
@@ -581,56 +603,50 @@ static struct clk_ops tegra_pll_ref_ops = {
  * only when its parent is a fixed rate PLL, since we can't change PLL rate
  * in this case.
  */
-static void tegra30_super_clk_init(struct clk *c)
+static void tegra30_super_clk_init(struct clk_hw *hw)
 {
-       u32 val;
-       int source;
-       int shift;
-       const struct clk_mux_sel *sel;
-       val = clk_readl(c->reg + SUPER_CLK_MUX);
-       c->state = ON;
-       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
-               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
-       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
-               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
-       source = (val >> shift) & SUPER_SOURCE_MASK;
-       if (c->flags & DIV_2)
-               source |= val & SUPER_LP_DIV2_BYPASS;
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->value == source)
-                       break;
-       }
-       BUG_ON(sel->input == NULL);
-       c->parent = sel->input;
+       struct clk_tegra *c = to_clk_tegra(hw);
+       struct clk_tegra *p =
+                       to_clk_tegra(__clk_get_hw(__clk_get_parent(hw->clk)));
 
+       c->state = ON;
        if (c->flags & DIV_U71) {
                /* Init safe 7.1 divider value (does not affect PLLX path) */
                clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT,
                           c->reg + SUPER_CLK_DIVIDER);
                c->mul = 2;
                c->div = 2;
-               if (!(c->parent->flags & PLLX))
+               if (!(p->flags & PLLX))
                        c->div += SUPER_CLOCK_DIV_U71_MIN;
        } else
                clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
 }
 
-static int tegra30_super_clk_enable(struct clk *c)
+static u8 tegra30_super_clk_get_parent(struct clk_hw *hw)
 {
-       return 0;
-}
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+       int source;
+       int shift;
 
-static void tegra30_super_clk_disable(struct clk *c)
-{
-       /* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and
-          geared up g-mode super clock - mode switch may request to disable
-          either of them; accept request with no affect on h/w */
+       val = clk_readl(c->reg + SUPER_CLK_MUX);
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+       source = (val >> shift) & SUPER_SOURCE_MASK;
+       if (c->flags & DIV_2)
+               source |= val & SUPER_LP_DIV2_BYPASS;
+
+       return source;
 }
 
-static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p)
+static int tegra30_super_clk_set_parent(struct clk_hw *hw, u8 index)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+       struct clk_tegra *p =
+                       to_clk_tegra(__clk_get_hw(clk_get_parent(hw->clk)));
        u32 val;
-       const struct clk_mux_sel *sel;
        int shift;
 
        val = clk_readl(c->reg + SUPER_CLK_MUX);
@@ -638,48 +654,36 @@ static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p)
                ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
        shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
                SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       /* For LP mode super-clock switch between PLLX direct
-                          and divided-by-2 outputs is allowed only when other
-                          than PLLX clock source is current parent */
-                       if ((c->flags & DIV_2) && (p->flags & PLLX) &&
-                           ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) {
-                               if (c->parent->flags & PLLX)
-                                       return -EINVAL;
-                               val ^= SUPER_LP_DIV2_BYPASS;
-                               clk_writel_delay(val, c->reg);
-                       }
-                       val &= ~(SUPER_SOURCE_MASK << shift);
-                       val |= (sel->value & SUPER_SOURCE_MASK) << shift;
-
-                       /* 7.1 divider for CPU super-clock does not affect
-                          PLLX path */
-                       if (c->flags & DIV_U71) {
-                               u32 div = 0;
-                               if (!(p->flags & PLLX)) {
-                                       div = clk_readl(c->reg +
-                                                       SUPER_CLK_DIVIDER);
-                                       div &= SUPER_CLOCK_DIV_U71_MASK;
-                                       div >>= SUPER_CLOCK_DIV_U71_SHIFT;
-                               }
-                               c->div = div + 2;
-                               c->mul = 2;
-                       }
 
-                       if (c->refcnt)
-                               clk_enable(p);
-
-                       clk_writel_delay(val, c->reg);
-
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
+       /* For LP mode super-clock switch between PLLX direct
+          and divided-by-2 outputs is allowed only when other
+          than PLLX clock source is current parent */
+       if ((c->flags & DIV_2) && (p->flags & PLLX) &&
+           ((index ^ val) & SUPER_LP_DIV2_BYPASS)) {
+               if (p->flags & PLLX)
+                       return -EINVAL;
+               val ^= SUPER_LP_DIV2_BYPASS;
+               clk_writel_delay(val, c->reg);
+       }
+       val &= ~(SUPER_SOURCE_MASK << shift);
+       val |= (index & SUPER_SOURCE_MASK) << shift;
 
-                       clk_reparent(c, p);
-                       return 0;
+       /* 7.1 divider for CPU super-clock does not affect
+          PLLX path */
+       if (c->flags & DIV_U71) {
+               u32 div = 0;
+               if (!(p->flags & PLLX)) {
+                       div = clk_readl(c->reg +
+                                       SUPER_CLK_DIVIDER);
+                       div &= SUPER_CLOCK_DIV_U71_MASK;
+                       div >>= SUPER_CLOCK_DIV_U71_SHIFT;
                }
+               c->div = div + 2;
+               c->mul = 2;
        }
-       return -EINVAL;
+       clk_writel_delay(val, c->reg);
+
+       return 0;
 }
 
 /*
@@ -691,10 +695,15 @@ static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p)
  * rate of this PLL can't be changed, and it has many other children. In
  * this case use 7.1 fractional divider to adjust the super clock rate.
  */
-static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate)
+static int tegra30_super_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
 {
-       if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) {
-               int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate,
+       struct clk_tegra *c = to_clk_tegra(hw);
+       struct clk *parent = __clk_get_parent(hw->clk);
+       struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent));
+
+       if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) {
+               int div = clk_div71_get_divider(parent_rate,
                                        rate, c->flags, ROUND_DIVIDER_DOWN);
                div = max(div, SUPER_CLOCK_DIV_U71_MIN);
 
@@ -704,55 +713,86 @@ static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate)
                c->mul = 2;
                return 0;
        }
-       return clk_set_rate(c->parent, rate);
+       return 0;
+}
+
+static unsigned long tegra30_super_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
+}
+
+static long tegra30_super_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       struct clk *parent = __clk_get_parent(hw->clk);
+       struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent));
+       int mul = 2;
+       int div;
+
+       if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) {
+               div = clk_div71_get_divider(*prate,
+                               rate, c->flags, ROUND_DIVIDER_DOWN);
+               div = max(div, SUPER_CLOCK_DIV_U71_MIN) + 2;
+               rate = *prate * mul;
+               rate += div - 1; /* round up */
+               do_div(rate, c->div);
+
+               return rate;
+       }
+       return *prate;
 }
 
-static struct clk_ops tegra_super_ops = {
-       .init                   = tegra30_super_clk_init,
-       .enable                 = tegra30_super_clk_enable,
-       .disable                = tegra30_super_clk_disable,
-       .set_parent             = tegra30_super_clk_set_parent,
-       .set_rate               = tegra30_super_clk_set_rate,
+struct clk_ops tegra30_super_ops = {
+       .init = tegra30_super_clk_init,
+       .set_parent = tegra30_super_clk_set_parent,
+       .get_parent = tegra30_super_clk_get_parent,
+       .recalc_rate = tegra30_super_clk_recalc_rate,
+       .round_rate = tegra30_super_clk_round_rate,
+       .set_rate = tegra30_super_clk_set_rate,
 };
 
-static int tegra30_twd_clk_set_rate(struct clk *c, unsigned long rate)
+static unsigned long tegra30_twd_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
 {
-       /* The input value 'rate' is the clock rate of the CPU complex. */
-       c->rate = (rate * c->mul) / c->div;
-       return 0;
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
 }
 
-static struct clk_ops tegra30_twd_ops = {
-       .set_rate       = tegra30_twd_clk_set_rate,
+struct clk_ops tegra30_twd_ops = {
+       .recalc_rate = tegra30_twd_clk_recalc_rate,
 };
 
 /* Blink output functions */
-
-static void tegra30_blink_clk_init(struct clk *c)
+static int tegra30_blink_clk_is_enabled(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
 
        val = pmc_readl(PMC_CTRL);
        c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
-       c->mul = 1;
-       val = pmc_readl(c->reg);
-
-       if (val & PMC_BLINK_TIMER_ENB) {
-               unsigned int on_off;
-
-               on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
-                       PMC_BLINK_TIMER_DATA_ON_MASK;
-               val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
-               val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
-               on_off += val;
-               /* each tick in the blink timer is 4 32KHz clocks */
-               c->div = on_off * 4;
-       } else {
-               c->div = 1;
-       }
+       return c->state;
 }
 
-static int tegra30_blink_clk_enable(struct clk *c)
+static int tegra30_blink_clk_enable(struct clk_hw *hw)
 {
        u32 val;
 
@@ -765,7 +805,7 @@ static int tegra30_blink_clk_enable(struct clk *c)
        return 0;
 }
 
-static void tegra30_blink_clk_disable(struct clk *c)
+static void tegra30_blink_clk_disable(struct clk_hw *hw)
 {
        u32 val;
 
@@ -776,9 +816,11 @@ static void tegra30_blink_clk_disable(struct clk *c)
        pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
 }
 
-static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate)
+static int tegra30_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
 {
-       unsigned long parent_rate = clk_get_rate(c->parent);
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        if (rate >= parent_rate) {
                c->div = 1;
                pmc_writel(0, c->reg);
@@ -801,41 +843,77 @@ static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate)
        return 0;
 }
 
-static struct clk_ops tegra_blink_clk_ops = {
-       .init                   = &tegra30_blink_clk_init,
-       .enable                 = &tegra30_blink_clk_enable,
-       .disable                = &tegra30_blink_clk_disable,
-       .set_rate               = &tegra30_blink_clk_set_rate,
-};
+static unsigned long tegra30_blink_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+       u32 val;
+       u32 mul;
+       u32 div;
+       u32 on_off;
 
-/* PLL Functions */
-static int tegra30_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg,
-                                        u32 lock_bit)
+       mul = 1;
+       val = pmc_readl(c->reg);
+
+       if (val & PMC_BLINK_TIMER_ENB) {
+               on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
+                       PMC_BLINK_TIMER_DATA_ON_MASK;
+               val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+               val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+               on_off += val;
+               /* each tick in the blink timer is 4 32KHz clocks */
+               div = on_off * 4;
+       } else {
+               div = 1;
+       }
+
+       if (mul != 0 && div != 0) {
+               rate *= mul;
+               rate += div - 1; /* round up */
+               do_div(rate, div);
+       }
+       return rate;
+}
+
+static long tegra30_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
 {
-#if USE_PLL_LOCK_BITS
-       int i;
-       for (i = 0; i < c->u.pll.lock_delay; i++) {
-               if (clk_readl(lock_reg) & lock_bit) {
-                       udelay(PLL_POST_LOCK_DELAY);
-                       return 0;
-               }
-               udelay(2);              /* timeout = 2 * lock time */
+       int div;
+       int mul;
+       long round_rate = *prate;
+
+       mul = 1;
+
+       if (rate >= *prate) {
+               div = 1;
+       } else {
+               div = DIV_ROUND_UP(*prate / 8, rate);
+               div *= 8;
        }
-       pr_err("Timed out waiting for lock bit on pll %s", c->name);
-       return -1;
-#endif
-       udelay(c->u.pll.lock_delay);
 
-       return 0;
+       round_rate *= mul;
+       round_rate += div - 1;
+       do_div(round_rate, div);
+
+       return round_rate;
 }
 
+struct clk_ops tegra30_blink_clk_ops = {
+       .is_enabled = tegra30_blink_clk_is_enabled,
+       .enable = tegra30_blink_clk_enable,
+       .disable = tegra30_blink_clk_disable,
+       .recalc_rate = tegra30_blink_clk_recalc_rate,
+       .round_rate = tegra30_blink_clk_round_rate,
+       .set_rate = tegra30_blink_clk_set_rate,
+};
 
-static void tegra30_utmi_param_configure(struct clk *c)
+static void tegra30_utmi_param_configure(struct clk_hw *hw)
 {
+       unsigned long main_rate =
+               __clk_get_rate(__clk_get_parent(__clk_get_parent(hw->clk)));
        u32 reg;
        int i;
-       unsigned long main_rate =
-               clk_get_rate(c->parent->parent);
 
        for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
                if (main_rate == utmi_parameters[i].osc_frequency)
@@ -886,50 +964,52 @@ static void tegra30_utmi_param_configure(struct clk *c)
        clk_writel(reg, UTMIP_PLL_CFG1);
 }
 
-static void tegra30_pll_clk_init(struct clk *c)
+/* PLL Functions */
+static int tegra30_pll_clk_wait_for_lock(struct clk_tegra *c, u32 lock_reg,
+                                        u32 lock_bit)
+{
+       int ret = 0;
+
+#if USE_PLL_LOCK_BITS
+       int i;
+       for (i = 0; i < c->u.pll.lock_delay; i++) {
+               if (clk_readl(lock_reg) & lock_bit) {
+                       udelay(PLL_POST_LOCK_DELAY);
+                       return 0;
+               }
+               udelay(2);      /* timeout = 2 * lock time */
+       }
+       pr_err("Timed out waiting for lock bit on pll %s",
+                                       __clk_get_name(hw->clk));
+       ret = -1;
+#else
+       udelay(c->u.pll.lock_delay);
+#endif
+       return ret;
+}
+
+static int tegra30_pll_clk_is_enabled(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val = clk_readl(c->reg + PLL_BASE);
 
        c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
+       return c->state;
+}
 
-       if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
-               const struct clk_pll_freq_table *sel;
-               unsigned long input_rate = clk_get_rate(c->parent);
-               for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
-                       if (sel->input_rate == input_rate &&
-                               sel->output_rate == c->u.pll.fixed_rate) {
-                               c->mul = sel->n;
-                               c->div = sel->m * sel->p;
-                               return;
-                       }
-               }
-               pr_err("Clock %s has unknown fixed frequency\n", c->name);
-               BUG();
-       } else if (val & PLL_BASE_BYPASS) {
-               c->mul = 1;
-               c->div = 1;
-       } else {
-               c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
-               c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
-               if (c->flags & PLLU)
-                       c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
-               else
-                       c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
-                                       PLL_BASE_DIVP_SHIFT));
-               if (c->flags & PLL_FIXED) {
-                       unsigned long rate = clk_get_rate_locked(c);
-                       BUG_ON(rate != c->u.pll.fixed_rate);
-               }
-       }
+static void tegra30_pll_clk_init(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
 
        if (c->flags & PLLU)
-               tegra30_utmi_param_configure(c);
+               tegra30_utmi_param_configure(hw);
 }
 
-static int tegra30_pll_clk_enable(struct clk *c)
+static int tegra30_pll_clk_enable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
-       pr_debug("%s on clock %s\n", __func__, c->name);
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
 
 #if USE_PLL_LOCK_BITS
        val = clk_readl(c->reg + PLL_MISC(c));
@@ -952,10 +1032,11 @@ static int tegra30_pll_clk_enable(struct clk *c)
        return 0;
 }
 
-static void tegra30_pll_clk_disable(struct clk *c)
+static void tegra30_pll_clk_disable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
-       pr_debug("%s on clock %s\n", __func__, c->name);
+       pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
 
        val = clk_readl(c->reg);
        val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
@@ -968,36 +1049,36 @@ static void tegra30_pll_clk_disable(struct clk *c)
        }
 }
 
-static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate)
+static int tegra30_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val, p_div, old_base;
        unsigned long input_rate;
        const struct clk_pll_freq_table *sel;
        struct clk_pll_freq_table cfg;
 
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
-
        if (c->flags & PLL_FIXED) {
                int ret = 0;
                if (rate != c->u.pll.fixed_rate) {
                        pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
-                              __func__, c->name, c->u.pll.fixed_rate, rate);
+                              __func__, __clk_get_name(hw->clk),
+                               c->u.pll.fixed_rate, rate);
                        ret = -EINVAL;
                }
                return ret;
        }
 
        if (c->flags & PLLM) {
-               if (rate != clk_get_rate_locked(c)) {
+               if (rate != __clk_get_rate(hw->clk)) {
                        pr_err("%s: Can not change memory %s rate in flight\n",
-                              __func__, c->name);
+                               __func__, __clk_get_name(hw->clk));
                        return -EINVAL;
                }
-               return 0;
        }
 
        p_div = 0;
-       input_rate = clk_get_rate(c->parent);
+       input_rate = parent_rate;
 
        /* Check if the target rate is tabulated */
        for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
@@ -1055,7 +1136,7 @@ static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate)
                    (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
                    (cfg.output_rate > c->u.pll.vco_max)) {
                        pr_err("%s: Failed to set %s out-of-table rate %lu\n",
-                              __func__, c->name, rate);
+                              __func__, __clk_get_name(hw->clk), rate);
                        return -EINVAL;
                }
                p_div <<= PLL_BASE_DIVP_SHIFT;
@@ -1073,7 +1154,7 @@ static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate)
                return 0;
 
        if (c->state == ON) {
-               tegra30_pll_clk_disable(c);
+               tegra30_pll_clk_disable(hw);
                val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
        }
        clk_writel(val, c->reg + PLL_BASE);
@@ -1095,89 +1176,203 @@ static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate)
        }
 
        if (c->state == ON)
-               tegra30_pll_clk_enable(c);
-
-       return 0;
-}
-
-static struct clk_ops tegra_pll_ops = {
-       .init                   = tegra30_pll_clk_init,
-       .enable                 = tegra30_pll_clk_enable,
-       .disable                = tegra30_pll_clk_disable,
-       .set_rate               = tegra30_pll_clk_set_rate,
-};
-
-static int
-tegra30_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
-{
-       u32 val, mask, reg;
+               tegra30_pll_clk_enable(hw);
 
-       switch (p) {
-       case TEGRA_CLK_PLLD_CSI_OUT_ENB:
-               mask = PLLD_BASE_CSI_CLKENABLE;
-               reg = c->reg + PLL_BASE;
-               break;
-       case TEGRA_CLK_PLLD_DSI_OUT_ENB:
-               mask = PLLD_MISC_DSI_CLKENABLE;
-               reg = c->reg + PLL_MISC(c);
-               break;
-       case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
-               if (!(c->flags & PLL_ALT_MISC_REG)) {
-                       mask = PLLD_BASE_DSIB_MUX_MASK;
-                       reg = c->reg + PLL_BASE;
-                       break;
-               }
-       /* fall through - error since PLLD2 does not have MUX_SEL control */
-       default:
-               return -EINVAL;
-       }
+       c->u.pll.fixed_rate = rate;
 
-       val = clk_readl(reg);
-       if (setting)
-               val |= mask;
-       else
-               val &= ~mask;
-       clk_writel(val, reg);
        return 0;
 }
 
-static struct clk_ops tegra_plld_ops = {
-       .init                   = tegra30_pll_clk_init,
-       .enable                 = tegra30_pll_clk_enable,
-       .disable                = tegra30_pll_clk_disable,
-       .set_rate               = tegra30_pll_clk_set_rate,
-       .clk_cfg_ex             = tegra30_plld_clk_cfg_ex,
-};
-
-static void tegra30_plle_clk_init(struct clk *c)
+static long tegra30_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long input_rate = *prate;
+       unsigned long output_rate = *prate;
+       const struct clk_pll_freq_table *sel;
+       struct clk_pll_freq_table cfg;
+       int mul;
+       int div;
+       u32 p_div;
        u32 val;
 
-       val = clk_readl(PLLE_AUX);
-       c->parent = (val & PLLE_AUX_PLLP_SEL) ?
-               tegra_get_clock_by_name("pll_p") :
-               tegra_get_clock_by_name("pll_ref");
+       if (c->flags & PLL_FIXED)
+               return c->u.pll.fixed_rate;
 
-       val = clk_readl(c->reg + PLL_BASE);
-       c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
-       c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
-       c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
-       c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
-}
+       if (c->flags & PLLM)
+               return __clk_get_rate(hw->clk);
 
-static void tegra30_plle_clk_disable(struct clk *c)
-{
-       u32 val;
-       pr_debug("%s on clock %s\n", __func__, c->name);
+       p_div = 0;
+       /* Check if the target rate is tabulated */
+       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+               if (sel->input_rate == input_rate && sel->output_rate == rate) {
+                       if (c->flags & PLLU) {
+                               BUG_ON(sel->p < 1 || sel->p > 2);
+                               if (sel->p == 1)
+                                       p_div = PLLU_BASE_POST_DIV;
+                       } else {
+                               BUG_ON(sel->p < 1);
+                               for (val = sel->p; val > 1; val >>= 1)
+                                       p_div++;
+                               p_div <<= PLL_BASE_DIVP_SHIFT;
+                       }
+                       break;
+               }
+       }
 
-       val = clk_readl(c->reg + PLL_BASE);
-       val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
-       clk_writel(val, c->reg + PLL_BASE);
-}
+       if (sel->input_rate == 0) {
+               unsigned long cfreq;
+               BUG_ON(c->flags & PLLU);
+               sel = &cfg;
 
-static void tegra30_plle_training(struct clk *c)
-{
-       u32 val;
+               switch (input_rate) {
+               case 12000000:
+               case 26000000:
+                       cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
+                       break;
+               case 13000000:
+                       cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
+                       break;
+               case 16800000:
+               case 19200000:
+                       cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
+                       break;
+               default:
+                       pr_err("%s: Unexpected reference rate %lu\n",
+                              __func__, input_rate);
+                       BUG();
+               }
+
+               /* Raise VCO to guarantee 0.5% accuracy */
+               for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
+                     cfg.output_rate <<= 1)
+                       p_div++;
+
+               cfg.p = 0x1 << p_div;
+               cfg.m = input_rate / cfreq;
+               cfg.n = cfg.output_rate / cfreq;
+       }
+
+       mul = sel->n;
+       div = sel->m * sel->p;
+
+       output_rate *= mul;
+       output_rate += div - 1; /* round up */
+       do_div(output_rate, div);
+
+       return output_rate;
+}
+
+static unsigned long tegra30_pll_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+       u32 val = clk_readl(c->reg + PLL_BASE);
+
+       if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
+               const struct clk_pll_freq_table *sel;
+               for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+                       if (sel->input_rate == parent_rate &&
+                               sel->output_rate == c->u.pll.fixed_rate) {
+                               c->mul = sel->n;
+                               c->div = sel->m * sel->p;
+                               break;
+                       }
+               }
+               pr_err("Clock %s has unknown fixed frequency\n",
+                                               __clk_get_name(hw->clk));
+               BUG();
+       } else if (val & PLL_BASE_BYPASS) {
+               c->mul = 1;
+               c->div = 1;
+       } else {
+               c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+               c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+               if (c->flags & PLLU)
+                       c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
+               else
+                       c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
+                                       PLL_BASE_DIVP_SHIFT));
+       }
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
+}
+
+struct clk_ops tegra30_pll_ops = {
+       .is_enabled = tegra30_pll_clk_is_enabled,
+       .init = tegra30_pll_clk_init,
+       .enable = tegra30_pll_clk_enable,
+       .disable = tegra30_pll_clk_disable,
+       .recalc_rate = tegra30_pll_recalc_rate,
+       .round_rate = tegra30_pll_round_rate,
+       .set_rate = tegra30_pll_clk_set_rate,
+};
+
+int tegra30_plld_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val, mask, reg;
+
+       switch (p) {
+       case TEGRA_CLK_PLLD_CSI_OUT_ENB:
+               mask = PLLD_BASE_CSI_CLKENABLE;
+               reg = c->reg + PLL_BASE;
+               break;
+       case TEGRA_CLK_PLLD_DSI_OUT_ENB:
+               mask = PLLD_MISC_DSI_CLKENABLE;
+               reg = c->reg + PLL_MISC(c);
+               break;
+       case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
+               if (!(c->flags & PLL_ALT_MISC_REG)) {
+                       mask = PLLD_BASE_DSIB_MUX_MASK;
+                       reg = c->reg + PLL_BASE;
+                       break;
+               }
+       /* fall through - error since PLLD2 does not have MUX_SEL control */
+       default:
+               return -EINVAL;
+       }
+
+       val = clk_readl(reg);
+       if (setting)
+               val |= mask;
+       else
+               val &= ~mask;
+       clk_writel(val, reg);
+       return 0;
+}
+
+static int tegra30_plle_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+
+       val = clk_readl(c->reg + PLL_BASE);
+       c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
+       return c->state;
+}
+
+static void tegra30_plle_clk_disable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val;
+
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
+       clk_writel(val, c->reg + PLL_BASE);
+}
+
+static void tegra30_plle_training(struct clk_tegra *c)
+{
+       u32 val;
 
        /* PLLE is already disabled, and setup cleared;
         * create falling edge on PLLE IDDQ input */
@@ -1198,12 +1393,15 @@ static void tegra30_plle_training(struct clk *c)
        } while (!(val & PLLE_MISC_READY));
 }
 
-static int tegra30_plle_configure(struct clk *c, bool force_training)
+static int tegra30_plle_configure(struct clk_hw *hw, bool force_training)
 {
-       u32 val;
+       struct clk_tegra *c = to_clk_tegra(hw);
+       struct clk *parent = __clk_get_parent(hw->clk);
        const struct clk_pll_freq_table *sel;
+       u32 val;
+
        unsigned long rate = c->u.pll.fixed_rate;
-       unsigned long input_rate = clk_get_rate(c->parent);
+       unsigned long input_rate = __clk_get_rate(parent);
 
        for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
                if (sel->input_rate == input_rate && sel->output_rate == rate)
@@ -1214,7 +1412,7 @@ static int tegra30_plle_configure(struct clk *c, bool force_training)
                return -ENOSYS;
 
        /* disable PLLE, clear setup fiels */
-       tegra30_plle_clk_disable(c);
+       tegra30_plle_clk_disable(hw);
 
        val = clk_readl(c->reg + PLL_MISC(c));
        val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
@@ -1252,52 +1450,64 @@ static int tegra30_plle_configure(struct clk *c, bool force_training)
        return 0;
 }
 
-static int tegra30_plle_clk_enable(struct clk *c)
+static int tegra30_plle_clk_enable(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+
+       return tegra30_plle_configure(hw, !c->set);
+}
+
+static unsigned long tegra30_plle_clk_recalc_rate(struct clk_hw *hw,
+                       unsigned long parent_rate)
 {
-       pr_debug("%s on clock %s\n", __func__, c->name);
-       return tegra30_plle_configure(c, !c->set);
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long rate = parent_rate;
+       u32 val;
+
+       val = clk_readl(c->reg + PLL_BASE);
+       c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
+       c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
+       c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+       return rate;
 }
 
-static struct clk_ops tegra_plle_ops = {
-       .init                   = tegra30_plle_clk_init,
-       .enable                 = tegra30_plle_clk_enable,
-       .disable                = tegra30_plle_clk_disable,
+struct clk_ops tegra30_plle_ops = {
+       .is_enabled = tegra30_plle_clk_is_enabled,
+       .enable = tegra30_plle_clk_enable,
+       .disable = tegra30_plle_clk_disable,
+       .recalc_rate = tegra30_plle_clk_recalc_rate,
 };
 
 /* Clock divider ops */
-static void tegra30_pll_div_clk_init(struct clk *c)
+static int tegra30_pll_div_clk_is_enabled(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        if (c->flags & DIV_U71) {
-               u32 divu71;
                u32 val = clk_readl(c->reg);
                val >>= c->reg_shift;
                c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
                if (!(val & PLL_OUT_RESET_DISABLE))
                        c->state = OFF;
-
-               divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
-               c->div = (divu71 + 2);
-               c->mul = 2;
-       } else if (c->flags & DIV_2) {
-               c->state = ON;
-               if (c->flags & (PLLD | PLLX)) {
-                       c->div = 2;
-                       c->mul = 1;
-               } else
-                       BUG();
        } else {
                c->state = ON;
-               c->div = 1;
-               c->mul = 1;
        }
+       return c->state;
 }
 
-static int tegra30_pll_div_clk_enable(struct clk *c)
+static int tegra30_pll_div_clk_enable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
        u32 new_val;
 
-       pr_debug("%s: %s\n", __func__, c->name);
+       pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
        if (c->flags & DIV_U71) {
                val = clk_readl(c->reg);
                new_val = val >> c->reg_shift;
@@ -1315,12 +1525,13 @@ static int tegra30_pll_div_clk_enable(struct clk *c)
        return -EINVAL;
 }
 
-static void tegra30_pll_div_clk_disable(struct clk *c)
+static void tegra30_pll_div_clk_disable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
        u32 new_val;
 
-       pr_debug("%s: %s\n", __func__, c->name);
+       pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
        if (c->flags & DIV_U71) {
                val = clk_readl(c->reg);
                new_val = val >> c->reg_shift;
@@ -1334,14 +1545,14 @@ static void tegra30_pll_div_clk_disable(struct clk *c)
        }
 }
 
-static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
+static int tegra30_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
        u32 new_val;
        int divider_u71;
-       unsigned long parent_rate = clk_get_rate(c->parent);
 
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
        if (c->flags & DIV_U71) {
                divider_u71 = clk_div71_get_divider(
                        parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
@@ -1359,19 +1570,59 @@ static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
                        clk_writel_delay(val, c->reg);
                        c->div = divider_u71 + 2;
                        c->mul = 2;
+                       c->fixed_rate = rate;
                        return 0;
                }
-       } else if (c->flags & DIV_2)
-               return clk_set_rate(c->parent, rate * 2);
+       } else if (c->flags & DIV_2) {
+               c->fixed_rate = rate;
+               return 0;
+       }
 
        return -EINVAL;
 }
 
-static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
+static unsigned long tegra30_pll_div_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+
+       if (c->flags & DIV_U71) {
+               u32 divu71;
+               u32 val = clk_readl(c->reg);
+               val >>= c->reg_shift;
+
+               divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
+               c->div = (divu71 + 2);
+               c->mul = 2;
+       } else if (c->flags & DIV_2) {
+               if (c->flags & (PLLD | PLLX)) {
+                       c->div = 2;
+                       c->mul = 1;
+               } else
+                       BUG();
+       } else {
+               c->div = 1;
+               c->mul = 1;
+       }
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
+}
+
+static long tegra30_pll_div_clk_round_rate(struct clk_hw *hw,
+                               unsigned long rate, unsigned long *prate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int divider;
-       unsigned long parent_rate = clk_get_rate(c->parent);
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (prate)
+               parent_rate = *prate;
 
        if (c->flags & DIV_U71) {
                divider = clk_div71_get_divider(
@@ -1379,23 +1630,25 @@ static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
                if (divider < 0)
                        return divider;
                return DIV_ROUND_UP(parent_rate * 2, divider + 2);
-       } else if (c->flags & DIV_2)
-               /* no rounding - fixed DIV_2 dividers pass rate to parent PLL */
+       } else if (c->flags & DIV_2) {
+               *prate = rate * 2;
                return rate;
+       }
 
        return -EINVAL;
 }
 
-static struct clk_ops tegra_pll_div_ops = {
-       .init                   = tegra30_pll_div_clk_init,
-       .enable                 = tegra30_pll_div_clk_enable,
-       .disable                = tegra30_pll_div_clk_disable,
-       .set_rate               = tegra30_pll_div_clk_set_rate,
-       .round_rate             = tegra30_pll_div_clk_round_rate,
+struct clk_ops tegra30_pll_div_ops = {
+       .is_enabled = tegra30_pll_div_clk_is_enabled,
+       .enable = tegra30_pll_div_clk_enable,
+       .disable = tegra30_pll_div_clk_disable,
+       .set_rate = tegra30_pll_div_clk_set_rate,
+       .recalc_rate = tegra30_pll_div_clk_recalc_rate,
+       .round_rate = tegra30_pll_div_clk_round_rate,
 };
 
 /* Periph clk ops */
-static inline u32 periph_clk_source_mask(struct clk *c)
+static inline u32 periph_clk_source_mask(struct clk_tegra *c)
 {
        if (c->flags & MUX8)
                return 7 << 29;
@@ -1409,7 +1662,7 @@ static inline u32 periph_clk_source_mask(struct clk *c)
                return 3 << 30;
 }
 
-static inline u32 periph_clk_source_shift(struct clk *c)
+static inline u32 periph_clk_source_shift(struct clk_tegra *c)
 {
        if (c->flags & MUX8)
                return 29;
@@ -1423,47 +1676,9 @@ static inline u32 periph_clk_source_shift(struct clk *c)
                return 30;
 }
 
-static void tegra30_periph_clk_init(struct clk *c)
+static int tegra30_periph_clk_is_enabled(struct clk_hw *hw)
 {
-       u32 val = clk_readl(c->reg);
-       const struct clk_mux_sel *mux = 0;
-       const struct clk_mux_sel *sel;
-       if (c->flags & MUX) {
-               for (sel = c->inputs; sel->input != NULL; sel++) {
-                       if (((val & periph_clk_source_mask(c)) >>
-                           periph_clk_source_shift(c)) == sel->value)
-                               mux = sel;
-               }
-               BUG_ON(!mux);
-
-               c->parent = mux->input;
-       } else {
-               c->parent = c->inputs[0].input;
-       }
-
-       if (c->flags & DIV_U71) {
-               u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
-               if ((c->flags & DIV_U71_UART) &&
-                   (!(val & PERIPH_CLK_UART_DIV_ENB))) {
-                       divu71 = 0;
-               }
-               if (c->flags & DIV_U71_IDLE) {
-                       val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
-                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
-                       val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
-                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
-                       clk_writel(val, c->reg);
-               }
-               c->div = divu71 + 2;
-               c->mul = 2;
-       } else if (c->flags & DIV_U16) {
-               u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
-               c->div = divu16 + 1;
-               c->mul = 1;
-       } else {
-               c->div = 1;
-               c->mul = 1;
-       }
+       struct clk_tegra *c = to_clk_tegra(hw);
 
        c->state = ON;
        if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
@@ -1471,11 +1686,12 @@ static void tegra30_periph_clk_init(struct clk *c)
        if (!(c->flags & PERIPH_NO_RESET))
                if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c))
                        c->state = OFF;
+       return c->state;
 }
 
-static int tegra30_periph_clk_enable(struct clk *c)
+static int tegra30_periph_clk_enable(struct clk_hw *hw)
 {
-       pr_debug("%s on clock %s\n", __func__, c->name);
+       struct clk_tegra *c = to_clk_tegra(hw);
 
        tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
        if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
@@ -1494,31 +1710,29 @@ static int tegra30_periph_clk_enable(struct clk *c)
        return 0;
 }
 
-static void tegra30_periph_clk_disable(struct clk *c)
+static void tegra30_periph_clk_disable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        unsigned long val;
-       pr_debug("%s on clock %s\n", __func__, c->name);
 
-       if (c->refcnt)
-               tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
+       tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
+
+       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0)
+               return;
 
-       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) {
-               /* If peripheral is in the APB bus then read the APB bus to
-                * flush the write operation in apb bus. This will avoid the
-                * peripheral access after disabling clock*/
-               if (c->flags & PERIPH_ON_APB)
-                       val = chipid_readl();
+       /* If peripheral is in the APB bus then read the APB bus to
+        * flush the write operation in apb bus. This will avoid the
+        * peripheral access after disabling clock*/
+       if (c->flags & PERIPH_ON_APB)
+               val = chipid_readl();
 
-               clk_writel_delay(
-                       PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
-       }
+       clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
 }
 
-static void tegra30_periph_clk_reset(struct clk *c, bool assert)
+void tegra30_periph_clk_reset(struct clk_hw *hw, bool assert)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        unsigned long val;
-       pr_debug("%s %s on clock %s\n", __func__,
-                assert ? "assert" : "deassert", c->name);
 
        if (!(c->flags & PERIPH_NO_RESET)) {
                if (assert) {
@@ -1537,42 +1751,40 @@ static void tegra30_periph_clk_reset(struct clk *c, bool assert)
        }
 }
 
-static int tegra30_periph_clk_set_parent(struct clk *c, struct clk *p)
+static int tegra30_periph_clk_set_parent(struct clk_hw *hw, u8 index)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
-       const struct clk_mux_sel *sel;
-       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
 
        if (!(c->flags & MUX))
-               return (p == c->parent) ? 0 : (-EINVAL);
+               return (index == 0) ? 0 : (-EINVAL);
 
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       val = clk_readl(c->reg);
-                       val &= ~periph_clk_source_mask(c);
-                       val |= (sel->value << periph_clk_source_shift(c));
-
-                       if (c->refcnt)
-                               clk_enable(p);
-
-                       clk_writel_delay(val, c->reg);
+       val = clk_readl(c->reg);
+       val &= ~periph_clk_source_mask(c);
+       val |= (index << periph_clk_source_shift(c));
+       clk_writel_delay(val, c->reg);
+       return 0;
+}
 
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
+static u8 tegra30_periph_clk_get_parent(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+       int source  = (val & periph_clk_source_mask(c)) >>
+                                       periph_clk_source_shift(c);
 
-                       clk_reparent(c, p);
-                       return 0;
-               }
-       }
+       if (!(c->flags & MUX))
+               return 0;
 
-       return -EINVAL;
+       return source;
 }
 
-static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate)
+static int tegra30_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
        int divider;
-       unsigned long parent_rate = clk_get_rate(c->parent);
 
        if (c->flags & DIV_U71) {
                divider = clk_div71_get_divider(
@@ -1611,12 +1823,15 @@ static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate)
        return -EINVAL;
 }
 
-static long tegra30_periph_clk_round_rate(struct clk *c,
-       unsigned long rate)
+static long tegra30_periph_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int divider;
-       unsigned long parent_rate = clk_get_rate(c->parent);
-       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (prate)
+               parent_rate = *prate;
 
        if (c->flags & DIV_U71) {
                divider = clk_div71_get_divider(
@@ -1634,21 +1849,85 @@ static long tegra30_periph_clk_round_rate(struct clk *c,
        return -EINVAL;
 }
 
-static struct clk_ops tegra_periph_clk_ops = {
-       .init                   = &tegra30_periph_clk_init,
-       .enable                 = &tegra30_periph_clk_enable,
-       .disable                = &tegra30_periph_clk_disable,
-       .set_parent             = &tegra30_periph_clk_set_parent,
-       .set_rate               = &tegra30_periph_clk_set_rate,
-       .round_rate             = &tegra30_periph_clk_round_rate,
-       .reset                  = &tegra30_periph_clk_reset,
-};
+static unsigned long tegra30_periph_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
+       u32 val = clk_readl(c->reg);
+
+       if (c->flags & DIV_U71) {
+               u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
+               if ((c->flags & DIV_U71_UART) &&
+                   (!(val & PERIPH_CLK_UART_DIV_ENB))) {
+                       divu71 = 0;
+               }
+               if (c->flags & DIV_U71_IDLE) {
+                       val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
+                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+                       val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
+                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+                       clk_writel(val, c->reg);
+               }
+               c->div = divu71 + 2;
+               c->mul = 2;
+       } else if (c->flags & DIV_U16) {
+               u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+               c->div = divu16 + 1;
+               c->mul = 1;
+       } else {
+               c->div = 1;
+               c->mul = 1;
+       }
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+       return rate;
+}
 
+struct clk_ops tegra30_periph_clk_ops = {
+       .is_enabled = tegra30_periph_clk_is_enabled,
+       .enable = tegra30_periph_clk_enable,
+       .disable = tegra30_periph_clk_disable,
+       .set_parent = tegra30_periph_clk_set_parent,
+       .get_parent = tegra30_periph_clk_get_parent,
+       .set_rate = tegra30_periph_clk_set_rate,
+       .round_rate = tegra30_periph_clk_round_rate,
+       .recalc_rate = tegra30_periph_clk_recalc_rate,
+};
 
-/* Periph extended clock configuration ops */
-static int
-tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+static int tegra30_dsib_clk_set_parent(struct clk_hw *hw, u8 index)
 {
+       struct clk *d = clk_get_sys(NULL, "pll_d");
+       /* The DSIB parent selection bit is in PLLD base
+          register - can not do direct r-m-w, must be
+          protected by PLLD lock */
+       tegra_clk_cfg_ex(
+               d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, index);
+
+       return 0;
+}
+
+struct clk_ops tegra30_dsib_clk_ops = {
+       .is_enabled = tegra30_periph_clk_is_enabled,
+       .enable                 = &tegra30_periph_clk_enable,
+       .disable                = &tegra30_periph_clk_disable,
+       .set_parent             = &tegra30_dsib_clk_set_parent,
+       .get_parent             = &tegra30_periph_clk_get_parent,
+       .set_rate               = &tegra30_periph_clk_set_rate,
+       .round_rate             = &tegra30_periph_clk_round_rate,
+       .recalc_rate            = &tegra30_periph_clk_recalc_rate,
+};
+
+/* Periph extended clock configuration ops */
+int tegra30_vi_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        if (p == TEGRA_CLK_VI_INP_SEL) {
                u32 val = clk_readl(c->reg);
                val &= ~PERIPH_CLK_VI_SEL_EX_MASK;
@@ -1660,20 +1939,11 @@ tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
        return -EINVAL;
 }
 
-static struct clk_ops tegra_vi_clk_ops = {
-       .init                   = &tegra30_periph_clk_init,
-       .enable                 = &tegra30_periph_clk_enable,
-       .disable                = &tegra30_periph_clk_disable,
-       .set_parent             = &tegra30_periph_clk_set_parent,
-       .set_rate               = &tegra30_periph_clk_set_rate,
-       .round_rate             = &tegra30_periph_clk_round_rate,
-       .clk_cfg_ex             = &tegra30_vi_clk_cfg_ex,
-       .reset                  = &tegra30_periph_clk_reset,
-};
-
-static int
-tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+int tegra30_nand_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) {
                u32 val = clk_readl(c->reg);
                if (setting)
@@ -1686,21 +1956,11 @@ tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
        return -EINVAL;
 }
 
-static struct clk_ops tegra_nand_clk_ops = {
-       .init                   = &tegra30_periph_clk_init,
-       .enable                 = &tegra30_periph_clk_enable,
-       .disable                = &tegra30_periph_clk_disable,
-       .set_parent             = &tegra30_periph_clk_set_parent,
-       .set_rate               = &tegra30_periph_clk_set_rate,
-       .round_rate             = &tegra30_periph_clk_round_rate,
-       .clk_cfg_ex             = &tegra30_nand_clk_cfg_ex,
-       .reset                  = &tegra30_periph_clk_reset,
-};
-
-
-static int
-tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+int tegra30_dtv_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        if (p == TEGRA_CLK_DTV_INVERT) {
                u32 val = clk_readl(c->reg);
                if (setting)
@@ -1713,91 +1973,27 @@ tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
        return -EINVAL;
 }
 
-static struct clk_ops tegra_dtv_clk_ops = {
-       .init                   = &tegra30_periph_clk_init,
-       .enable                 = &tegra30_periph_clk_enable,
-       .disable                = &tegra30_periph_clk_disable,
-       .set_parent             = &tegra30_periph_clk_set_parent,
-       .set_rate               = &tegra30_periph_clk_set_rate,
-       .round_rate             = &tegra30_periph_clk_round_rate,
-       .clk_cfg_ex             = &tegra30_dtv_clk_cfg_ex,
-       .reset                  = &tegra30_periph_clk_reset,
-};
-
-static int tegra30_dsib_clk_set_parent(struct clk *c, struct clk *p)
-{
-       const struct clk_mux_sel *sel;
-       struct clk *d = tegra_get_clock_by_name("pll_d");
-
-       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
-
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       if (c->refcnt)
-                               clk_enable(p);
-
-                       /* The DSIB parent selection bit is in PLLD base
-                          register - can not do direct r-m-w, must be
-                          protected by PLLD lock */
-                       tegra_clk_cfg_ex(
-                               d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value);
-
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
-
-                       clk_reparent(c, p);
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static struct clk_ops tegra_dsib_clk_ops = {
-       .init                   = &tegra30_periph_clk_init,
-       .enable                 = &tegra30_periph_clk_enable,
-       .disable                = &tegra30_periph_clk_disable,
-       .set_parent             = &tegra30_dsib_clk_set_parent,
-       .set_rate               = &tegra30_periph_clk_set_rate,
-       .round_rate             = &tegra30_periph_clk_round_rate,
-       .reset                  = &tegra30_periph_clk_reset,
-};
-
-/* pciex clock support only reset function */
-static struct clk_ops tegra_pciex_clk_ops = {
-       .reset    = tegra30_periph_clk_reset,
-};
-
 /* Output clock ops */
 
 static DEFINE_SPINLOCK(clk_out_lock);
 
-static void tegra30_clk_out_init(struct clk *c)
+static int tegra30_clk_out_is_enabled(struct clk_hw *hw)
 {
-       const struct clk_mux_sel *mux = 0;
-       const struct clk_mux_sel *sel;
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val = pmc_readl(c->reg);
 
        c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF;
        c->mul = 1;
        c->div = 1;
-
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (((val & periph_clk_source_mask(c)) >>
-                    periph_clk_source_shift(c)) == sel->value)
-                       mux = sel;
-       }
-       BUG_ON(!mux);
-       c->parent = mux->input;
+       return c->state;
 }
 
-static int tegra30_clk_out_enable(struct clk *c)
+static int tegra30_clk_out_enable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
        unsigned long flags;
 
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
        spin_lock_irqsave(&clk_out_lock, flags);
        val = pmc_readl(c->reg);
        val |= (0x1 << c->u.periph.clk_num);
@@ -1807,13 +2003,12 @@ static int tegra30_clk_out_enable(struct clk *c)
        return 0;
 }
 
-static void tegra30_clk_out_disable(struct clk *c)
+static void tegra30_clk_out_disable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
        unsigned long flags;
 
-       pr_debug("%s on clock %s\n", __func__, c->name);
-
        spin_lock_irqsave(&clk_out_lock, flags);
        val = pmc_readl(c->reg);
        val &= ~(0x1 << c->u.periph.clk_num);
@@ -1821,59 +2016,59 @@ static void tegra30_clk_out_disable(struct clk *c)
        spin_unlock_irqrestore(&clk_out_lock, flags);
 }
 
-static int tegra30_clk_out_set_parent(struct clk *c, struct clk *p)
+static int tegra30_clk_out_set_parent(struct clk_hw *hw, u8 index)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
        unsigned long flags;
-       const struct clk_mux_sel *sel;
 
-       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
-
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       if (c->refcnt)
-                               clk_enable(p);
+       spin_lock_irqsave(&clk_out_lock, flags);
+       val = pmc_readl(c->reg);
+       val &= ~periph_clk_source_mask(c);
+       val |= (index << periph_clk_source_shift(c));
+       pmc_writel(val, c->reg);
+       spin_unlock_irqrestore(&clk_out_lock, flags);
 
-                       spin_lock_irqsave(&clk_out_lock, flags);
-                       val = pmc_readl(c->reg);
-                       val &= ~periph_clk_source_mask(c);
-                       val |= (sel->value << periph_clk_source_shift(c));
-                       pmc_writel(val, c->reg);
-                       spin_unlock_irqrestore(&clk_out_lock, flags);
+       return 0;
+}
 
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
+static u8 tegra30_clk_out_get_parent(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = pmc_readl(c->reg);
+       int source;
 
-                       clk_reparent(c, p);
-                       return 0;
-               }
-       }
-       return -EINVAL;
+       source = (val & periph_clk_source_mask(c)) >>
+                               periph_clk_source_shift(c);
+       return source;
 }
 
-static struct clk_ops tegra_clk_out_ops = {
-       .init                   = &tegra30_clk_out_init,
-       .enable                 = &tegra30_clk_out_enable,
-       .disable                = &tegra30_clk_out_disable,
-       .set_parent             = &tegra30_clk_out_set_parent,
+struct clk_ops tegra_clk_out_ops = {
+       .is_enabled = tegra30_clk_out_is_enabled,
+       .enable = tegra30_clk_out_enable,
+       .disable = tegra30_clk_out_disable,
+       .set_parent = tegra30_clk_out_set_parent,
+       .get_parent = tegra30_clk_out_get_parent,
+       .recalc_rate = tegra30_clk_fixed_recalc_rate,
 };
 
-
 /* Clock doubler ops */
-static void tegra30_clk_double_init(struct clk *c)
+static int tegra30_clk_double_is_enabled(struct clk_hw *hw)
 {
-       u32 val = clk_readl(c->reg);
-       c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
-       c->div = 1;
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        c->state = ON;
        if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
                c->state = OFF;
+       return c->state;
 };
 
-static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate)
+static int tegra30_clk_double_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
-       unsigned long parent_rate = clk_get_rate(c->parent);
+
        if (rate == parent_rate) {
                val = clk_readl(c->reg) | (0x1 << c->reg_shift);
                clk_writel(val, c->reg);
@@ -1890,1215 +2085,139 @@ static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate)
        return -EINVAL;
 }
 
-static struct clk_ops tegra_clk_double_ops = {
-       .init                   = &tegra30_clk_double_init,
-       .enable                 = &tegra30_periph_clk_enable,
-       .disable                = &tegra30_periph_clk_disable,
-       .set_rate               = &tegra30_clk_double_set_rate,
-};
+static unsigned long tegra30_clk_double_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u64 rate = parent_rate;
 
-/* Audio sync clock ops */
-static int tegra30_sync_source_set_rate(struct clk *c, unsigned long rate)
+       u32 val = clk_readl(c->reg);
+       c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
+       c->div = 1;
+
+       if (c->mul != 0 && c->div != 0) {
+               rate *= c->mul;
+               rate += c->div - 1; /* round up */
+               do_div(rate, c->div);
+       }
+
+       return rate;
+}
+
+static long tegra30_clk_double_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
 {
-       c->rate = rate;
-       return 0;
+       unsigned long output_rate = *prate;
+
+       do_div(output_rate, 2);
+       return output_rate;
 }
 
-static struct clk_ops tegra_sync_source_ops = {
-       .set_rate               = &tegra30_sync_source_set_rate,
+struct clk_ops tegra30_clk_double_ops = {
+       .is_enabled = tegra30_clk_double_is_enabled,
+       .enable = tegra30_periph_clk_enable,
+       .disable = tegra30_periph_clk_disable,
+       .recalc_rate = tegra30_clk_double_recalc_rate,
+       .round_rate = tegra30_clk_double_round_rate,
+       .set_rate = tegra30_clk_double_set_rate,
 };
 
-static void tegra30_audio_sync_clk_init(struct clk *c)
+/* Audio sync clock ops */
+struct clk_ops tegra_sync_source_ops = {
+       .recalc_rate = tegra30_clk_fixed_recalc_rate,
+};
+
+static int tegra30_audio_sync_clk_is_enabled(struct clk_hw *hw)
 {
-       int source;
-       const struct clk_mux_sel *sel;
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val = clk_readl(c->reg);
        c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON;
-       source = val & AUDIO_SYNC_SOURCE_MASK;
-       for (sel = c->inputs; sel->input != NULL; sel++)
-               if (sel->value == source)
-                       break;
-       BUG_ON(sel->input == NULL);
-       c->parent = sel->input;
+       return c->state;
 }
 
-static int tegra30_audio_sync_clk_enable(struct clk *c)
+static int tegra30_audio_sync_clk_enable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val = clk_readl(c->reg);
        clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg);
        return 0;
 }
 
-static void tegra30_audio_sync_clk_disable(struct clk *c)
+static void tegra30_audio_sync_clk_disable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val = clk_readl(c->reg);
        clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg);
 }
 
-static int tegra30_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
+static int tegra30_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val;
-       const struct clk_mux_sel *sel;
-       for (sel = c->inputs; sel->input != NULL; sel++) {
-               if (sel->input == p) {
-                       val = clk_readl(c->reg);
-                       val &= ~AUDIO_SYNC_SOURCE_MASK;
-                       val |= sel->value;
-
-                       if (c->refcnt)
-                               clk_enable(p);
 
-                       clk_writel(val, c->reg);
+       val = clk_readl(c->reg);
+       val &= ~AUDIO_SYNC_SOURCE_MASK;
+       val |= index;
 
-                       if (c->refcnt && c->parent)
-                               clk_disable(c->parent);
+       clk_writel(val, c->reg);
+       return 0;
+}
 
-                       clk_reparent(c, p);
-                       return 0;
-               }
-       }
+static u8 tegra30_audio_sync_clk_get_parent(struct clk_hw *hw)
+{
+       struct clk_tegra *c = to_clk_tegra(hw);
+       u32 val = clk_readl(c->reg);
+       int source;
 
-       return -EINVAL;
+       source = val & AUDIO_SYNC_SOURCE_MASK;
+       return source;
 }
 
-static struct clk_ops tegra_audio_sync_clk_ops = {
-       .init       = tegra30_audio_sync_clk_init,
-       .enable     = tegra30_audio_sync_clk_enable,
-       .disable    = tegra30_audio_sync_clk_disable,
+struct clk_ops tegra30_audio_sync_clk_ops = {
+       .is_enabled = tegra30_audio_sync_clk_is_enabled,
+       .enable = tegra30_audio_sync_clk_enable,
+       .disable = tegra30_audio_sync_clk_disable,
        .set_parent = tegra30_audio_sync_clk_set_parent,
+       .get_parent = tegra30_audio_sync_clk_get_parent,
+       .recalc_rate = tegra30_clk_fixed_recalc_rate,
 };
 
 /* cml0 (pcie), and cml1 (sata) clock ops */
-static void tegra30_cml_clk_init(struct clk *c)
+static int tegra30_cml_clk_is_enabled(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
        u32 val = clk_readl(c->reg);
        c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF;
+       return c->state;
 }
 
-static int tegra30_cml_clk_enable(struct clk *c)
+static int tegra30_cml_clk_enable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        u32 val = clk_readl(c->reg);
        val |= (0x1 << c->u.periph.clk_num);
        clk_writel(val, c->reg);
+
        return 0;
 }
 
-static void tegra30_cml_clk_disable(struct clk *c)
+static void tegra30_cml_clk_disable(struct clk_hw *hw)
 {
+       struct clk_tegra *c = to_clk_tegra(hw);
+
        u32 val = clk_readl(c->reg);
        val &= ~(0x1 << c->u.periph.clk_num);
        clk_writel(val, c->reg);
 }
 
-static struct clk_ops tegra_cml_clk_ops = {
-       .init                   = &tegra30_cml_clk_init,
-       .enable                 = &tegra30_cml_clk_enable,
-       .disable                = &tegra30_cml_clk_disable,
-};
-
-/* Clock definitions */
-static struct clk tegra_clk_32k = {
-       .name = "clk_32k",
-       .rate = 32768,
-       .ops  = NULL,
-       .max_rate = 32768,
-};
-
-static struct clk tegra_clk_m = {
-       .name      = "clk_m",
-       .flags     = ENABLE_ON_INIT,
-       .ops       = &tegra_clk_m_ops,
-       .reg       = 0x1fc,
-       .reg_shift = 28,
-       .max_rate  = 48000000,
-};
-
-static struct clk tegra_clk_m_div2 = {
-       .name      = "clk_m_div2",
-       .ops       = &tegra_clk_m_div_ops,
-       .parent    = &tegra_clk_m,
-       .mul       = 1,
-       .div       = 2,
-       .state     = ON,
-       .max_rate  = 24000000,
-};
-
-static struct clk tegra_clk_m_div4 = {
-       .name      = "clk_m_div4",
-       .ops       = &tegra_clk_m_div_ops,
-       .parent    = &tegra_clk_m,
-       .mul       = 1,
-       .div       = 4,
-       .state     = ON,
-       .max_rate  = 12000000,
-};
-
-static struct clk tegra_pll_ref = {
-       .name      = "pll_ref",
-       .flags     = ENABLE_ON_INIT,
-       .ops       = &tegra_pll_ref_ops,
-       .parent    = &tegra_clk_m,
-       .max_rate  = 26000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
-       { 12000000, 1040000000, 520,  6, 1, 8},
-       { 13000000, 1040000000, 480,  6, 1, 8},
-       { 16800000, 1040000000, 495,  8, 1, 8},         /* actual: 1039.5 MHz */
-       { 19200000, 1040000000, 325,  6, 1, 6},
-       { 26000000, 1040000000, 520, 13, 1, 8},
-
-       { 12000000, 832000000, 416,  6, 1, 8},
-       { 13000000, 832000000, 832, 13, 1, 8},
-       { 16800000, 832000000, 396,  8, 1, 8},          /* actual: 831.6 MHz */
-       { 19200000, 832000000, 260,  6, 1, 8},
-       { 26000000, 832000000, 416, 13, 1, 8},
-
-       { 12000000, 624000000, 624, 12, 1, 8},
-       { 13000000, 624000000, 624, 13, 1, 8},
-       { 16800000, 600000000, 520, 14, 1, 8},
-       { 19200000, 624000000, 520, 16, 1, 8},
-       { 26000000, 624000000, 624, 26, 1, 8},
-
-       { 12000000, 600000000, 600, 12, 1, 8},
-       { 13000000, 600000000, 600, 13, 1, 8},
-       { 16800000, 600000000, 500, 14, 1, 8},
-       { 19200000, 600000000, 375, 12, 1, 6},
-       { 26000000, 600000000, 600, 26, 1, 8},
-
-       { 12000000, 520000000, 520, 12, 1, 8},
-       { 13000000, 520000000, 520, 13, 1, 8},
-       { 16800000, 520000000, 495, 16, 1, 8},          /* actual: 519.75 MHz */
-       { 19200000, 520000000, 325, 12, 1, 6},
-       { 26000000, 520000000, 520, 26, 1, 8},
-
-       { 12000000, 416000000, 416, 12, 1, 8},
-       { 13000000, 416000000, 416, 13, 1, 8},
-       { 16800000, 416000000, 396, 16, 1, 8},          /* actual: 415.8 MHz */
-       { 19200000, 416000000, 260, 12, 1, 6},
-       { 26000000, 416000000, 416, 26, 1, 8},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_c = {
-       .name      = "pll_c",
-       .flags     = PLL_HAS_CPCON,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0x80,
-       .parent    = &tegra_pll_ref,
-       .max_rate  = 1400000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1400000000,
-               .freq_table = tegra_pll_c_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_c_out1 = {
-       .name      = "pll_c_out1",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_U71,
-       .parent    = &tegra_pll_c,
-       .reg       = 0x84,
-       .reg_shift = 0,
-       .max_rate  = 700000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
-       { 12000000, 666000000, 666, 12, 1, 8},
-       { 13000000, 666000000, 666, 13, 1, 8},
-       { 16800000, 666000000, 555, 14, 1, 8},
-       { 19200000, 666000000, 555, 16, 1, 8},
-       { 26000000, 666000000, 666, 26, 1, 8},
-       { 12000000, 600000000, 600, 12, 1, 8},
-       { 13000000, 600000000, 600, 13, 1, 8},
-       { 16800000, 600000000, 500, 14, 1, 8},
-       { 19200000, 600000000, 375, 12, 1, 6},
-       { 26000000, 600000000, 600, 26, 1, 8},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_m = {
-       .name      = "pll_m",
-       .flags     = PLL_HAS_CPCON | PLLM,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0x90,
-       .parent    = &tegra_pll_ref,
-       .max_rate  = 800000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1200000000,
-               .freq_table = tegra_pll_m_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_m_out1 = {
-       .name      = "pll_m_out1",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_U71,
-       .parent    = &tegra_pll_m,
-       .reg       = 0x94,
-       .reg_shift = 0,
-       .max_rate  = 600000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
-       { 12000000, 216000000, 432, 12, 2, 8},
-       { 13000000, 216000000, 432, 13, 2, 8},
-       { 16800000, 216000000, 360, 14, 2, 8},
-       { 19200000, 216000000, 360, 16, 2, 8},
-       { 26000000, 216000000, 432, 26, 2, 8},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_p = {
-       .name      = "pll_p",
-       .flags     = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xa0,
-       .parent    = &tegra_pll_ref,
-       .max_rate  = 432000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1400000000,
-               .freq_table = tegra_pll_p_freq_table,
-               .lock_delay = 300,
-               .fixed_rate = 408000000,
-       },
-};
-
-static struct clk tegra_pll_p_out1 = {
-       .name      = "pll_p_out1",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa4,
-       .reg_shift = 0,
-       .max_rate  = 432000000,
-};
-
-static struct clk tegra_pll_p_out2 = {
-       .name      = "pll_p_out2",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa4,
-       .reg_shift = 16,
-       .max_rate  = 432000000,
-};
-
-static struct clk tegra_pll_p_out3 = {
-       .name      = "pll_p_out3",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa8,
-       .reg_shift = 0,
-       .max_rate  = 432000000,
-};
-
-static struct clk tegra_pll_p_out4 = {
-       .name      = "pll_p_out4",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
-       .parent    = &tegra_pll_p,
-       .reg       = 0xa8,
-       .reg_shift = 16,
-       .max_rate  = 432000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
-       { 9600000, 564480000, 294, 5, 1, 4},
-       { 9600000, 552960000, 288, 5, 1, 4},
-       { 9600000, 24000000,  5,   2, 1, 1},
-
-       { 28800000, 56448000, 49, 25, 1, 1},
-       { 28800000, 73728000, 64, 25, 1, 1},
-       { 28800000, 24000000,  5,  6, 1, 1},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_a = {
-       .name      = "pll_a",
-       .flags     = PLL_HAS_CPCON,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xb0,
-       .parent    = &tegra_pll_p_out1,
-       .max_rate  = 700000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1400000000,
-               .freq_table = tegra_pll_a_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_a_out0 = {
-       .name      = "pll_a_out0",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_U71,
-       .parent    = &tegra_pll_a,
-       .reg       = 0xb4,
-       .reg_shift = 0,
-       .max_rate  = 100000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
-       { 12000000, 216000000, 216, 12, 1, 4},
-       { 13000000, 216000000, 216, 13, 1, 4},
-       { 16800000, 216000000, 180, 14, 1, 4},
-       { 19200000, 216000000, 180, 16, 1, 4},
-       { 26000000, 216000000, 216, 26, 1, 4},
-
-       { 12000000, 594000000, 594, 12, 1, 8},
-       { 13000000, 594000000, 594, 13, 1, 8},
-       { 16800000, 594000000, 495, 14, 1, 8},
-       { 19200000, 594000000, 495, 16, 1, 8},
-       { 26000000, 594000000, 594, 26, 1, 8},
-
-       { 12000000, 1000000000, 1000, 12, 1, 12},
-       { 13000000, 1000000000, 1000, 13, 1, 12},
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 12},
-
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_d = {
-       .name      = "pll_d",
-       .flags     = PLL_HAS_CPCON | PLLD,
-       .ops       = &tegra_plld_ops,
-       .reg       = 0xd0,
-       .parent    = &tegra_pll_ref,
-       .max_rate  = 1000000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 40000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 40000000,
-               .vco_max   = 1000000000,
-               .freq_table = tegra_pll_d_freq_table,
-               .lock_delay = 1000,
-       },
-};
-
-static struct clk tegra_pll_d_out0 = {
-       .name      = "pll_d_out0",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_2 | PLLD,
-       .parent    = &tegra_pll_d,
-       .max_rate  = 500000000,
-};
-
-static struct clk tegra_pll_d2 = {
-       .name      = "pll_d2",
-       .flags     = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD,
-       .ops       = &tegra_plld_ops,
-       .reg       = 0x4b8,
-       .parent    = &tegra_pll_ref,
-       .max_rate  = 1000000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 40000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 40000000,
-               .vco_max   = 1000000000,
-               .freq_table = tegra_pll_d_freq_table,
-               .lock_delay = 1000,
-       },
-};
-
-static struct clk tegra_pll_d2_out0 = {
-       .name      = "pll_d2_out0",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_2 | PLLD,
-       .parent    = &tegra_pll_d2,
-       .max_rate  = 500000000,
-};
-
-static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
-       { 12000000, 480000000, 960, 12, 2, 12},
-       { 13000000, 480000000, 960, 13, 2, 12},
-       { 16800000, 480000000, 400, 7,  2, 5},
-       { 19200000, 480000000, 200, 4,  2, 3},
-       { 26000000, 480000000, 960, 26, 2, 12},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_u = {
-       .name      = "pll_u",
-       .flags     = PLL_HAS_CPCON | PLLU,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xc0,
-       .parent    = &tegra_pll_ref,
-       .max_rate  = 480000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 40000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 480000000,
-               .vco_max   = 960000000,
-               .freq_table = tegra_pll_u_freq_table,
-               .lock_delay = 1000,
-       },
-};
-
-static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
-       /* 1.7 GHz */
-       { 12000000, 1700000000, 850,  6,  1, 8},
-       { 13000000, 1700000000, 915,  7,  1, 8},        /* actual: 1699.2 MHz */
-       { 16800000, 1700000000, 708,  7,  1, 8},        /* actual: 1699.2 MHz */
-       { 19200000, 1700000000, 885,  10, 1, 8},        /* actual: 1699.2 MHz */
-       { 26000000, 1700000000, 850,  13, 1, 8},
-
-       /* 1.6 GHz */
-       { 12000000, 1600000000, 800,  6,  1, 8},
-       { 13000000, 1600000000, 738,  6,  1, 8},        /* actual: 1599.0 MHz */
-       { 16800000, 1600000000, 857,  9,  1, 8},        /* actual: 1599.7 MHz */
-       { 19200000, 1600000000, 500,  6,  1, 8},
-       { 26000000, 1600000000, 800,  13, 1, 8},
-
-       /* 1.5 GHz */
-       { 12000000, 1500000000, 750,  6,  1, 8},
-       { 13000000, 1500000000, 923,  8,  1, 8},        /* actual: 1499.8 MHz */
-       { 16800000, 1500000000, 625,  7,  1, 8},
-       { 19200000, 1500000000, 625,  8,  1, 8},
-       { 26000000, 1500000000, 750,  13, 1, 8},
-
-       /* 1.4 GHz */
-       { 12000000, 1400000000, 700,  6,  1, 8},
-       { 13000000, 1400000000, 969,  9,  1, 8},        /* actual: 1399.7 MHz */
-       { 16800000, 1400000000, 1000, 12, 1, 8},
-       { 19200000, 1400000000, 875,  12, 1, 8},
-       { 26000000, 1400000000, 700,  13, 1, 8},
-
-       /* 1.3 GHz */
-       { 12000000, 1300000000, 975,  9,  1, 8},
-       { 13000000, 1300000000, 1000, 10, 1, 8},
-       { 16800000, 1300000000, 928,  12, 1, 8},        /* actual: 1299.2 MHz */
-       { 19200000, 1300000000, 812,  12, 1, 8},        /* actual: 1299.2 MHz */
-       { 26000000, 1300000000, 650,  13, 1, 8},
-
-       /* 1.2 GHz */
-       { 12000000, 1200000000, 1000, 10, 1, 8},
-       { 13000000, 1200000000, 923,  10, 1, 8},        /* actual: 1199.9 MHz */
-       { 16800000, 1200000000, 1000, 14, 1, 8},
-       { 19200000, 1200000000, 1000, 16, 1, 8},
-       { 26000000, 1200000000, 600,  13, 1, 8},
-
-       /* 1.1 GHz */
-       { 12000000, 1100000000, 825,  9,  1, 8},
-       { 13000000, 1100000000, 846,  10, 1, 8},        /* actual: 1099.8 MHz */
-       { 16800000, 1100000000, 982,  15, 1, 8},        /* actual: 1099.8 MHz */
-       { 19200000, 1100000000, 859,  15, 1, 8},        /* actual: 1099.5 MHz */
-       { 26000000, 1100000000, 550,  13, 1, 8},
-
-       /* 1 GHz */
-       { 12000000, 1000000000, 1000, 12, 1, 8},
-       { 13000000, 1000000000, 1000, 13, 1, 8},
-       { 16800000, 1000000000, 833,  14, 1, 8},        /* actual: 999.6 MHz */
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 8},
-
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_x = {
-       .name      = "pll_x",
-       .flags     = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX,
-       .ops       = &tegra_pll_ops,
-       .reg       = 0xe0,
-       .parent    = &tegra_pll_ref,
-       .max_rate  = 1700000000,
-       .u.pll = {
-               .input_min = 2000000,
-               .input_max = 31000000,
-               .cf_min    = 1000000,
-               .cf_max    = 6000000,
-               .vco_min   = 20000000,
-               .vco_max   = 1700000000,
-               .freq_table = tegra_pll_x_freq_table,
-               .lock_delay = 300,
-       },
-};
-
-static struct clk tegra_pll_x_out0 = {
-       .name      = "pll_x_out0",
-       .ops       = &tegra_pll_div_ops,
-       .flags     = DIV_2 | PLLX,
-       .parent    = &tegra_pll_x,
-       .max_rate  = 850000000,
-};
-
-
-static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
-       /* PLLE special case: use cpcon field to store cml divider value */
-       { 12000000,  100000000, 150, 1,  18, 11},
-       { 216000000, 100000000, 200, 18, 24, 13},
-       { 0, 0, 0, 0, 0, 0 },
-};
-
-static struct clk tegra_pll_e = {
-       .name      = "pll_e",
-       .flags     = PLL_ALT_MISC_REG,
-       .ops       = &tegra_plle_ops,
-       .reg       = 0xe8,
-       .max_rate  = 100000000,
-       .u.pll = {
-               .input_min = 12000000,
-               .input_max = 216000000,
-               .cf_min    = 12000000,
-               .cf_max    = 12000000,
-               .vco_min   = 1200000000,
-               .vco_max   = 2400000000U,
-               .freq_table = tegra_pll_e_freq_table,
-               .lock_delay = 300,
-               .fixed_rate = 100000000,
-       },
-};
-
-static struct clk tegra_cml0_clk = {
-       .name      = "cml0",
-       .parent    = &tegra_pll_e,
-       .ops       = &tegra_cml_clk_ops,
-       .reg       = PLLE_AUX,
-       .max_rate  = 100000000,
-       .u.periph  = {
-               .clk_num = 0,
-       },
-};
-
-static struct clk tegra_cml1_clk = {
-       .name      = "cml1",
-       .parent    = &tegra_pll_e,
-       .ops       = &tegra_cml_clk_ops,
-       .reg       = PLLE_AUX,
-       .max_rate  = 100000000,
-       .u.periph  = {
-               .clk_num   = 1,
-       },
-};
-
-static struct clk tegra_pciex_clk = {
-       .name      = "pciex",
-       .parent    = &tegra_pll_e,
-       .ops       = &tegra_pciex_clk_ops,
-       .max_rate  = 100000000,
-       .u.periph  = {
-               .clk_num   = 74,
-       },
-};
-
-/* Audio sync clocks */
-#define SYNC_SOURCE(_id)                               \
-       {                                               \
-               .name      = #_id "_sync",              \
-               .rate      = 24000000,                  \
-               .max_rate  = 24000000,                  \
-               .ops       = &tegra_sync_source_ops     \
-       }
-static struct clk tegra_sync_source_list[] = {
-       SYNC_SOURCE(spdif_in),
-       SYNC_SOURCE(i2s0),
-       SYNC_SOURCE(i2s1),
-       SYNC_SOURCE(i2s2),
-       SYNC_SOURCE(i2s3),
-       SYNC_SOURCE(i2s4),
-       SYNC_SOURCE(vimclk),
-};
-
-static struct clk_mux_sel mux_audio_sync_clk[] = {
-       { .input = &tegra_sync_source_list[0],  .value = 0},
-       { .input = &tegra_sync_source_list[1],  .value = 1},
-       { .input = &tegra_sync_source_list[2],  .value = 2},
-       { .input = &tegra_sync_source_list[3],  .value = 3},
-       { .input = &tegra_sync_source_list[4],  .value = 4},
-       { .input = &tegra_sync_source_list[5],  .value = 5},
-       { .input = &tegra_pll_a_out0,           .value = 6},
-       { .input = &tegra_sync_source_list[6],  .value = 7},
-       { 0, 0 }
-};
-
-#define AUDIO_SYNC_CLK(_id, _index)                    \
-       {                                               \
-               .name      = #_id,                      \
-               .inputs    = mux_audio_sync_clk,        \
-               .reg       = 0x4A0 + (_index) * 4,      \
-               .max_rate  = 24000000,                  \
-               .ops       = &tegra_audio_sync_clk_ops  \
-       }
-static struct clk tegra_clk_audio_list[] = {
-       AUDIO_SYNC_CLK(audio0, 0),
-       AUDIO_SYNC_CLK(audio1, 1),
-       AUDIO_SYNC_CLK(audio2, 2),
-       AUDIO_SYNC_CLK(audio3, 3),
-       AUDIO_SYNC_CLK(audio4, 4),
-       AUDIO_SYNC_CLK(audio, 5),       /* SPDIF */
-};
-
-#define AUDIO_SYNC_2X_CLK(_id, _index)                         \
-       {                                                       \
-               .name      = #_id "_2x",                        \
-               .flags     = PERIPH_NO_RESET,                   \
-               .max_rate  = 48000000,                          \
-               .ops       = &tegra_clk_double_ops,             \
-               .reg       = 0x49C,                             \
-               .reg_shift = 24 + (_index),                     \
-               .parent    = &tegra_clk_audio_list[(_index)],   \
-               .u.periph = {                                   \
-                       .clk_num = 113 + (_index),              \
-               },                                              \
-       }
-static struct clk tegra_clk_audio_2x_list[] = {
-       AUDIO_SYNC_2X_CLK(audio0, 0),
-       AUDIO_SYNC_2X_CLK(audio1, 1),
-       AUDIO_SYNC_2X_CLK(audio2, 2),
-       AUDIO_SYNC_2X_CLK(audio3, 3),
-       AUDIO_SYNC_2X_CLK(audio4, 4),
-       AUDIO_SYNC_2X_CLK(audio, 5),    /* SPDIF */
-};
-
-#define MUX_I2S_SPDIF(_id, _index)                                     \
-static struct clk_mux_sel mux_pllaout0_##_id##_2x_pllp_clkm[] = {      \
-       {.input = &tegra_pll_a_out0, .value = 0},                       \
-       {.input = &tegra_clk_audio_2x_list[(_index)], .value = 1},      \
-       {.input = &tegra_pll_p, .value = 2},                            \
-       {.input = &tegra_clk_m, .value = 3},                            \
-       { 0, 0},                                                        \
-}
-MUX_I2S_SPDIF(audio0, 0);
-MUX_I2S_SPDIF(audio1, 1);
-MUX_I2S_SPDIF(audio2, 2);
-MUX_I2S_SPDIF(audio3, 3);
-MUX_I2S_SPDIF(audio4, 4);
-MUX_I2S_SPDIF(audio, 5);               /* SPDIF */
-
-/* External clock outputs (through PMC) */
-#define MUX_EXTERN_OUT(_id)                                            \
-static struct clk_mux_sel mux_clkm_clkm2_clkm4_extern##_id[] = {       \
-       {.input = &tegra_clk_m,         .value = 0},                    \
-       {.input = &tegra_clk_m_div2,    .value = 1},                    \
-       {.input = &tegra_clk_m_div4,    .value = 2},                    \
-       {.input = NULL,                 .value = 3}, /* placeholder */  \
-       { 0, 0},                                                        \
-}
-MUX_EXTERN_OUT(1);
-MUX_EXTERN_OUT(2);
-MUX_EXTERN_OUT(3);
-
-static struct clk_mux_sel *mux_extern_out_list[] = {
-       mux_clkm_clkm2_clkm4_extern1,
-       mux_clkm_clkm2_clkm4_extern2,
-       mux_clkm_clkm2_clkm4_extern3,
-};
-
-#define CLK_OUT_CLK(_id)                                       \
-       {                                                       \
-               .name      = "clk_out_" #_id,                   \
-               .lookup    = {                                  \
-                       .dev_id    = "clk_out_" #_id,           \
-                       .con_id    = "extern" #_id,             \
-               },                                              \
-               .ops       = &tegra_clk_out_ops,                \
-               .reg       = 0x1a8,                             \
-               .inputs    = mux_clkm_clkm2_clkm4_extern##_id,  \
-               .flags     = MUX_CLK_OUT,                       \
-               .max_rate  = 216000000,                         \
-               .u.periph = {                                   \
-                       .clk_num   = (_id - 1) * 8 + 2,         \
-               },                                              \
-       }
-static struct clk tegra_clk_out_list[] = {
-       CLK_OUT_CLK(1),
-       CLK_OUT_CLK(2),
-       CLK_OUT_CLK(3),
-};
-
-/* called after peripheral external clocks are initialized */
-static void init_clk_out_mux(void)
-{
-       int i;
-       struct clk *c;
-
-       /* output clock con_id is the name of peripheral
-          external clock connected to input 3 of the output mux */
-       for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) {
-               c = tegra_get_clock_by_name(
-                       tegra_clk_out_list[i].lookup.con_id);
-               if (!c)
-                       pr_err("%s: could not find clk %s\n", __func__,
-                              tegra_clk_out_list[i].lookup.con_id);
-               mux_extern_out_list[i][3].input = c;
-       }
-}
-
-/* Peripheral muxes */
-static struct clk_mux_sel mux_sclk[] = {
-       { .input = &tegra_clk_m,        .value = 0},
-       { .input = &tegra_pll_c_out1,   .value = 1},
-       { .input = &tegra_pll_p_out4,   .value = 2},
-       { .input = &tegra_pll_p_out3,   .value = 3},
-       { .input = &tegra_pll_p_out2,   .value = 4},
-       /* { .input = &tegra_clk_d,     .value = 5}, - no use on tegra30 */
-       { .input = &tegra_clk_32k,      .value = 6},
-       { .input = &tegra_pll_m_out1,   .value = 7},
-       { 0, 0},
-};
-
-static struct clk tegra_clk_sclk = {
-       .name   = "sclk",
-       .inputs = mux_sclk,
-       .reg    = 0x28,
-       .ops    = &tegra_super_ops,
-       .max_rate = 334000000,
-       .min_rate = 40000000,
-};
-
-static struct clk tegra_clk_blink = {
-       .name           = "blink",
-       .parent         = &tegra_clk_32k,
-       .reg            = 0x40,
-       .ops            = &tegra_blink_clk_ops,
-       .max_rate       = 32768,
-};
-
-static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
-       { .input = &tegra_pll_m, .value = 0},
-       { .input = &tegra_pll_c, .value = 1},
-       { .input = &tegra_pll_p, .value = 2},
-       { .input = &tegra_pll_a_out0, .value = 3},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
-       { .input = &tegra_pll_p, .value = 0},
-       { .input = &tegra_pll_c, .value = 1},
-       { .input = &tegra_pll_m, .value = 2},
-       { .input = &tegra_clk_m, .value = 3},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_clkm[] = {
-       { .input = &tegra_pll_p, .value = 0},
-       { .input = &tegra_clk_m, .value = 3},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
-       {.input = &tegra_pll_p, .value = 0},
-       {.input = &tegra_pll_d_out0, .value = 1},
-       {.input = &tegra_pll_c, .value = 2},
-       {.input = &tegra_clk_m, .value = 3},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
-       {.input = &tegra_pll_p, .value = 0},
-       {.input = &tegra_pll_m, .value = 1},
-       {.input = &tegra_pll_d_out0, .value = 2},
-       {.input = &tegra_pll_a_out0, .value = 3},
-       {.input = &tegra_pll_c, .value = 4},
-       {.input = &tegra_pll_d2_out0, .value = 5},
-       {.input = &tegra_clk_m, .value = 6},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_plla_pllc_pllp_clkm[] = {
-       { .input = &tegra_pll_a_out0, .value = 0},
-       /* { .input = &tegra_pll_c, .value = 1}, no use on tegra30 */
-       { .input = &tegra_pll_p, .value = 2},
-       { .input = &tegra_clk_m, .value = 3},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllc_clk32_clkm[] = {
-       {.input = &tegra_pll_p,     .value = 0},
-       {.input = &tegra_pll_c,     .value = 1},
-       {.input = &tegra_clk_32k,   .value = 2},
-       {.input = &tegra_clk_m,     .value = 3},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllc_clkm_clk32[] = {
-       {.input = &tegra_pll_p,     .value = 0},
-       {.input = &tegra_pll_c,     .value = 1},
-       {.input = &tegra_clk_m,     .value = 2},
-       {.input = &tegra_clk_32k,   .value = 3},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
-       {.input = &tegra_pll_p,     .value = 0},
-       {.input = &tegra_pll_c,     .value = 1},
-       {.input = &tegra_pll_m,     .value = 2},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_clk_m[] = {
-       { .input = &tegra_clk_m, .value = 0},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_pllp_out3[] = {
-       { .input = &tegra_pll_p_out3, .value = 0},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_plld_out0[] = {
-       { .input = &tegra_pll_d_out0, .value = 0},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_plld_out0_plld2_out0[] = {
-       { .input = &tegra_pll_d_out0,  .value = 0},
-       { .input = &tegra_pll_d2_out0, .value = 1},
-       { 0, 0},
-};
-
-static struct clk_mux_sel mux_clk_32k[] = {
-       { .input = &tegra_clk_32k, .value = 0},
-       { 0, 0},
+struct clk_ops tegra_cml_clk_ops = {
+       .is_enabled = tegra30_cml_clk_is_enabled,
+       .enable = tegra30_cml_clk_enable,
+       .disable = tegra30_cml_clk_disable,
+       .recalc_rate = tegra30_clk_fixed_recalc_rate,
 };
 
-static struct clk_mux_sel mux_plla_clk32_pllp_clkm_plle[] = {
-       { .input = &tegra_pll_a_out0, .value = 0},
-       { .input = &tegra_clk_32k,    .value = 1},
-       { .input = &tegra_pll_p,      .value = 2},
-       { .input = &tegra_clk_m,      .value = 3},
-       { .input = &tegra_pll_e,      .value = 4},
-       { 0, 0},
+struct clk_ops tegra_pciex_clk_ops = {
+       .recalc_rate = tegra30_clk_fixed_recalc_rate,
 };
-
-static struct clk_mux_sel mux_cclk_g[] = {
-       { .input = &tegra_clk_m,        .value = 0},
-       { .input = &tegra_pll_c,        .value = 1},
-       { .input = &tegra_clk_32k,      .value = 2},
-       { .input = &tegra_pll_m,        .value = 3},
-       { .input = &tegra_pll_p,        .value = 4},
-       { .input = &tegra_pll_p_out4,   .value = 5},
-       { .input = &tegra_pll_p_out3,   .value = 6},
-       { .input = &tegra_pll_x,        .value = 8},
-       { 0, 0},
-};
-
-static struct clk tegra_clk_cclk_g = {
-       .name   = "cclk_g",
-       .flags  = DIV_U71 | DIV_U71_INT,
-       .inputs = mux_cclk_g,
-       .reg    = 0x368,
-       .ops    = &tegra_super_ops,
-       .max_rate = 1700000000,
-};
-
-static struct clk tegra30_clk_twd = {
-       .parent   = &tegra_clk_cclk_g,
-       .name     = "twd",
-       .ops      = &tegra30_twd_ops,
-       .max_rate = 1400000000, /* Same as tegra_clk_cpu_cmplx.max_rate */
-       .mul      = 1,
-       .div      = 2,
-};
-
-#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
-       {                                               \
-               .name      = _name,                     \
-               .lookup    = {                          \
-                       .dev_id    = _dev,              \
-                       .con_id    = _con,              \
-               },                                      \
-               .ops       = &tegra_periph_clk_ops,     \
-               .reg       = _reg,                      \
-               .inputs    = _inputs,                   \
-               .flags     = _flags,                    \
-               .max_rate  = _max,                      \
-               .u.periph = {                           \
-                       .clk_num   = _clk_num,          \
-               },                                      \
-       }
-
-#define PERIPH_CLK_EX(_name, _dev, _con, _clk_num, _reg, _max, _inputs,        \
-                       _flags, _ops)                                   \
-       {                                               \
-               .name      = _name,                     \
-               .lookup    = {                          \
-                       .dev_id    = _dev,              \
-                       .con_id    = _con,              \
-               },                                      \
-               .ops       = _ops,                      \
-               .reg       = _reg,                      \
-               .inputs    = _inputs,                   \
-               .flags     = _flags,                    \
-               .max_rate  = _max,                      \
-               .u.periph = {                           \
-                       .clk_num   = _clk_num,          \
-               },                                      \
-       }
-
-#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div, _mode)\
-       {                                               \
-               .name      = _name,                     \
-               .lookup    = {                          \
-                       .dev_id    = _dev,              \
-                       .con_id    = _con,              \
-               },                                      \
-               .ops       = &tegra_clk_shared_bus_ops, \
-               .parent = _parent,                      \
-               .u.shared_bus_user = {                  \
-                       .client_id = _id,               \
-                       .client_div = _div,             \
-                       .mode = _mode,                  \
-               },                                      \
-       }
-struct clk tegra_list_clks[] = {
-       PERIPH_CLK("apbdma",    "tegra-apbdma",         NULL,   34,     0,      26000000,  mux_clk_m,                   0),
-       PERIPH_CLK("rtc",       "rtc-tegra",            NULL,   4,      0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET | PERIPH_ON_APB),
-       PERIPH_CLK("kbc",       "tegra-kbc",            NULL,   36,     0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET | PERIPH_ON_APB),
-       PERIPH_CLK("timer",     "timer",                NULL,   5,      0,      26000000,  mux_clk_m,                   0),
-       PERIPH_CLK("kfuse",     "kfuse-tegra",          NULL,   40,     0,      26000000,  mux_clk_m,                   0),
-       PERIPH_CLK("fuse",      "fuse-tegra",           "fuse", 39,     0,      26000000,  mux_clk_m,                   PERIPH_ON_APB),
-       PERIPH_CLK("fuse_burn", "fuse-tegra",           "fuse_burn",    39,     0,      26000000,  mux_clk_m,           PERIPH_ON_APB),
-       PERIPH_CLK("apbif",     "tegra30-ahub",         "apbif", 107,   0,      26000000,  mux_clk_m,                   0),
-       PERIPH_CLK("i2s0",      "tegra30-i2s.0",        NULL,   30,     0x1d8,  26000000,  mux_pllaout0_audio0_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("i2s1",      "tegra30-i2s.1",        NULL,   11,     0x100,  26000000,  mux_pllaout0_audio1_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("i2s2",      "tegra30-i2s.2",        NULL,   18,     0x104,  26000000,  mux_pllaout0_audio2_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("i2s3",      "tegra30-i2s.3",        NULL,   101,    0x3bc,  26000000,  mux_pllaout0_audio3_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("i2s4",      "tegra30-i2s.4",        NULL,   102,    0x3c0,  26000000,  mux_pllaout0_audio4_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("spdif_out", "tegra30-spdif",        "spdif_out",    10,     0x108,  100000000, mux_pllaout0_audio_2x_pllp_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("spdif_in",  "tegra30-spdif",        "spdif_in",     10,     0x10c,  100000000, mux_pllp_pllc_pllm,          MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("pwm",       "tegra-pwm",            NULL,   17,     0x110,  432000000, mux_pllp_pllc_clk32_clkm,    MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("d_audio",   "tegra30-ahub",         "d_audio", 106, 0x3d0,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("dam0",      "tegra30-dam.0",        NULL,   108,    0x3d8,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("dam1",      "tegra30-dam.1",        NULL,   109,    0x3dc,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("dam2",      "tegra30-dam.2",        NULL,   110,    0x3e0,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("hda",       "tegra30-hda",          "hda",   125,   0x428,  108000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("hda2codec_2x",      "tegra30-hda",  "hda2codec",   111,     0x3e4,  48000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("hda2hdmi",  "tegra30-hda",          "hda2hdmi",     128,    0,      48000000,  mux_clk_m,                   0),
-       PERIPH_CLK("sbc1",      "spi_tegra.0",          NULL,   41,     0x134,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("sbc2",      "spi_tegra.1",          NULL,   44,     0x118,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("sbc3",      "spi_tegra.2",          NULL,   46,     0x11c,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("sbc4",      "spi_tegra.3",          NULL,   68,     0x1b4,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("sbc5",      "spi_tegra.4",          NULL,   104,    0x3c8,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("sbc6",      "spi_tegra.5",          NULL,   105,    0x3cc,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("sata_oob",  "tegra_sata_oob",       NULL,   123,    0x420,  216000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("sata",      "tegra_sata",           NULL,   124,    0x424,  216000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("sata_cold", "tegra_sata_cold",      NULL,   129,    0,      48000000,  mux_clk_m,                   0),
-       PERIPH_CLK_EX("ndflash", "tegra_nand",          NULL,   13,     0x160,  240000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71,  &tegra_nand_clk_ops),
-       PERIPH_CLK("ndspeed",   "tegra_nand_speed",     NULL,   80,     0x3f8,  240000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("vfir",      "vfir",                 NULL,   7,      0x168,  72000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("sdmmc1",    "sdhci-tegra.0",        NULL,   14,     0x150,  208000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("sdmmc2",    "sdhci-tegra.1",        NULL,   9,      0x154,  104000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("sdmmc3",    "sdhci-tegra.2",        NULL,   69,     0x1bc,  208000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("sdmmc4",    "sdhci-tegra.3",        NULL,   15,     0x164,  104000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
-       PERIPH_CLK("vcp",       "tegra-avp",            "vcp",  29,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("bsea",      "tegra-avp",            "bsea", 62,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("bsev",      "tegra-aes",            "bsev", 63,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("vde",       "vde",                  NULL,   61,     0x1c8,  520000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_INT),
-       PERIPH_CLK("csite",     "csite",                NULL,   73,     0x1d4,  144000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* max rate ??? */
-       PERIPH_CLK("la",        "la",                   NULL,   76,     0x1f8,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
-       PERIPH_CLK("owr",       "tegra_w1",             NULL,   71,     0x1cc,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("nor",       "nor",                  NULL,   42,     0x1d0,  127000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("mipi",      "mipi",                 NULL,   50,     0x174,  60000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB), /* scales with voltage */
-       PERIPH_CLK("i2c1",      "tegra-i2c.0",          NULL,   12,     0x124,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
-       PERIPH_CLK("i2c2",      "tegra-i2c.1",          NULL,   54,     0x198,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
-       PERIPH_CLK("i2c3",      "tegra-i2c.2",          NULL,   67,     0x1b8,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
-       PERIPH_CLK("i2c4",      "tegra-i2c.3",          NULL,   103,    0x3c4,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
-       PERIPH_CLK("i2c5",      "tegra-i2c.4",          NULL,   47,     0x128,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
-       PERIPH_CLK("uarta",     "tegra-uart.0",         NULL,   6,      0x178,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
-       PERIPH_CLK("uartb",     "tegra-uart.1",         NULL,   7,      0x17c,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
-       PERIPH_CLK("uartc",     "tegra-uart.2",         NULL,   55,     0x1a0,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
-       PERIPH_CLK("uartd",     "tegra-uart.3",         NULL,   65,     0x1c0,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
-       PERIPH_CLK("uarte",     "tegra-uart.4",         NULL,   66,     0x1c4,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
-       PERIPH_CLK_EX("vi",     "tegra_camera",         "vi",   20,     0x148,  425000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT,    &tegra_vi_clk_ops),
-       PERIPH_CLK("3d",        "3d",                   NULL,   24,     0x158,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
-       PERIPH_CLK("3d2",       "3d2",                  NULL,   98,     0x3b0,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
-       PERIPH_CLK("2d",        "2d",                   NULL,   21,     0x15c,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE),
-       PERIPH_CLK("vi_sensor", "tegra_camera",         "vi_sensor",    20,     0x1a8,  150000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_NO_RESET),
-       PERIPH_CLK("epp",       "epp",                  NULL,   19,     0x16c,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT),
-       PERIPH_CLK("mpe",       "mpe",                  NULL,   60,     0x170,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT),
-       PERIPH_CLK("host1x",    "host1x",               NULL,   28,     0x180,  260000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT),
-       PERIPH_CLK("cve",       "cve",                  NULL,   49,     0x140,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("tvo",       "tvo",                  NULL,   49,     0x188,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK_EX("dtv",    "dtv",                  NULL,   79,     0x1dc,  250000000, mux_clk_m,                   0,              &tegra_dtv_clk_ops),
-       PERIPH_CLK("hdmi",      "hdmi",                 NULL,   51,     0x18c,  148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8 | DIV_U71),
-       PERIPH_CLK("tvdac",     "tvdac",                NULL,   53,     0x194,  220000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
-       PERIPH_CLK("disp1",     "tegradc.0",            NULL,   27,     0x138,  600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8),
-       PERIPH_CLK("disp2",     "tegradc.1",            NULL,   26,     0x13c,  600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8),
-       PERIPH_CLK("usbd",      "fsl-tegra-udc",        NULL,   22,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
-       PERIPH_CLK("usb2",      "tegra-ehci.1",         NULL,   58,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
-       PERIPH_CLK("usb3",      "tegra-ehci.2",         NULL,   59,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
-       PERIPH_CLK("dsia",      "tegradc.0",            "dsia", 48,     0,      500000000, mux_plld_out0,               0),
-       PERIPH_CLK_EX("dsib",   "tegradc.1",            "dsib", 82,     0xd0,   500000000, mux_plld_out0_plld2_out0,    MUX | PLLD,     &tegra_dsib_clk_ops),
-       PERIPH_CLK("csi",       "tegra_camera",         "csi",  52,     0,      102000000, mux_pllp_out3,               0),
-       PERIPH_CLK("isp",       "tegra_camera",         "isp",  23,     0,      150000000, mux_clk_m,                   0), /* same frequency as VI */
-       PERIPH_CLK("csus",      "tegra_camera",         "csus", 92,     0,      150000000, mux_clk_m,                   PERIPH_NO_RESET),
-
-       PERIPH_CLK("tsensor",   "tegra-tsensor",        NULL,   100,    0x3b8,  216000000, mux_pllp_pllc_clkm_clk32,    MUX | DIV_U71),
-       PERIPH_CLK("actmon",    "actmon",               NULL,   119,    0x3e8,  216000000, mux_pllp_pllc_clk32_clkm,    MUX | DIV_U71),
-       PERIPH_CLK("extern1",   "extern1",              NULL,   120,    0x3ec,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71),
-       PERIPH_CLK("extern2",   "extern2",              NULL,   121,    0x3f0,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71),
-       PERIPH_CLK("extern3",   "extern3",              NULL,   122,    0x3f4,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71),
-       PERIPH_CLK("i2cslow",   "i2cslow",              NULL,   81,     0x3fc,  26000000,  mux_pllp_pllc_clk32_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
-       PERIPH_CLK("pcie",      "tegra-pcie",           "pcie", 70,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("afi",       "tegra-pcie",           "afi",  72,     0,      250000000, mux_clk_m,                   0),
-       PERIPH_CLK("se",        "se",                   NULL,   127,    0x42c,  520000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_INT),
-};
-
-#define CLK_DUPLICATE(_name, _dev, _con)               \
-       {                                               \
-               .name   = _name,                        \
-               .lookup = {                             \
-                       .dev_id = _dev,                 \
-                       .con_id         = _con,         \
-               },                                      \
-       }
-
-/* Some clocks may be used by different drivers depending on the board
- * configuration.  List those here to register them twice in the clock lookup
- * table under two names.
- */
-struct clk_duplicate tegra_clk_duplicates[] = {
-       CLK_DUPLICATE("uarta",  "serial8250.0", NULL),
-       CLK_DUPLICATE("uartb",  "serial8250.1", NULL),
-       CLK_DUPLICATE("uartc",  "serial8250.2", NULL),
-       CLK_DUPLICATE("uartd",  "serial8250.3", NULL),
-       CLK_DUPLICATE("uarte",  "serial8250.4", NULL),
-       CLK_DUPLICATE("usbd", "utmip-pad", NULL),
-       CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
-       CLK_DUPLICATE("usbd", "tegra-otg", NULL),
-       CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
-       CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
-       CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
-       CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
-       CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
-       CLK_DUPLICATE("bsev", "nvavp", "bsev"),
-       CLK_DUPLICATE("vde", "tegra-aes", "vde"),
-       CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
-       CLK_DUPLICATE("bsea", "nvavp", "bsea"),
-       CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
-       CLK_DUPLICATE("cml0", "tegra_pcie", "cml"),
-       CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"),
-       CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL),
-       CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL),
-       CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL),
-       CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL),
-       CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL),
-       CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL),
-       CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL),
-       CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL),
-       CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL),
-       CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL),
-       CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
-       CLK_DUPLICATE("twd", "smp_twd", NULL),
-       CLK_DUPLICATE("vcp", "nvavp", "vcp"),
-       CLK_DUPLICATE("i2s0", NULL, "i2s0"),
-       CLK_DUPLICATE("i2s1", NULL, "i2s1"),
-       CLK_DUPLICATE("i2s2", NULL, "i2s2"),
-       CLK_DUPLICATE("i2s3", NULL, "i2s3"),
-       CLK_DUPLICATE("i2s4", NULL, "i2s4"),
-       CLK_DUPLICATE("dam0", NULL, "dam0"),
-       CLK_DUPLICATE("dam1", NULL, "dam1"),
-       CLK_DUPLICATE("dam2", NULL, "dam2"),
-       CLK_DUPLICATE("spdif_in", NULL, "spdif_in"),
-};
-
-struct clk *tegra_ptr_clks[] = {
-       &tegra_clk_32k,
-       &tegra_clk_m,
-       &tegra_clk_m_div2,
-       &tegra_clk_m_div4,
-       &tegra_pll_ref,
-       &tegra_pll_m,
-       &tegra_pll_m_out1,
-       &tegra_pll_c,
-       &tegra_pll_c_out1,
-       &tegra_pll_p,
-       &tegra_pll_p_out1,
-       &tegra_pll_p_out2,
-       &tegra_pll_p_out3,
-       &tegra_pll_p_out4,
-       &tegra_pll_a,
-       &tegra_pll_a_out0,
-       &tegra_pll_d,
-       &tegra_pll_d_out0,
-       &tegra_pll_d2,
-       &tegra_pll_d2_out0,
-       &tegra_pll_u,
-       &tegra_pll_x,
-       &tegra_pll_x_out0,
-       &tegra_pll_e,
-       &tegra_clk_cclk_g,
-       &tegra_cml0_clk,
-       &tegra_cml1_clk,
-       &tegra_pciex_clk,
-       &tegra_clk_sclk,
-       &tegra_clk_blink,
-       &tegra30_clk_twd,
-};
-
-
-static void tegra30_init_one_clock(struct clk *c)
-{
-       clk_init(c);
-       INIT_LIST_HEAD(&c->shared_bus_list);
-       if (!c->lookup.dev_id && !c->lookup.con_id)
-               c->lookup.con_id = c->name;
-       c->lookup.clk = c;
-       clkdev_add(&c->lookup);
-}
-
-void __init tegra30_init_clocks(void)
-{
-       int i;
-       struct clk *c;
-
-       for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
-               tegra30_init_one_clock(tegra_ptr_clks[i]);
-
-       for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
-               tegra30_init_one_clock(&tegra_list_clks[i]);
-
-       for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
-               c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
-               if (!c) {
-                       pr_err("%s: Unknown duplicate clock %s\n", __func__,
-                               tegra_clk_duplicates[i].name);
-                       continue;
-               }
-
-               tegra_clk_duplicates[i].lookup.clk = c;
-               clkdev_add(&tegra_clk_duplicates[i].lookup);
-       }
-
-       for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++)
-               tegra30_init_one_clock(&tegra_sync_source_list[i]);
-       for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++)
-               tegra30_init_one_clock(&tegra_clk_audio_list[i]);
-       for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++)
-               tegra30_init_one_clock(&tegra_clk_audio_2x_list[i]);
-
-       init_clk_out_mux();
-       for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++)
-               tegra30_init_one_clock(&tegra_clk_out_list[i]);
-
-}
diff --git a/arch/arm/mach-tegra/tegra30_clocks.h b/arch/arm/mach-tegra/tegra30_clocks.h
new file mode 100644 (file)
index 0000000..f2f88fe
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA30_CLOCK_H
+#define __MACH_TEGRA30_CLOCK_H
+
+extern struct clk_ops tegra30_clk_32k_ops;
+extern struct clk_ops tegra30_clk_m_ops;
+extern struct clk_ops tegra_clk_m_div_ops;
+extern struct clk_ops tegra_pll_ref_ops;
+extern struct clk_ops tegra30_pll_ops;
+extern struct clk_ops tegra30_pll_div_ops;
+extern struct clk_ops tegra_plld_ops;
+extern struct clk_ops tegra30_plle_ops;
+extern struct clk_ops tegra_cml_clk_ops;
+extern struct clk_ops tegra_pciex_clk_ops;
+extern struct clk_ops tegra_sync_source_ops;
+extern struct clk_ops tegra30_audio_sync_clk_ops;
+extern struct clk_ops tegra30_clk_double_ops;
+extern struct clk_ops tegra_clk_out_ops;
+extern struct clk_ops tegra30_super_ops;
+extern struct clk_ops tegra30_blink_clk_ops;
+extern struct clk_ops tegra30_twd_ops;
+extern struct clk_ops tegra30_periph_clk_ops;
+extern struct clk_ops tegra30_dsib_clk_ops;
+extern struct clk_ops tegra_nand_clk_ops;
+extern struct clk_ops tegra_vi_clk_ops;
+extern struct clk_ops tegra_dtv_clk_ops;
+extern struct clk_ops tegra_clk_shared_bus_ops;
+
+int tegra30_plld_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting);
+void tegra30_periph_clk_reset(struct clk_hw *hw, bool assert);
+int tegra30_vi_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting);
+int tegra30_nand_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting);
+int tegra30_dtv_clk_cfg_ex(struct clk_hw *hw,
+                               enum tegra_clk_ex_param p, u32 setting);
+#endif
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c b/arch/arm/mach-tegra/tegra30_clocks_data.c
new file mode 100644 (file)
index 0000000..8d2dbdd
--- /dev/null
@@ -0,0 +1,1374 @@
+/*
+ * arch/arm/mach-tegra/tegra30_clocks.c
+ *
+ * Copyright (c) 2010-2012 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <linux/clk-private.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+
+#include "clock.h"
+#include "fuse.h"
+#include "tegra30_clocks.h"
+
+#define DEFINE_CLK_TEGRA(_name, _rate, _ops, _flags,           \
+                  _parent_names, _parents, _parent)            \
+       static struct clk tegra_##_name = {                     \
+               .hw = &tegra_##_name##_hw.hw,                   \
+               .name = #_name,                                 \
+               .rate = _rate,                                  \
+               .ops = _ops,                                    \
+               .flags = _flags,                                \
+               .parent_names = _parent_names,                  \
+               .parents = _parents,                            \
+               .num_parents = ARRAY_SIZE(_parent_names),       \
+               .parent = _parent,                              \
+       };
+
+static struct clk tegra_clk_32k;
+static struct clk_tegra tegra_clk_32k_hw = {
+       .hw = {
+               .clk = &tegra_clk_32k,
+       },
+       .fixed_rate = 32768,
+};
+static struct clk tegra_clk_32k = {
+       .name = "clk_32k",
+       .hw = &tegra_clk_32k_hw.hw,
+       .ops = &tegra30_clk_32k_ops,
+       .flags = CLK_IS_ROOT,
+};
+
+static struct clk tegra_clk_m;
+static struct clk_tegra tegra_clk_m_hw = {
+       .hw = {
+               .clk = &tegra_clk_m,
+       },
+       .flags = ENABLE_ON_INIT,
+       .reg = 0x1fc,
+       .reg_shift = 28,
+       .max_rate = 48000000,
+};
+static struct clk tegra_clk_m = {
+       .name = "clk_m",
+       .hw = &tegra_clk_m_hw.hw,
+       .ops = &tegra30_clk_m_ops,
+       .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
+};
+
+static const char *clk_m_div_parent_names[] = {
+       "clk_m",
+};
+
+static struct clk *clk_m_div_parents[] = {
+       &tegra_clk_m,
+};
+
+static struct clk tegra_clk_m_div2;
+static struct clk_tegra tegra_clk_m_div2_hw = {
+       .hw = {
+               .clk = &tegra_clk_m_div2,
+       },
+       .mul = 1,
+       .div = 2,
+       .max_rate = 24000000,
+};
+DEFINE_CLK_TEGRA(clk_m_div2, 0, &tegra_clk_m_div_ops, 0,
+               clk_m_div_parent_names, clk_m_div_parents, &tegra_clk_m);
+
+static struct clk tegra_clk_m_div4;
+static struct clk_tegra tegra_clk_m_div4_hw = {
+       .hw = {
+               .clk = &tegra_clk_m_div4,
+       },
+       .mul = 1,
+       .div = 4,
+       .max_rate = 12000000,
+};
+DEFINE_CLK_TEGRA(clk_m_div4, 0, &tegra_clk_m_div_ops, 0,
+               clk_m_div_parent_names, clk_m_div_parents, &tegra_clk_m);
+
+static struct clk tegra_pll_ref;
+static struct clk_tegra tegra_pll_ref_hw = {
+       .hw = {
+               .clk = &tegra_pll_ref,
+       },
+       .flags = ENABLE_ON_INIT,
+       .max_rate = 26000000,
+};
+DEFINE_CLK_TEGRA(pll_ref, 0, &tegra_pll_ref_ops, 0, clk_m_div_parent_names,
+               clk_m_div_parents, &tegra_clk_m);
+
+#define DEFINE_PLL(_name, _flags, _reg, _max_rate, _input_min, \
+                  _input_max, _cf_min, _cf_max, _vco_min,      \
+                  _vco_max, _freq_table, _lock_delay, _ops,    \
+                  _fixed_rate, _clk_cfg_ex, _parent)           \
+       static struct clk tegra_##_name;                        \
+       static const char *_name##_parent_names[] = {           \
+               #_parent,                                       \
+       };                                                      \
+       static struct clk *_name##_parents[] = {                \
+               &tegra_##_parent,                               \
+       };                                                      \
+       static struct clk_tegra tegra_##_name##_hw = {          \
+               .hw = {                                         \
+                       .clk = &tegra_##_name,                  \
+               },                                              \
+               .flags = _flags,                                \
+               .reg = _reg,                                    \
+               .max_rate = _max_rate,                          \
+               .u.pll = {                                      \
+                       .input_min = _input_min,                \
+                       .input_max = _input_max,                \
+                       .cf_min = _cf_min,                      \
+                       .cf_max = _cf_max,                      \
+                       .vco_min = _vco_min,                    \
+                       .vco_max = _vco_max,                    \
+                       .freq_table = _freq_table,              \
+                       .lock_delay = _lock_delay,              \
+                       .fixed_rate = _fixed_rate,              \
+               },                                              \
+               .clk_cfg_ex = _clk_cfg_ex,                      \
+       };                                                      \
+       DEFINE_CLK_TEGRA(_name, 0, &_ops, CLK_IGNORE_UNUSED,    \
+                        _name##_parent_names, _name##_parents, \
+                       &tegra_##_parent);
+
+#define DEFINE_PLL_OUT(_name, _flags, _reg, _reg_shift,                \
+               _max_rate, _ops, _parent, _clk_flags)           \
+       static const char *_name##_parent_names[] = {           \
+               #_parent,                                       \
+       };                                                      \
+       static struct clk *_name##_parents[] = {                \
+               &tegra_##_parent,                               \
+       };                                                      \
+       static struct clk tegra_##_name;                        \
+       static struct clk_tegra tegra_##_name##_hw = {          \
+               .hw = {                                         \
+                       .clk = &tegra_##_name,                  \
+               },                                              \
+               .flags = _flags,                                \
+               .reg = _reg,                                    \
+               .max_rate = _max_rate,                          \
+               .reg_shift = _reg_shift,                        \
+       };                                                      \
+       DEFINE_CLK_TEGRA(_name, 0, &tegra30_pll_div_ops,        \
+               _clk_flags,  _name##_parent_names,              \
+               _name##_parents, &tegra_##_parent);
+
+static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
+       { 12000000, 1040000000, 520,  6, 1, 8},
+       { 13000000, 1040000000, 480,  6, 1, 8},
+       { 16800000, 1040000000, 495,  8, 1, 8}, /* actual: 1039.5 MHz */
+       { 19200000, 1040000000, 325,  6, 1, 6},
+       { 26000000, 1040000000, 520, 13, 1, 8},
+
+       { 12000000, 832000000, 416,  6, 1, 8},
+       { 13000000, 832000000, 832, 13, 1, 8},
+       { 16800000, 832000000, 396,  8, 1, 8},  /* actual: 831.6 MHz */
+       { 19200000, 832000000, 260,  6, 1, 8},
+       { 26000000, 832000000, 416, 13, 1, 8},
+
+       { 12000000, 624000000, 624, 12, 1, 8},
+       { 13000000, 624000000, 624, 13, 1, 8},
+       { 16800000, 600000000, 520, 14, 1, 8},
+       { 19200000, 624000000, 520, 16, 1, 8},
+       { 26000000, 624000000, 624, 26, 1, 8},
+
+       { 12000000, 600000000, 600, 12, 1, 8},
+       { 13000000, 600000000, 600, 13, 1, 8},
+       { 16800000, 600000000, 500, 14, 1, 8},
+       { 19200000, 600000000, 375, 12, 1, 6},
+       { 26000000, 600000000, 600, 26, 1, 8},
+
+       { 12000000, 520000000, 520, 12, 1, 8},
+       { 13000000, 520000000, 520, 13, 1, 8},
+       { 16800000, 520000000, 495, 16, 1, 8},  /* actual: 519.75 MHz */
+       { 19200000, 520000000, 325, 12, 1, 6},
+       { 26000000, 520000000, 520, 26, 1, 8},
+
+       { 12000000, 416000000, 416, 12, 1, 8},
+       { 13000000, 416000000, 416, 13, 1, 8},
+       { 16800000, 416000000, 396, 16, 1, 8},  /* actual: 415.8 MHz */
+       { 19200000, 416000000, 260, 12, 1, 6},
+       { 26000000, 416000000, 416, 26, 1, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_c, PLL_HAS_CPCON, 0x80, 1400000000, 2000000, 31000000, 1000000,
+               6000000, 20000000, 1400000000, tegra_pll_c_freq_table, 300,
+               tegra30_pll_ops, 0, NULL, pll_ref);
+
+DEFINE_PLL_OUT(pll_c_out1, DIV_U71, 0x84, 0, 700000000,
+               tegra30_pll_div_ops, pll_c, CLK_IGNORE_UNUSED);
+
+static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
+       { 12000000, 666000000, 666, 12, 1, 8},
+       { 13000000, 666000000, 666, 13, 1, 8},
+       { 16800000, 666000000, 555, 14, 1, 8},
+       { 19200000, 666000000, 555, 16, 1, 8},
+       { 26000000, 666000000, 666, 26, 1, 8},
+       { 12000000, 600000000, 600, 12, 1, 8},
+       { 13000000, 600000000, 600, 13, 1, 8},
+       { 16800000, 600000000, 500, 14, 1, 8},
+       { 19200000, 600000000, 375, 12, 1, 6},
+       { 26000000, 600000000, 600, 26, 1, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_m, PLL_HAS_CPCON | PLLM, 0x90, 800000000, 2000000, 31000000,
+               1000000, 6000000, 20000000, 1200000000, tegra_pll_m_freq_table,
+               300, tegra30_pll_ops, 0, NULL, pll_ref);
+
+DEFINE_PLL_OUT(pll_m_out1, DIV_U71, 0x94, 0, 600000000,
+               tegra30_pll_div_ops, pll_m, CLK_IGNORE_UNUSED);
+
+static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
+       { 12000000, 216000000, 432, 12, 2, 8},
+       { 13000000, 216000000, 432, 13, 2, 8},
+       { 16800000, 216000000, 360, 14, 2, 8},
+       { 19200000, 216000000, 360, 16, 2, 8},
+       { 26000000, 216000000, 432, 26, 2, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_p, ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, 0xa0, 432000000,
+               2000000, 31000000, 1000000, 6000000, 20000000, 1400000000,
+               tegra_pll_p_freq_table, 300, tegra30_pll_ops, 408000000, NULL,
+               pll_ref);
+
+DEFINE_PLL_OUT(pll_p_out1, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4,
+               0, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
+DEFINE_PLL_OUT(pll_p_out2, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4,
+               16, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
+DEFINE_PLL_OUT(pll_p_out3, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8,
+               0, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
+DEFINE_PLL_OUT(pll_p_out4, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8,
+               16, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED);
+
+static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
+       { 9600000, 564480000, 294, 5, 1, 4},
+       { 9600000, 552960000, 288, 5, 1, 4},
+       { 9600000, 24000000,  5,   2, 1, 1},
+
+       { 28800000, 56448000, 49, 25, 1, 1},
+       { 28800000, 73728000, 64, 25, 1, 1},
+       { 28800000, 24000000,  5,  6, 1, 1},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_a, PLL_HAS_CPCON, 0xb0, 700000000, 2000000, 31000000, 1000000,
+               6000000, 20000000, 1400000000, tegra_pll_a_freq_table,
+               300, tegra30_pll_ops, 0, NULL, pll_p_out1);
+
+DEFINE_PLL_OUT(pll_a_out0, DIV_U71, 0xb4, 0, 100000000, tegra30_pll_div_ops,
+               pll_a, CLK_IGNORE_UNUSED);
+
+static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
+       { 12000000, 216000000, 216, 12, 1, 4},
+       { 13000000, 216000000, 216, 13, 1, 4},
+       { 16800000, 216000000, 180, 14, 1, 4},
+       { 19200000, 216000000, 180, 16, 1, 4},
+       { 26000000, 216000000, 216, 26, 1, 4},
+
+       { 12000000, 594000000, 594, 12, 1, 8},
+       { 13000000, 594000000, 594, 13, 1, 8},
+       { 16800000, 594000000, 495, 14, 1, 8},
+       { 19200000, 594000000, 495, 16, 1, 8},
+       { 26000000, 594000000, 594, 26, 1, 8},
+
+       { 12000000, 1000000000, 1000, 12, 1, 12},
+       { 13000000, 1000000000, 1000, 13, 1, 12},
+       { 19200000, 1000000000, 625,  12, 1, 8},
+       { 26000000, 1000000000, 1000, 26, 1, 12},
+
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_d, PLL_HAS_CPCON | PLLD, 0xd0, 1000000000, 2000000, 40000000,
+               1000000, 6000000, 40000000, 1000000000, tegra_pll_d_freq_table,
+               1000, tegra30_pll_ops, 0, tegra30_plld_clk_cfg_ex, pll_ref);
+
+DEFINE_PLL_OUT(pll_d_out0, DIV_2 | PLLD, 0, 0, 500000000, tegra30_pll_div_ops,
+               pll_d, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED);
+
+DEFINE_PLL(pll_d2, PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD, 0x4b8, 1000000000,
+               2000000, 40000000, 1000000, 6000000, 40000000, 1000000000,
+               tegra_pll_d_freq_table, 1000, tegra30_pll_ops, 0, NULL,
+               pll_ref);
+
+DEFINE_PLL_OUT(pll_d2_out0, DIV_2 | PLLD, 0, 0, 500000000, tegra30_pll_div_ops,
+               pll_d2, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED);
+
+static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
+       { 12000000, 480000000, 960, 12, 2, 12},
+       { 13000000, 480000000, 960, 13, 2, 12},
+       { 16800000, 480000000, 400, 7,  2, 5},
+       { 19200000, 480000000, 200, 4,  2, 3},
+       { 26000000, 480000000, 960, 26, 2, 12},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_u, PLL_HAS_CPCON | PLLU, 0xc0, 480000000, 2000000, 40000000,
+               1000000, 6000000, 48000000, 960000000, tegra_pll_u_freq_table,
+               1000, tegra30_pll_ops, 0, NULL, pll_ref);
+
+static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
+       /* 1.7 GHz */
+       { 12000000, 1700000000, 850,  6,  1, 8},
+       { 13000000, 1700000000, 915,  7,  1, 8},        /* actual: 1699.2 MHz */
+       { 16800000, 1700000000, 708,  7,  1, 8},        /* actual: 1699.2 MHz */
+       { 19200000, 1700000000, 885,  10, 1, 8},        /* actual: 1699.2 MHz */
+       { 26000000, 1700000000, 850,  13, 1, 8},
+
+       /* 1.6 GHz */
+       { 12000000, 1600000000, 800,  6,  1, 8},
+       { 13000000, 1600000000, 738,  6,  1, 8},        /* actual: 1599.0 MHz */
+       { 16800000, 1600000000, 857,  9,  1, 8},        /* actual: 1599.7 MHz */
+       { 19200000, 1600000000, 500,  6,  1, 8},
+       { 26000000, 1600000000, 800,  13, 1, 8},
+
+       /* 1.5 GHz */
+       { 12000000, 1500000000, 750,  6,  1, 8},
+       { 13000000, 1500000000, 923,  8,  1, 8},        /* actual: 1499.8 MHz */
+       { 16800000, 1500000000, 625,  7,  1, 8},
+       { 19200000, 1500000000, 625,  8,  1, 8},
+       { 26000000, 1500000000, 750,  13, 1, 8},
+
+       /* 1.4 GHz */
+       { 12000000, 1400000000, 700,  6,  1, 8},
+       { 13000000, 1400000000, 969,  9,  1, 8},        /* actual: 1399.7 MHz */
+       { 16800000, 1400000000, 1000, 12, 1, 8},
+       { 19200000, 1400000000, 875,  12, 1, 8},
+       { 26000000, 1400000000, 700,  13, 1, 8},
+
+       /* 1.3 GHz */
+       { 12000000, 1300000000, 975,  9,  1, 8},
+       { 13000000, 1300000000, 1000, 10, 1, 8},
+       { 16800000, 1300000000, 928,  12, 1, 8},        /* actual: 1299.2 MHz */
+       { 19200000, 1300000000, 812,  12, 1, 8},        /* actual: 1299.2 MHz */
+       { 26000000, 1300000000, 650,  13, 1, 8},
+
+       /* 1.2 GHz */
+       { 12000000, 1200000000, 1000, 10, 1, 8},
+       { 13000000, 1200000000, 923,  10, 1, 8},        /* actual: 1199.9 MHz */
+       { 16800000, 1200000000, 1000, 14, 1, 8},
+       { 19200000, 1200000000, 1000, 16, 1, 8},
+       { 26000000, 1200000000, 600,  13, 1, 8},
+
+       /* 1.1 GHz */
+       { 12000000, 1100000000, 825,  9,  1, 8},
+       { 13000000, 1100000000, 846,  10, 1, 8},        /* actual: 1099.8 MHz */
+       { 16800000, 1100000000, 982,  15, 1, 8},        /* actual: 1099.8 MHz */
+       { 19200000, 1100000000, 859,  15, 1, 8},        /* actual: 1099.5 MHz */
+       { 26000000, 1100000000, 550,  13, 1, 8},
+
+       /* 1 GHz */
+       { 12000000, 1000000000, 1000, 12, 1, 8},
+       { 13000000, 1000000000, 1000, 13, 1, 8},
+       { 16800000, 1000000000, 833,  14, 1, 8},        /* actual: 999.6 MHz */
+       { 19200000, 1000000000, 625,  12, 1, 8},
+       { 26000000, 1000000000, 1000, 26, 1, 8},
+
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_x, PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX, 0xe0, 1700000000,
+               2000000, 31000000, 1000000, 6000000, 20000000, 1700000000,
+               tegra_pll_x_freq_table, 300, tegra30_pll_ops, 0, NULL, pll_ref);
+
+DEFINE_PLL_OUT(pll_x_out0, DIV_2 | PLLX, 0, 0, 850000000, tegra30_pll_div_ops,
+               pll_x, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED);
+
+static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
+       /* PLLE special case: use cpcon field to store cml divider value */
+       { 12000000,  100000000, 150, 1,  18, 11},
+       { 216000000, 100000000, 200, 18, 24, 13},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+DEFINE_PLL(pll_e, PLL_ALT_MISC_REG, 0xe8, 100000000, 2000000, 216000000,
+               12000000, 12000000, 1200000000, 2400000000U,
+               tegra_pll_e_freq_table, 300, tegra30_plle_ops, 100000000, NULL,
+               pll_ref);
+
+static const char *mux_plle[] = {
+       "pll_e",
+};
+
+static struct clk *mux_plle_p[] = {
+       &tegra_pll_e,
+};
+
+static struct clk tegra_cml0;
+static struct clk_tegra tegra_cml0_hw = {
+       .hw = {
+               .clk = &tegra_cml0,
+       },
+       .reg = 0x48c,
+       .fixed_rate = 100000000,
+       .u.periph = {
+               .clk_num = 0,
+       },
+};
+DEFINE_CLK_TEGRA(cml0, 0, &tegra_cml_clk_ops, 0, mux_plle,
+               mux_plle_p, &tegra_pll_e);
+
+static struct clk tegra_cml1;
+static struct clk_tegra tegra_cml1_hw = {
+       .hw = {
+               .clk = &tegra_cml1,
+       },
+       .reg = 0x48c,
+       .fixed_rate = 100000000,
+       .u.periph = {
+               .clk_num = 1,
+       },
+};
+DEFINE_CLK_TEGRA(cml1, 0, &tegra_cml_clk_ops, 0, mux_plle,
+               mux_plle_p, &tegra_pll_e);
+
+static struct clk tegra_pciex;
+static struct clk_tegra tegra_pciex_hw = {
+       .hw = {
+               .clk = &tegra_pciex,
+       },
+       .reg = 0x48c,
+       .fixed_rate = 100000000,
+       .reset = tegra30_periph_clk_reset,
+       .u.periph = {
+               .clk_num = 74,
+       },
+};
+DEFINE_CLK_TEGRA(pciex, 0, &tegra_pciex_clk_ops, 0, mux_plle,
+               mux_plle_p, &tegra_pll_e);
+
+#define SYNC_SOURCE(_name)                                     \
+       static struct clk tegra_##_name##_sync;                 \
+       static struct clk_tegra tegra_##_name##_sync_hw = {     \
+               .hw = {                                         \
+                       .clk = &tegra_##_name##_sync,           \
+               },                                              \
+               .max_rate = 24000000,                           \
+               .fixed_rate = 24000000,                         \
+       };                                                      \
+       static struct clk tegra_##_name##_sync = {              \
+               .name = #_name "_sync",                         \
+               .hw = &tegra_##_name##_sync_hw.hw,              \
+               .ops = &tegra_sync_source_ops,                  \
+               .flags = CLK_IS_ROOT,                           \
+       };
+
+SYNC_SOURCE(spdif_in);
+SYNC_SOURCE(i2s0);
+SYNC_SOURCE(i2s1);
+SYNC_SOURCE(i2s2);
+SYNC_SOURCE(i2s3);
+SYNC_SOURCE(i2s4);
+SYNC_SOURCE(vimclk);
+
+static struct clk *tegra_sync_source_list[] = {
+       &tegra_spdif_in_sync,
+       &tegra_i2s0_sync,
+       &tegra_i2s1_sync,
+       &tegra_i2s2_sync,
+       &tegra_i2s3_sync,
+       &tegra_i2s4_sync,
+       &tegra_vimclk_sync,
+};
+
+static const char *mux_audio_sync_clk[] = {
+       "spdif_in_sync",
+       "i2s0_sync",
+       "i2s1_sync",
+       "i2s2_sync",
+       "i2s3_sync",
+       "i2s4_sync",
+       "vimclk_sync",
+};
+
+#define AUDIO_SYNC_CLK(_name, _index)                          \
+       static struct clk tegra_##_name;                        \
+       static struct clk_tegra tegra_##_name##_hw = {          \
+               .hw = {                                         \
+                       .clk = &tegra_##_name,                  \
+               },                                              \
+               .max_rate = 24000000,                           \
+               .reg = 0x4A0 + (_index) * 4,                    \
+       };                                                      \
+       static struct clk tegra_##_name = {                     \
+               .name = #_name,                                 \
+               .ops = &tegra30_audio_sync_clk_ops,             \
+               .hw = &tegra_##_name##_hw.hw,                   \
+               .parent_names = mux_audio_sync_clk,             \
+               .parents = tegra_sync_source_list,              \
+               .num_parents = ARRAY_SIZE(mux_audio_sync_clk),  \
+       };
+
+AUDIO_SYNC_CLK(audio0, 0);
+AUDIO_SYNC_CLK(audio1, 1);
+AUDIO_SYNC_CLK(audio2, 2);
+AUDIO_SYNC_CLK(audio3, 3);
+AUDIO_SYNC_CLK(audio4, 4);
+AUDIO_SYNC_CLK(audio5, 5);
+
+static struct clk *tegra_clk_audio_list[] = {
+       &tegra_audio0,
+       &tegra_audio1,
+       &tegra_audio2,
+       &tegra_audio3,
+       &tegra_audio4,
+       &tegra_audio5,  /* SPDIF */
+};
+
+#define AUDIO_SYNC_2X_CLK(_name, _index)                       \
+       static const char *_name##_parent_names[] = {           \
+               "tegra_" #_name,                                \
+       };                                                      \
+       static struct clk *_name##_parents[] = {                \
+               &tegra_##_name,                                 \
+       };                                                      \
+       static struct clk tegra_##_name##_2x;                   \
+       static struct clk_tegra tegra_##_name##_2x_hw = {       \
+               .hw = {                                         \
+                       .clk = &tegra_##_name##_2x,             \
+               },                                              \
+               .flags = PERIPH_NO_RESET,                       \
+               .max_rate = 48000000,                           \
+               .reg = 0x49C,                                   \
+               .reg_shift = 24 + (_index),                     \
+               .u.periph = {                                   \
+                       .clk_num = 113 + (_index),              \
+               },                                              \
+       };                                                      \
+       static struct clk tegra_##_name##_2x = {                \
+               .name = #_name "_2x",                           \
+               .ops = &tegra30_clk_double_ops,                 \
+               .hw = &tegra_##_name##_2x_hw.hw,                \
+               .parent_names = _name##_parent_names,           \
+               .parents = _name##_parents,                     \
+               .parent = &tegra_##_name,                       \
+               .num_parents = 1,                               \
+       };
+
+AUDIO_SYNC_2X_CLK(audio0, 0);
+AUDIO_SYNC_2X_CLK(audio1, 1);
+AUDIO_SYNC_2X_CLK(audio2, 2);
+AUDIO_SYNC_2X_CLK(audio3, 3);
+AUDIO_SYNC_2X_CLK(audio4, 4);
+AUDIO_SYNC_2X_CLK(audio5, 5);  /* SPDIF */
+
+static struct clk *tegra_clk_audio_2x_list[] = {
+       &tegra_audio0_2x,
+       &tegra_audio1_2x,
+       &tegra_audio2_2x,
+       &tegra_audio3_2x,
+       &tegra_audio4_2x,
+       &tegra_audio5_2x,       /* SPDIF */
+};
+
+#define MUX_I2S_SPDIF(_id)                                     \
+static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = {     \
+       "pll_a_out0",                                           \
+       #_id "_2x",                                             \
+       "pll_p",                                                \
+       "clk_m",                                                \
+};                                                             \
+static struct clk *mux_pllaout0_##_id##_2x_pllp_clkm_p[] = {   \
+       &tegra_pll_a_out0,                                      \
+       &tegra_##_id##_2x,                                      \
+       &tegra_pll_p,                                           \
+       &tegra_clk_m,                                           \
+};
+
+MUX_I2S_SPDIF(audio0);
+MUX_I2S_SPDIF(audio1);
+MUX_I2S_SPDIF(audio2);
+MUX_I2S_SPDIF(audio3);
+MUX_I2S_SPDIF(audio4);
+MUX_I2S_SPDIF(audio5);         /* SPDIF */
+
+static struct clk tegra_extern1;
+static struct clk tegra_extern2;
+static struct clk tegra_extern3;
+
+/* External clock outputs (through PMC) */
+#define MUX_EXTERN_OUT(_id)                                    \
+static const char *mux_clkm_clkm2_clkm4_extern##_id[] = {      \
+       "clk_m",                                                \
+       "clk_m_div2",                                           \
+       "clk_m_div4",                                           \
+       "extern" #_id,                                          \
+};                                                             \
+static struct clk *mux_clkm_clkm2_clkm4_extern##_id##_p[] = {  \
+       &tegra_clk_m,                                           \
+       &tegra_clk_m_div2,                                      \
+       &tegra_clk_m_div4,                                      \
+       &tegra_extern##_id,                                     \
+};
+
+MUX_EXTERN_OUT(1);
+MUX_EXTERN_OUT(2);
+MUX_EXTERN_OUT(3);
+
+#define CLK_OUT_CLK(_name, _index)                                     \
+       static struct clk tegra_##_name;                                \
+       static struct clk_tegra tegra_##_name##_hw = {                  \
+               .hw = {                                                 \
+                       .clk = &tegra_##_name,                          \
+               },                                                      \
+               .lookup = {                                             \
+                       .dev_id = #_name,                               \
+                       .con_id = "extern" #_index,                     \
+               },                                                      \
+               .flags = MUX_CLK_OUT,                                   \
+               .fixed_rate = 216000000,                                        \
+               .reg = 0x1a8,                                           \
+               .u.periph = {                                           \
+                       .clk_num = (_index - 1) * 8 + 2,                \
+               },                                                      \
+       };                                                              \
+       static struct clk tegra_##_name = {                             \
+               .name = #_name,                                         \
+               .ops = &tegra_clk_out_ops,                              \
+               .hw = &tegra_##_name##_hw.hw,                           \
+               .parent_names = mux_clkm_clkm2_clkm4_extern##_index,    \
+               .parents = mux_clkm_clkm2_clkm4_extern##_index##_p,     \
+               .num_parents = ARRAY_SIZE(mux_clkm_clkm2_clkm4_extern##_index),\
+       };
+
+CLK_OUT_CLK(clk_out_1, 1);
+CLK_OUT_CLK(clk_out_2, 2);
+CLK_OUT_CLK(clk_out_3, 3);
+
+static struct clk *tegra_clk_out_list[] = {
+       &tegra_clk_out_1,
+       &tegra_clk_out_2,
+       &tegra_clk_out_3,
+};
+
+static const char *mux_sclk[] = {
+       "clk_m",
+       "pll_c_out1",
+       "pll_p_out4",
+       "pll_p_out3",
+       "pll_p_out2",
+       "dummy",
+       "clk_32k",
+       "pll_m_out1",
+};
+
+static struct clk *mux_sclk_p[] = {
+       &tegra_clk_m,
+       &tegra_pll_c_out1,
+       &tegra_pll_p_out4,
+       &tegra_pll_p_out3,
+       &tegra_pll_p_out2,
+       NULL,
+       &tegra_clk_32k,
+       &tegra_pll_m_out1,
+};
+
+static struct clk tegra_clk_sclk;
+static struct clk_tegra tegra_clk_sclk_hw = {
+       .hw = {
+               .clk = &tegra_clk_sclk,
+       },
+       .reg = 0x28,
+       .max_rate = 334000000,
+       .min_rate = 40000000,
+};
+
+static struct clk tegra_clk_sclk = {
+       .name = "sclk",
+       .ops = &tegra30_super_ops,
+       .hw = &tegra_clk_sclk_hw.hw,
+       .parent_names = mux_sclk,
+       .parents = mux_sclk_p,
+       .num_parents = ARRAY_SIZE(mux_sclk),
+};
+
+static const char *mux_blink[] = {
+       "clk_32k",
+};
+
+static struct clk *mux_blink_p[] = {
+       &tegra_clk_32k,
+};
+
+static struct clk tegra_clk_blink;
+static struct clk_tegra tegra_clk_blink_hw = {
+       .hw = {
+               .clk = &tegra_clk_blink,
+       },
+       .reg = 0x40,
+       .max_rate = 32768,
+};
+static struct clk tegra_clk_blink = {
+       .name = "blink",
+       .ops = &tegra30_blink_clk_ops,
+       .hw = &tegra_clk_blink_hw.hw,
+       .parent = &tegra_clk_32k,
+       .parent_names = mux_blink,
+       .parents = mux_blink_p,
+       .num_parents = ARRAY_SIZE(mux_blink),
+};
+
+static const char *mux_pllm_pllc_pllp_plla[] = {
+       "pll_m",
+       "pll_c",
+       "pll_p",
+       "pll_a_out0",
+};
+
+static const char *mux_pllp_pllc_pllm_clkm[] = {
+       "pll_p",
+       "pll_c",
+       "pll_m",
+       "clk_m",
+};
+
+static const char *mux_pllp_clkm[] = {
+       "pll_p",
+       "dummy",
+       "dummy",
+       "clk_m",
+};
+
+static const char *mux_pllp_plld_pllc_clkm[] = {
+       "pll_p",
+       "pll_d_out0",
+       "pll_c",
+       "clk_m",
+};
+
+static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
+       "pll_p",
+       "pll_m",
+       "pll_d_out0",
+       "pll_a_out0",
+       "pll_c",
+       "pll_d2_out0",
+       "clk_m",
+};
+
+static const char *mux_plla_pllc_pllp_clkm[] = {
+       "pll_a_out0",
+       "dummy",
+       "pll_p",
+       "clk_m"
+};
+
+static const char *mux_pllp_pllc_clk32_clkm[] = {
+       "pll_p",
+       "pll_c",
+       "clk_32k",
+       "clk_m",
+};
+
+static const char *mux_pllp_pllc_clkm_clk32[] = {
+       "pll_p",
+       "pll_c",
+       "clk_m",
+       "clk_32k",
+};
+
+static const char *mux_pllp_pllc_pllm[] = {
+       "pll_p",
+       "pll_c",
+       "pll_m",
+};
+
+static const char *mux_clk_m[] = {
+       "clk_m",
+};
+
+static const char *mux_pllp_out3[] = {
+       "pll_p_out3",
+};
+
+static const char *mux_plld_out0[] = {
+       "pll_d_out0",
+};
+
+static const char *mux_plld_out0_plld2_out0[] = {
+       "pll_d_out0",
+       "pll_d2_out0",
+};
+
+static const char *mux_clk_32k[] = {
+       "clk_32k",
+};
+
+static const char *mux_plla_clk32_pllp_clkm_plle[] = {
+       "pll_a_out0",
+       "clk_32k",
+       "pll_p",
+       "clk_m",
+       "pll_e",
+};
+
+static const char *mux_cclk_g[] = {
+       "clk_m",
+       "pll_c",
+       "clk_32k",
+       "pll_m",
+       "pll_p",
+       "pll_p_out4",
+       "pll_p_out3",
+       "dummy",
+       "pll_x",
+};
+
+static struct clk *mux_pllm_pllc_pllp_plla_p[] = {
+       &tegra_pll_m,
+       &tegra_pll_c,
+       &tegra_pll_p,
+       &tegra_pll_a_out0,
+};
+
+static struct clk *mux_pllp_pllc_pllm_clkm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_c,
+       &tegra_pll_m,
+       &tegra_clk_m,
+};
+
+static struct clk *mux_pllp_clkm_p[] = {
+       &tegra_pll_p,
+       NULL,
+       NULL,
+       &tegra_clk_m,
+};
+
+static struct clk *mux_pllp_plld_pllc_clkm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_d_out0,
+       &tegra_pll_c,
+       &tegra_clk_m,
+};
+
+static struct clk *mux_pllp_pllm_plld_plla_pllc_plld2_clkm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_m,
+       &tegra_pll_d_out0,
+       &tegra_pll_a_out0,
+       &tegra_pll_c,
+       &tegra_pll_d2_out0,
+       &tegra_clk_m,
+};
+
+static struct clk *mux_plla_pllc_pllp_clkm_p[] = {
+       &tegra_pll_a_out0,
+       NULL,
+       &tegra_pll_p,
+       &tegra_clk_m,
+};
+
+static struct clk *mux_pllp_pllc_clk32_clkm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_c,
+       &tegra_clk_32k,
+       &tegra_clk_m,
+};
+
+static struct clk *mux_pllp_pllc_clkm_clk32_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_c,
+       &tegra_clk_m,
+       &tegra_clk_32k,
+};
+
+static struct clk *mux_pllp_pllc_pllm_p[] = {
+       &tegra_pll_p,
+       &tegra_pll_c,
+       &tegra_pll_m,
+};
+
+static struct clk *mux_clk_m_p[] = {
+       &tegra_clk_m,
+};
+
+static struct clk *mux_pllp_out3_p[] = {
+       &tegra_pll_p_out3,
+};
+
+static struct clk *mux_plld_out0_p[] = {
+       &tegra_pll_d_out0,
+};
+
+static struct clk *mux_plld_out0_plld2_out0_p[] = {
+       &tegra_pll_d_out0,
+       &tegra_pll_d2_out0,
+};
+
+static struct clk *mux_clk_32k_p[] = {
+       &tegra_clk_32k,
+};
+
+static struct clk *mux_plla_clk32_pllp_clkm_plle_p[] = {
+       &tegra_pll_a_out0,
+       &tegra_clk_32k,
+       &tegra_pll_p,
+       &tegra_clk_m,
+       &tegra_pll_e,
+};
+
+static struct clk *mux_cclk_g_p[] = {
+       &tegra_clk_m,
+       &tegra_pll_c,
+       &tegra_clk_32k,
+       &tegra_pll_m,
+       &tegra_pll_p,
+       &tegra_pll_p_out4,
+       &tegra_pll_p_out3,
+       NULL,
+       &tegra_pll_x,
+};
+
+static struct clk tegra_clk_cclk_g;
+static struct clk_tegra tegra_clk_cclk_g_hw = {
+       .hw = {
+               .clk = &tegra_clk_cclk_g,
+       },
+       .flags = DIV_U71 | DIV_U71_INT,
+       .reg = 0x368,
+       .max_rate = 1700000000,
+};
+static struct clk tegra_clk_cclk_g = {
+       .name = "cclk_g",
+       .ops = &tegra30_super_ops,
+       .hw = &tegra_clk_cclk_g_hw.hw,
+       .parent_names = mux_cclk_g,
+       .parents = mux_cclk_g_p,
+       .num_parents = ARRAY_SIZE(mux_cclk_g),
+};
+
+static const char *mux_twd[] = {
+       "cclk_g",
+};
+
+static struct clk *mux_twd_p[] = {
+       &tegra_clk_cclk_g,
+};
+
+static struct clk tegra30_clk_twd;
+static struct clk_tegra tegra30_clk_twd_hw = {
+       .hw = {
+               .clk = &tegra30_clk_twd,
+       },
+       .max_rate = 1400000000,
+       .mul = 1,
+       .div = 2,
+};
+
+static struct clk tegra30_clk_twd = {
+       .name = "twd",
+       .ops = &tegra30_twd_ops,
+       .hw = &tegra30_clk_twd_hw.hw,
+       .parent = &tegra_clk_cclk_g,
+       .parent_names = mux_twd,
+       .parents = mux_twd_p,
+       .num_parents = ARRAY_SIZE(mux_twd),
+};
+
+#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg,  \
+               _max, _inputs, _flags)                  \
+       static struct clk tegra_##_name;                \
+       static struct clk_tegra tegra_##_name##_hw = {  \
+               .hw = {                                 \
+                       .clk = &tegra_##_name,          \
+               },                                      \
+               .lookup = {                             \
+                       .dev_id = _dev,                 \
+                       .con_id = _con,                 \
+               },                                      \
+               .reg = _reg,                            \
+               .flags = _flags,                        \
+               .max_rate = _max,                       \
+               .u.periph = {                           \
+                       .clk_num = _clk_num,            \
+               },                                      \
+               .reset = &tegra30_periph_clk_reset,     \
+       };                                              \
+       static struct clk tegra_##_name = {             \
+               .name = #_name,                         \
+               .ops = &tegra30_periph_clk_ops,         \
+               .hw = &tegra_##_name##_hw.hw,           \
+               .parent_names = _inputs,                \
+               .parents = _inputs##_p,                 \
+               .num_parents = ARRAY_SIZE(_inputs),     \
+       };
+
+PERIPH_CLK(apbdma,     "tegra-apbdma",         NULL,   34,     0,      26000000,  mux_clk_m,                   0);
+PERIPH_CLK(rtc,                "rtc-tegra",            NULL,   4,      0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET | PERIPH_ON_APB);
+PERIPH_CLK(kbc,                "tegra-kbc",            NULL,   36,     0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET | PERIPH_ON_APB);
+PERIPH_CLK(timer,      "timer",                NULL,   5,      0,      26000000,  mux_clk_m,                   0);
+PERIPH_CLK(kfuse,      "kfuse-tegra",          NULL,   40,     0,      26000000,  mux_clk_m,                   0);
+PERIPH_CLK(fuse,       "fuse-tegra",           "fuse", 39,     0,      26000000,  mux_clk_m,                   PERIPH_ON_APB);
+PERIPH_CLK(fuse_burn,  "fuse-tegra",           "fuse_burn",    39,     0,      26000000,  mux_clk_m,           PERIPH_ON_APB);
+PERIPH_CLK(apbif,      "tegra30-ahub",         "apbif", 107,   0,      26000000,  mux_clk_m,                   0);
+PERIPH_CLK(i2s0,       "tegra30-i2s.0",        NULL,   30,     0x1d8,  26000000,  mux_pllaout0_audio0_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(i2s1,       "tegra30-i2s.1",        NULL,   11,     0x100,  26000000,  mux_pllaout0_audio1_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(i2s2,       "tegra30-i2s.2",        NULL,   18,     0x104,  26000000,  mux_pllaout0_audio2_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(i2s3,       "tegra30-i2s.3",        NULL,   101,    0x3bc,  26000000,  mux_pllaout0_audio3_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(i2s4,       "tegra30-i2s.4",        NULL,   102,    0x3c0,  26000000,  mux_pllaout0_audio4_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(spdif_out,  "tegra30-spdif",        "spdif_out",    10,     0x108,  100000000, mux_pllaout0_audio5_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(spdif_in,   "tegra30-spdif",        "spdif_in",     10,     0x10c,  100000000, mux_pllp_pllc_pllm,          MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(pwm,                "tegra-pwm",            NULL,   17,     0x110,  432000000, mux_pllp_pllc_clk32_clkm,    MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(d_audio,    "tegra30-ahub",         "d_audio", 106, 0x3d0,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71);
+PERIPH_CLK(dam0,       "tegra30-dam.0",        NULL,   108,    0x3d8,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71);
+PERIPH_CLK(dam1,       "tegra30-dam.1",        NULL,   109,    0x3dc,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71);
+PERIPH_CLK(dam2,       "tegra30-dam.2",        NULL,   110,    0x3e0,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71);
+PERIPH_CLK(hda,                "tegra30-hda",          "hda",  125,    0x428,  108000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(hda2codec_2x,       "tegra30-hda",  "hda2codec",    111,    0x3e4,  48000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(hda2hdmi,   "tegra30-hda",          "hda2hdmi",     128,    0,      48000000,  mux_clk_m,                   0);
+PERIPH_CLK(sbc1,       "spi_tegra.0",          NULL,   41,     0x134,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(sbc2,       "spi_tegra.1",          NULL,   44,     0x118,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(sbc3,       "spi_tegra.2",          NULL,   46,     0x11c,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(sbc4,       "spi_tegra.3",          NULL,   68,     0x1b4,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(sbc5,       "spi_tegra.4",          NULL,   104,    0x3c8,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(sbc6,       "spi_tegra.5",          NULL,   105,    0x3cc,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(sata_oob,   "tegra_sata_oob",       NULL,   123,    0x420,  216000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(sata,       "tegra_sata",           NULL,   124,    0x424,  216000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(sata_cold,  "tegra_sata_cold",      NULL,   129,    0,      48000000,  mux_clk_m,                   0);
+PERIPH_CLK(ndflash,    "tegra_nand",           NULL,   13,     0x160,  240000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(ndspeed,    "tegra_nand_speed",     NULL,   80,     0x3f8,  240000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(vfir,       "vfir",                 NULL,   7,      0x168,  72000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(sdmmc1,     "sdhci-tegra.0",        NULL,   14,     0x150,  208000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(sdmmc2,     "sdhci-tegra.1",        NULL,   9,      0x154,  104000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(sdmmc3,     "sdhci-tegra.2",        NULL,   69,     0x1bc,  208000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(sdmmc4,     "sdhci-tegra.3",        NULL,   15,     0x164,  104000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* scales with voltage */
+PERIPH_CLK(vcp,                "tegra-avp",            "vcp",  29,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(bsea,       "tegra-avp",            "bsea", 62,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(bsev,       "tegra-aes",            "bsev", 63,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(vde,                "vde",                  NULL,   61,     0x1c8,  520000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_INT);
+PERIPH_CLK(csite,      "csite",                NULL,   73,     0x1d4,  144000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* max rate ??? */
+PERIPH_CLK(la,         "la",                   NULL,   76,     0x1f8,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71);
+PERIPH_CLK(owr,                "tegra_w1",             NULL,   71,     0x1cc,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(nor,                "nor",                  NULL,   42,     0x1d0,  127000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(mipi,       "mipi",                 NULL,   50,     0x174,  60000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB); /* scales with voltage */
+PERIPH_CLK(i2c1,       "tegra-i2c.0",          "div-clk", 12,  0x124,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c2,       "tegra-i2c.1",          "div-clk", 54,  0x198,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c3,       "tegra-i2c.2",          "div-clk", 67,  0x1b8,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c4,       "tegra-i2c.3",          "div-clk", 103, 0x3c4,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c5,       "tegra-i2c.4",          "div-clk", 47,  0x128,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(uarta,      "tegra-uart.0",         NULL,   6,      0x178,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
+PERIPH_CLK(uartb,      "tegra-uart.1",         NULL,   7,      0x17c,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
+PERIPH_CLK(uartc,      "tegra-uart.2",         NULL,   55,     0x1a0,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
+PERIPH_CLK(uartd,      "tegra-uart.3",         NULL,   65,     0x1c0,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
+PERIPH_CLK(uarte,      "tegra-uart.4",         NULL,   66,     0x1c4,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB);
+PERIPH_CLK(vi,         "tegra_camera",         "vi",   20,     0x148,  425000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT);
+PERIPH_CLK(3d,         "3d",                   NULL,   24,     0x158,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET);
+PERIPH_CLK(3d2,                "3d2",                  NULL,   98,     0x3b0,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET);
+PERIPH_CLK(2d,         "2d",                   NULL,   21,     0x15c,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE);
+PERIPH_CLK(vi_sensor,  "tegra_camera",         "vi_sensor",    20,     0x1a8,  150000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_NO_RESET);
+PERIPH_CLK(epp,                "epp",                  NULL,   19,     0x16c,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT);
+PERIPH_CLK(mpe,                "mpe",                  NULL,   60,     0x170,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT);
+PERIPH_CLK(host1x,     "host1x",               NULL,   28,     0x180,  260000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT);
+PERIPH_CLK(cve,                "cve",                  NULL,   49,     0x140,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(tvo,                "tvo",                  NULL,   49,     0x188,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(dtv,                "dtv",                  NULL,   79,     0x1dc,  250000000, mux_clk_m,                   0);
+PERIPH_CLK(hdmi,       "hdmi",                 NULL,   51,     0x18c,  148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8 | DIV_U71);
+PERIPH_CLK(tvdac,      "tvdac",                NULL,   53,     0x194,  220000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71); /* requires min voltage */
+PERIPH_CLK(disp1,      "tegradc.0",            NULL,   27,     0x138,  600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8);
+PERIPH_CLK(disp2,      "tegradc.1",            NULL,   26,     0x13c,  600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8);
+PERIPH_CLK(usbd,       "fsl-tegra-udc",        NULL,   22,     0,      480000000, mux_clk_m,                   0); /* requires min voltage */
+PERIPH_CLK(usb2,       "tegra-ehci.1",         NULL,   58,     0,      480000000, mux_clk_m,                   0); /* requires min voltage */
+PERIPH_CLK(usb3,       "tegra-ehci.2",         NULL,   59,     0,      480000000, mux_clk_m,                   0); /* requires min voltage */
+PERIPH_CLK(dsia,       "tegradc.0",            "dsia", 48,     0,      500000000, mux_plld_out0,               0);
+PERIPH_CLK(csi,                "tegra_camera",         "csi",  52,     0,      102000000, mux_pllp_out3,               0);
+PERIPH_CLK(isp,                "tegra_camera",         "isp",  23,     0,      150000000, mux_clk_m,                   0); /* same frequency as VI */
+PERIPH_CLK(csus,       "tegra_camera",         "csus", 92,     0,      150000000, mux_clk_m,                   PERIPH_NO_RESET);
+PERIPH_CLK(tsensor,    "tegra-tsensor",        NULL,   100,    0x3b8,  216000000, mux_pllp_pllc_clkm_clk32,    MUX | DIV_U71);
+PERIPH_CLK(actmon,     "actmon",               NULL,   119,    0x3e8,  216000000, mux_pllp_pllc_clk32_clkm,    MUX | DIV_U71);
+PERIPH_CLK(extern1,    "extern1",              NULL,   120,    0x3ec,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71);
+PERIPH_CLK(extern2,    "extern2",              NULL,   121,    0x3f0,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71);
+PERIPH_CLK(extern3,    "extern3",              NULL,   122,    0x3f4,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71);
+PERIPH_CLK(i2cslow,    "i2cslow",              NULL,   81,     0x3fc,  26000000,  mux_pllp_pllc_clk32_clkm,    MUX | DIV_U71 | PERIPH_ON_APB);
+PERIPH_CLK(pcie,       "tegra-pcie",           "pcie", 70,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(afi,                "tegra-pcie",           "afi",  72,     0,      250000000, mux_clk_m,                   0);
+PERIPH_CLK(se,         "se",                   NULL,   127,    0x42c,  520000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_INT);
+
+static struct clk tegra_dsib;
+static struct clk_tegra tegra_dsib_hw = {
+       .hw = {
+               .clk = &tegra_dsib,
+       },
+       .lookup = {
+               .dev_id = "tegradc.1",
+               .con_id = "dsib",
+       },
+       .reg = 0xd0,
+       .flags = MUX | PLLD,
+       .max_rate = 500000000,
+       .u.periph = {
+               .clk_num = 82,
+       },
+       .reset = &tegra30_periph_clk_reset,
+};
+static struct clk tegra_dsib = {
+       .name = "dsib",
+       .ops = &tegra30_dsib_clk_ops,
+       .hw = &tegra_dsib_hw.hw,
+       .parent_names = mux_plld_out0_plld2_out0,
+       .parents = mux_plld_out0_plld2_out0_p,
+       .num_parents = ARRAY_SIZE(mux_plld_out0_plld2_out0),
+};
+
+struct clk *tegra_list_clks[] = {
+       &tegra_apbdma,
+       &tegra_rtc,
+       &tegra_kbc,
+       &tegra_kfuse,
+       &tegra_fuse,
+       &tegra_fuse_burn,
+       &tegra_apbif,
+       &tegra_i2s0,
+       &tegra_i2s1,
+       &tegra_i2s2,
+       &tegra_i2s3,
+       &tegra_i2s4,
+       &tegra_spdif_out,
+       &tegra_spdif_in,
+       &tegra_pwm,
+       &tegra_d_audio,
+       &tegra_dam0,
+       &tegra_dam1,
+       &tegra_dam2,
+       &tegra_hda,
+       &tegra_hda2codec_2x,
+       &tegra_hda2hdmi,
+       &tegra_sbc1,
+       &tegra_sbc2,
+       &tegra_sbc3,
+       &tegra_sbc4,
+       &tegra_sbc5,
+       &tegra_sbc6,
+       &tegra_sata_oob,
+       &tegra_sata,
+       &tegra_sata_cold,
+       &tegra_ndflash,
+       &tegra_ndspeed,
+       &tegra_vfir,
+       &tegra_sdmmc1,
+       &tegra_sdmmc2,
+       &tegra_sdmmc3,
+       &tegra_sdmmc4,
+       &tegra_vcp,
+       &tegra_bsea,
+       &tegra_bsev,
+       &tegra_vde,
+       &tegra_csite,
+       &tegra_la,
+       &tegra_owr,
+       &tegra_nor,
+       &tegra_mipi,
+       &tegra_i2c1,
+       &tegra_i2c2,
+       &tegra_i2c3,
+       &tegra_i2c4,
+       &tegra_i2c5,
+       &tegra_uarta,
+       &tegra_uartb,
+       &tegra_uartc,
+       &tegra_uartd,
+       &tegra_uarte,
+       &tegra_vi,
+       &tegra_3d,
+       &tegra_3d2,
+       &tegra_2d,
+       &tegra_vi_sensor,
+       &tegra_epp,
+       &tegra_mpe,
+       &tegra_host1x,
+       &tegra_cve,
+       &tegra_tvo,
+       &tegra_dtv,
+       &tegra_hdmi,
+       &tegra_tvdac,
+       &tegra_disp1,
+       &tegra_disp2,
+       &tegra_usbd,
+       &tegra_usb2,
+       &tegra_usb3,
+       &tegra_dsia,
+       &tegra_dsib,
+       &tegra_csi,
+       &tegra_isp,
+       &tegra_csus,
+       &tegra_tsensor,
+       &tegra_actmon,
+       &tegra_extern1,
+       &tegra_extern2,
+       &tegra_extern3,
+       &tegra_i2cslow,
+       &tegra_pcie,
+       &tegra_afi,
+       &tegra_se,
+};
+
+#define CLK_DUPLICATE(_name, _dev, _con)       \
+       {                                       \
+               .name   = _name,                \
+               .lookup = {                     \
+                       .dev_id = _dev,         \
+                       .con_id = _con,         \
+               },                              \
+       }
+
+/* Some clocks may be used by different drivers depending on the board
+ * configuration.  List those here to register them twice in the clock lookup
+ * table under two names.
+ */
+struct clk_duplicate tegra_clk_duplicates[] = {
+       CLK_DUPLICATE("uarta",  "serial8250.0", NULL),
+       CLK_DUPLICATE("uartb",  "serial8250.1", NULL),
+       CLK_DUPLICATE("uartc",  "serial8250.2", NULL),
+       CLK_DUPLICATE("uartd",  "serial8250.3", NULL),
+       CLK_DUPLICATE("uarte",  "serial8250.4", NULL),
+       CLK_DUPLICATE("usbd", "utmip-pad", NULL),
+       CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
+       CLK_DUPLICATE("usbd", "tegra-otg", NULL),
+       CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
+       CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
+       CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
+       CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
+       CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
+       CLK_DUPLICATE("bsev", "nvavp", "bsev"),
+       CLK_DUPLICATE("vde", "tegra-aes", "vde"),
+       CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
+       CLK_DUPLICATE("bsea", "nvavp", "bsea"),
+       CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
+       CLK_DUPLICATE("cml0", "tegra_pcie", "cml"),
+       CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"),
+       CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL),
+       CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL),
+       CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL),
+       CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL),
+       CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL),
+       CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL),
+       CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL),
+       CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL),
+       CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL),
+       CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL),
+       CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
+       CLK_DUPLICATE("twd", "smp_twd", NULL),
+       CLK_DUPLICATE("vcp", "nvavp", "vcp"),
+       CLK_DUPLICATE("i2s0", NULL, "i2s0"),
+       CLK_DUPLICATE("i2s1", NULL, "i2s1"),
+       CLK_DUPLICATE("i2s2", NULL, "i2s2"),
+       CLK_DUPLICATE("i2s3", NULL, "i2s3"),
+       CLK_DUPLICATE("i2s4", NULL, "i2s4"),
+       CLK_DUPLICATE("dam0", NULL, "dam0"),
+       CLK_DUPLICATE("dam1", NULL, "dam1"),
+       CLK_DUPLICATE("dam2", NULL, "dam2"),
+       CLK_DUPLICATE("spdif_in", NULL, "spdif_in"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.0", "fast-clk"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"),
+       CLK_DUPLICATE("pll_p_out3", "tegra-i2c.4", "fast-clk"),
+};
+
+struct clk *tegra_ptr_clks[] = {
+       &tegra_clk_32k,
+       &tegra_clk_m,
+       &tegra_clk_m_div2,
+       &tegra_clk_m_div4,
+       &tegra_pll_ref,
+       &tegra_pll_m,
+       &tegra_pll_m_out1,
+       &tegra_pll_c,
+       &tegra_pll_c_out1,
+       &tegra_pll_p,
+       &tegra_pll_p_out1,
+       &tegra_pll_p_out2,
+       &tegra_pll_p_out3,
+       &tegra_pll_p_out4,
+       &tegra_pll_a,
+       &tegra_pll_a_out0,
+       &tegra_pll_d,
+       &tegra_pll_d_out0,
+       &tegra_pll_d2,
+       &tegra_pll_d2_out0,
+       &tegra_pll_u,
+       &tegra_pll_x,
+       &tegra_pll_x_out0,
+       &tegra_pll_e,
+       &tegra_clk_cclk_g,
+       &tegra_cml0,
+       &tegra_cml1,
+       &tegra_pciex,
+       &tegra_clk_sclk,
+       &tegra_clk_blink,
+       &tegra30_clk_twd,
+};
+
+static void tegra30_init_one_clock(struct clk *c)
+{
+       struct clk_tegra *clk = to_clk_tegra(c->hw);
+       __clk_init(NULL, c);
+       INIT_LIST_HEAD(&clk->shared_bus_list);
+       if (!clk->lookup.dev_id && !clk->lookup.con_id)
+               clk->lookup.con_id = c->name;
+       clk->lookup.clk = c;
+       clkdev_add(&clk->lookup);
+       tegra_clk_add(c);
+}
+
+void __init tegra30_init_clocks(void)
+{
+       int i;
+       struct clk *c;
+
+       for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
+               tegra30_init_one_clock(tegra_ptr_clks[i]);
+
+       for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
+               tegra30_init_one_clock(tegra_list_clks[i]);
+
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
+               c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
+               if (!c) {
+                       pr_err("%s: Unknown duplicate clock %s\n", __func__,
+                               tegra_clk_duplicates[i].name);
+                       continue;
+               }
+
+               tegra_clk_duplicates[i].lookup.clk = c;
+               clkdev_add(&tegra_clk_duplicates[i].lookup);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++)
+               tegra30_init_one_clock(tegra_sync_source_list[i]);
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++)
+               tegra30_init_one_clock(tegra_clk_audio_list[i]);
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++)
+               tegra30_init_one_clock(tegra_clk_audio_2x_list[i]);
+
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++)
+               tegra30_init_one_clock(tegra_clk_out_list[i]);
+}
index c013bbf79cac0d0eff64edfd5221d7815bb04879..53d3d46dec1290b4265a3c3c26d7ffc0449f223e 100644 (file)
@@ -41,7 +41,6 @@ config MACH_HREFV60
 config MACH_SNOWBALL
        bool "U8500 Snowball platform"
        select MACH_MOP500
-       select LEDS_GPIO
        help
          Include support for the snowball development platform.
 
index 996048038743f777e114ff6a48bc2bb682271a46..df15646036aacd9bec713b7beebb926dafa707fa 100644 (file)
@@ -191,9 +191,9 @@ static struct platform_device *db8500_add_msp_i2s(struct device *parent,
        return pdev;
 }
 
-/* Platform device for ASoC U8500 machine */
-static struct platform_device snd_soc_u8500 = {
-               .name = "snd-soc-u8500",
+/* Platform device for ASoC MOP500 machine */
+static struct platform_device snd_soc_mop500 = {
+               .name = "snd-soc-mop500",
                .id = 0,
                .dev = {
                        .platform_data = NULL,
@@ -227,8 +227,8 @@ int mop500_msp_init(struct device *parent)
 {
        struct platform_device *msp1;
 
-       pr_info("%s: Register platform-device 'snd-soc-u8500'.\n", __func__);
-       platform_device_register(&snd_soc_u8500);
+       pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__);
+       platform_device_register(&snd_soc_mop500);
 
        pr_info("Initialize MSP I2S-devices.\n");
        db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0,
index 8674a890fd1c7071ae2efce55a3a7c888a97c091..a534d8880de12e2a92b0c7a35ec1ebdc3034c44e 100644 (file)
@@ -797,6 +797,7 @@ static void __init u8500_init_machine(void)
                                ARRAY_SIZE(mop500_platform_devs));
 
                mop500_sdi_init(parent);
+               mop500_msp_init(parent);
                i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
                i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
                i2c_register_board_info(2, mop500_i2c2_devices,
@@ -804,6 +805,8 @@ static void __init u8500_init_machine(void)
 
                mop500_uib_init();
 
+       } else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
+               mop500_msp_init(parent);
        } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) {
                /*
                 * The HREFv60 board removed a GPIO expander and routed
@@ -815,6 +818,7 @@ static void __init u8500_init_machine(void)
                                ARRAY_SIZE(mop500_platform_devs));
 
                hrefv60_sdi_init(parent);
+               mop500_msp_init(parent);
 
                i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
                i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES;
index c2cdf6500f75dc5a1ab5a688ea305099e8d30057..4e7d1182e8a3a59270073b5cb3b348e0bd690ef8 100644 (file)
@@ -358,7 +358,7 @@ void __init dma_contiguous_remap(void)
                if (end > arm_lowmem_limit)
                        end = arm_lowmem_limit;
                if (start >= end)
-                       return;
+                       continue;
 
                map.pfn = __phys_to_pfn(start);
                map.virtual = __phys_to_virt(start);
@@ -423,7 +423,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page)
        unsigned int pageno;
        unsigned long flags;
        void *ptr = NULL;
-       size_t align;
+       unsigned long align_mask;
 
        if (!pool->vaddr) {
                WARN(1, "coherent pool not initialised!\n");
@@ -435,11 +435,11 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page)
         * small, so align them to their order in pages, minimum is a page
         * size. This helps reduce fragmentation of the DMA space.
         */
-       align = PAGE_SIZE << get_order(size);
+       align_mask = (1 << get_order(size)) - 1;
 
        spin_lock_irqsave(&pool->lock, flags);
        pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages,
-                                           0, count, (1 << align) - 1);
+                                           0, count, align_mask);
        if (pageno < pool->nr_pages) {
                bitmap_set(pool->bitmap, pageno, count);
                ptr = pool->vaddr + PAGE_SIZE * pageno;
@@ -648,12 +648,12 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
 
        if (arch_is_coherent() || nommu()) {
                __dma_free_buffer(page, size);
+       } else if (__free_from_pool(cpu_addr, size)) {
+               return;
        } else if (!IS_ENABLED(CONFIG_CMA)) {
                __dma_free_remap(cpu_addr, size);
                __dma_free_buffer(page, size);
        } else {
-               if (__free_from_pool(cpu_addr, size))
-                       return;
                /*
                 * Non-atomic allocations cannot be freed with IRQs disabled
                 */
index 77458548e031fe73d75a5a79ea36f923c95cc88a..40ca11ed6e5fbae9c54914db0123bf136e788481 100644 (file)
@@ -231,8 +231,6 @@ void __sync_icache_dcache(pte_t pteval)
        struct page *page;
        struct address_space *mapping;
 
-       if (!pte_present_user(pteval))
-               return;
        if (cache_is_vipt_nonaliasing() && !pte_exec(pteval))
                /* only flush non-aliasing VIPT caches for exec mappings */
                return;
index c2021139cb563fd14a74c327d453f3cf0cee183d..ea94765acf9a3650f5cb850f6990893f3ccb459b 100644 (file)
@@ -38,10 +38,10 @@ ENTRY(v7wbi_flush_user_tlb_range)
        dsb
        mov     r0, r0, lsr #PAGE_SHIFT         @ align address
        mov     r1, r1, lsr #PAGE_SHIFT
-#ifdef CONFIG_ARM_ERRATA_720789
-       mov     r3, #0
-#else
        asid    r3, r3                          @ mask ASID
+#ifdef CONFIG_ARM_ERRATA_720789
+       ALT_SMP(W(mov)  r3, #0  )
+       ALT_UP(W(nop)           )
 #endif
        orr     r0, r3, r0, lsl #PAGE_SHIFT     @ Create initial MVA
        mov     r1, r1, lsl #PAGE_SHIFT
index 626ad8cad7a9486d71408f611b4f99b46c85b995..938b50a33439b092202de715e81267b18b5f73cb 100644 (file)
@@ -189,6 +189,7 @@ struct omap_dm_timer *omap_dm_timer_request(void)
                timer->reserved = 1;
                break;
        }
+       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (timer) {
                ret = omap_dm_timer_prepare(timer);
@@ -197,7 +198,6 @@ struct omap_dm_timer *omap_dm_timer_request(void)
                        timer = NULL;
                }
        }
-       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (!timer)
                pr_debug("%s: timer request failed!\n", __func__);
@@ -220,6 +220,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
                        break;
                }
        }
+       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (timer) {
                ret = omap_dm_timer_prepare(timer);
@@ -228,7 +229,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
                        timer = NULL;
                }
        }
-       spin_unlock_irqrestore(&dm_timer_lock, flags);
 
        if (!timer)
                pr_debug("%s: timer%d request failed!\n", __func__, id);
@@ -258,7 +258,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
 
 void omap_dm_timer_disable(struct omap_dm_timer *timer)
 {
-       pm_runtime_put(&timer->pdev->dev);
+       pm_runtime_put_sync(&timer->pdev->dev);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
 
index 68b180edcfffd0e05c9256aaa153993500177f84..bb5d08a70dbc64ac961945669655e2c47d380750 100644 (file)
@@ -372,7 +372,8 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define cpu_class_is_omap1()   (cpu_is_omap7xx() || cpu_is_omap15xx() || \
                                cpu_is_omap16xx())
 #define cpu_class_is_omap2()   (cpu_is_omap24xx() || cpu_is_omap34xx() || \
-                               cpu_is_omap44xx() || soc_is_omap54xx())
+                               cpu_is_omap44xx() || soc_is_omap54xx() || \
+                               soc_is_am33xx())
 
 /* Various silicon revisions for omap2 */
 #define OMAP242X_CLASS         0x24200024
index 045e320f1067408abc1ef08e6a3667fe911c63f7..324d31b14852e632d614635e40af358d24a36aab 100644 (file)
 # endif
 #endif
 
+#ifdef CONFIG_SOC_AM33XX
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME am33xx
+# endif
+#endif
+
 #endif /* __PLAT_OMAP_MULTI_H */
index b8d19a136781e4ba89382cc151ba6fe0190ccbc3..7f7b112acccb897b90066a6b8357a943284c3a14 100644 (file)
@@ -110,7 +110,7 @@ static inline void flush(void)
        _DEBUG_LL_ENTRY(mach, AM33XX_UART##p##_BASE, OMAP_PORT_SHIFT,   \
                AM33XXUART##p)
 
-static inline void __arch_decomp_setup(unsigned long arch_id)
+static inline void arch_decomp_setup(void)
 {
        int port = 0;
 
@@ -198,8 +198,6 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
        } while (0);
 }
 
-#define arch_decomp_setup()    __arch_decomp_setup(arch_id)
-
 /*
  * nothing to do
  */
index d245a87dc014d4c6cf3d1c9a3285add47a56ecb5..b8b747a9d360110e9ca24b505f5249a730209e3e 100644 (file)
@@ -291,10 +291,12 @@ static struct platform_device orion_ge00 = {
 void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
                            unsigned long mapbase,
                            unsigned long irq,
-                           unsigned long irq_err)
+                           unsigned long irq_err,
+                           unsigned int tx_csum_limit)
 {
        fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
                       mapbase + 0x2000, SZ_16K - 1, irq_err);
+       orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;
        ge_complete(&orion_ge00_shared_data,
                    orion_ge00_resources, irq, &orion_ge00_shared,
                    eth_data, &orion_ge00);
@@ -343,10 +345,12 @@ static struct platform_device orion_ge01 = {
 void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
                            unsigned long mapbase,
                            unsigned long irq,
-                           unsigned long irq_err)
+                           unsigned long irq_err,
+                           unsigned int tx_csum_limit)
 {
        fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
                       mapbase + 0x2000, SZ_16K - 1, irq_err);
+       orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;
        ge_complete(&orion_ge01_shared_data,
                    orion_ge01_resources, irq, &orion_ge01_shared,
                    eth_data, &orion_ge01);
index e00fdb2136090154ea930c9f224365677644444e..ae2377ef63e5d9c455e07a4c8db7590f8935d4dc 100644 (file)
@@ -39,12 +39,14 @@ void __init orion_rtc_init(unsigned long mapbase,
 void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
                            unsigned long mapbase,
                            unsigned long irq,
-                           unsigned long irq_err);
+                           unsigned long irq_err,
+                           unsigned int tx_csum_limit);
 
 void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
                            unsigned long mapbase,
                            unsigned long irq,
-                           unsigned long irq_err);
+                           unsigned long irq_err,
+                           unsigned int tx_csum_limit);
 
 void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
                            unsigned long mapbase,
index 28f898f75380a8ff39036805afdc5b5d40803df8..db98e7021f0daf7507fe55f91f1e73ef761a6dc3 100644 (file)
@@ -430,7 +430,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
  * when necessary.
 */
 
-int s3c2410_dma_enqueue(unsigned int channel, void *id,
+int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
                        dma_addr_t data, int size)
 {
        struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
index 7aca31c1df1fe57ac91b4278b13ad8036a8dac93..9c3b90c3538e3b71bb1e71c8c8bf817ca5057a89 100644 (file)
@@ -403,7 +403,8 @@ config S5P_DEV_USB_EHCI
 
 config S3C24XX_PWM
        bool "PWM device support"
-       select HAVE_PWM
+       select PWM
+       select PWM_SAMSUNG
        help
          Support for exporting the PWM timer blocks via the pwm device
          system
index 74e31ce355388bd7c2062b35fb30e09ca085b3f5..fc49f3dabd7653624b7f9ccc8e78ef12b102d527 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/platform_data/s3c-hsudc.h>
 #include <linux/platform_data/s3c-hsotg.h>
 
+#include <media/s5p_hdmi.h>
+
 #include <asm/irq.h>
 #include <asm/pmu.h>
 #include <asm/mach/arch.h>
@@ -748,7 +750,8 @@ void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)
        if (!pd) {
                pd = &default_i2c_data;
 
-               if (soc_is_exynos4210())
+               if (soc_is_exynos4210() ||
+                   soc_is_exynos4212() || soc_is_exynos4412())
                        pd->bus_num = 8;
                else if (soc_is_s5pv210())
                        pd->bus_num = 3;
@@ -759,6 +762,30 @@ void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)
        npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
                               &s5p_device_i2c_hdmiphy);
 }
+
+struct s5p_hdmi_platform_data s5p_hdmi_def_platdata;
+
+void __init s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info,
+                                 struct i2c_board_info *mhl_info, int mhl_bus)
+{
+       struct s5p_hdmi_platform_data *pd = &s5p_hdmi_def_platdata;
+
+       if (soc_is_exynos4210() ||
+           soc_is_exynos4212() || soc_is_exynos4412())
+               pd->hdmiphy_bus = 8;
+       else if (soc_is_s5pv210())
+               pd->hdmiphy_bus = 3;
+       else
+               pd->hdmiphy_bus = 0;
+
+       pd->hdmiphy_info = hdmiphy_info;
+       pd->mhl_info = mhl_info;
+       pd->mhl_bus = mhl_bus;
+
+       s3c_set_platdata(pd, sizeof(struct s5p_hdmi_platform_data),
+                        &s5p_device_hdmi);
+}
+
 #endif /* CONFIG_S5P_DEV_I2C_HDMIPHY */
 
 /* I2S */
diff --git a/arch/arm/plat-samsung/include/plat/hdmi.h b/arch/arm/plat-samsung/include/plat/hdmi.h
new file mode 100644 (file)
index 0000000..331d046
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *
+ * 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.
+ */
+
+#ifndef __PLAT_SAMSUNG_HDMI_H
+#define __PLAT_SAMSUNG_HDMI_H __FILE__
+
+extern void s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info,
+                                 struct i2c_board_info *mhl_info, int mhl_bus);
+
+#endif /* __PLAT_SAMSUNG_HDMI_H */
index 64ab65f0fdbc652cd1e0f165ec13bf5a61cc6377..15070284343ee43070c7130d3f8ce6bff6a0b4ff 100644 (file)
@@ -74,7 +74,7 @@ unsigned char pm_uart_udivslot;
 
 #ifdef CONFIG_SAMSUNG_PM_DEBUG
 
-struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
+static struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
 
 static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
 {
index fb849d044bde9b231d481201c985f84cc37c0a3d..c834b32af275d73d4cd760efeb4a365e940f1df7 100644 (file)
@@ -719,8 +719,10 @@ static int __init vfp_init(void)
                        if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
                                elf_hwcap |= HWCAP_NEON;
 #endif
+#ifdef CONFIG_VFPv3
                        if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
                                elf_hwcap |= HWCAP_VFPv4;
+#endif
                }
        }
        return 0;
index ada8f0fc71e4731fc9bb619aacc7a77df50d7d54..fb96e607adcf815890de6ce475c55a3cfd76a42b 100644 (file)
@@ -52,7 +52,6 @@ EXPORT_SYMBOL(reserved_mem_dcache_on);
 #ifdef CONFIG_MTD_UCLINUX
 extern struct map_info uclinux_ram_map;
 unsigned long memory_mtd_end, memory_mtd_start, mtd_size;
-unsigned long _ebss;
 EXPORT_SYMBOL(memory_mtd_end);
 EXPORT_SYMBOL(memory_mtd_start);
 EXPORT_SYMBOL(mtd_size);
index 052f81a762398670188778a0645c8ed9ad1a4982..983c859e40b7b57e5eb1da68094524b7fe1c1301 100644 (file)
@@ -6,6 +6,7 @@
 config C6X
        def_bool y
        select CLKDEV_LOOKUP
+       select GENERIC_ATOMIC64
        select GENERIC_IRQ_SHOW
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DMA_API_DEBUG
index 6d521d96d94136e25cd83158a5706a1c6681a84f..09c5a0f5f4d1778156a5ee83715e6a2aec7f0441 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Port on Texas Instruments TMS320C6x architecture
  *
- *  Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated
+ *  Copyright (C) 2005, 2006, 2009, 2010, 2012 Texas Instruments Incorporated
  *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
  *
  *  This program is free software; you can redistribute it and/or modify
 /*
  * Cache line size
  */
-#define L1D_CACHE_BYTES   64
-#define L1P_CACHE_BYTES   32
-#define L2_CACHE_BYTES   128
+#define L1D_CACHE_SHIFT   6
+#define L1D_CACHE_BYTES   (1 << L1D_CACHE_SHIFT)
+
+#define L1P_CACHE_SHIFT   5
+#define L1P_CACHE_BYTES   (1 << L1P_CACHE_SHIFT)
+
+#define L2_CACHE_SHIFT    7
+#define L2_CACHE_BYTES    (1 << L2_CACHE_SHIFT)
 
 /*
  * L2 used as cache
@@ -29,7 +34,8 @@
  * For practical reasons the L1_CACHE_BYTES defines should not be smaller than
  * the L2 line size
  */
-#define L1_CACHE_BYTES        L2_CACHE_BYTES
+#define L1_CACHE_SHIFT        L2_CACHE_SHIFT
+#define L1_CACHE_BYTES        (1 << L1_CACHE_SHIFT)
 
 #define L2_CACHE_ALIGN_LOW(x) \
        (((x) & ~(L2_CACHE_BYTES - 1)))
index 954d81e2e837648d80a67fb9648dad29dd6f39c4..7913695b2fcbe5605830b9e1da6441188a591b8b 100644 (file)
@@ -234,5 +234,4 @@ CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRC_T10DIF=y
-CONFIG_MISC_DEVICES=y
 CONFIG_INTEL_IOMMU=y
index 91c41ecfa6d9e0fad551ef268cab3f01200af2d8..f8e91336542392236c878276ad8abcef4d786166 100644 (file)
@@ -209,4 +209,3 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_CRYPTO_MD5=y
-CONFIG_MISC_DEVICES=y
index 6f38b6120d96bc841f4563c1fe3202ae7a78b7f3..440578850ae52bad9df8961aeec12d52f9a94ceb 100644 (file)
@@ -497,7 +497,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
        srat_num_cpus++;
 }
 
-void __init
+int __init
 acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
 {
        unsigned long paddr, size;
@@ -512,7 +512,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
 
        /* Ignore disabled entries */
        if (!(ma->flags & ACPI_SRAT_MEM_ENABLED))
-               return;
+               return -1;
 
        /* record this node in proximity bitmap */
        pxm_bit_set(pxm);
@@ -531,6 +531,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
        p->size = size;
        p->nid = pxm;
        num_node_memblks++;
+       return 0;
 }
 
 void __init acpi_numa_arch_fixup(void)
index 0b0f8b8c4a266571d33fcd61900161d7961d8cea..b22df9410dceb75169f4127bb897befb6f4960ad 100644 (file)
@@ -5,6 +5,7 @@ config M68K
        select HAVE_AOUT if MMU
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_SHOW
+       select GENERIC_ATOMIC64
        select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
        select GENERIC_CPU_DEVICES
        select GENERIC_STRNCPY_FROM_USER if MMU
@@ -54,18 +55,6 @@ config ZONE_DMA
        bool
        default y
 
-config CPU_HAS_NO_BITFIELDS
-       bool
-
-config CPU_HAS_NO_MULDIV64
-       bool
-
-config CPU_HAS_ADDRESS_SPACES
-       bool
-
-config FPU
-       bool
-
 config HZ
        int
        default 1000 if CLEOPATRA
index 43a9f8f1b8eb43d41049051358b08667684cc6f0..c4eb79edecec04d58d5ad681c389118a3472cec5 100644 (file)
@@ -28,6 +28,7 @@ config COLDFIRE
        select CPU_HAS_NO_BITFIELDS
        select CPU_HAS_NO_MULDIV64
        select GENERIC_CSUM
+       select HAVE_CLK
 
 endchoice
 
@@ -37,6 +38,7 @@ config M68000
        bool
        select CPU_HAS_NO_BITFIELDS
        select CPU_HAS_NO_MULDIV64
+       select CPU_HAS_NO_UNALIGNED
        select GENERIC_CSUM
        help
          The Freescale (was Motorola) 68000 CPU is the first generation of
@@ -48,6 +50,7 @@ config M68000
 config MCPU32
        bool
        select CPU_HAS_NO_BITFIELDS
+       select CPU_HAS_NO_UNALIGNED
        help
          The Freescale (was then Motorola) CPU32 is a CPU core that is
          based on the 68020 processor. For the most part it is used in
@@ -56,7 +59,6 @@ config MCPU32
 config M68020
        bool "68020 support"
        depends on MMU
-       select GENERIC_ATOMIC64
        select CPU_HAS_ADDRESS_SPACES
        help
          If you anticipate running this kernel on a computer with a MC68020
@@ -67,7 +69,6 @@ config M68020
 config M68030
        bool "68030 support"
        depends on MMU && !MMU_SUN3
-       select GENERIC_ATOMIC64
        select CPU_HAS_ADDRESS_SPACES
        help
          If you anticipate running this kernel on a computer with a MC68030
@@ -77,7 +78,6 @@ config M68030
 config M68040
        bool "68040 support"
        depends on MMU && !MMU_SUN3
-       select GENERIC_ATOMIC64
        select CPU_HAS_ADDRESS_SPACES
        help
          If you anticipate running this kernel on a computer with a MC68LC040
@@ -88,7 +88,6 @@ config M68040
 config M68060
        bool "68060 support"
        depends on MMU && !MMU_SUN3
-       select GENERIC_ATOMIC64
        select CPU_HAS_ADDRESS_SPACES
        help
          If you anticipate running this kernel on a computer with a MC68060
@@ -376,6 +375,18 @@ config NODES_SHIFT
        default "3"
        depends on !SINGLE_MEMORY_CHUNK
 
+config CPU_HAS_NO_BITFIELDS
+       bool
+
+config CPU_HAS_NO_MULDIV64
+       bool
+
+config CPU_HAS_NO_UNALIGNED
+       bool
+
+config CPU_HAS_ADDRESS_SPACES
+       bool
+
 config FPU
        bool
 
index 0a30406b9442a4961b8f40fbc2832e0cc2079889..f5565d6eeb8e9bbe24b9ef1df22dea0310f9c4ee 100644 (file)
@@ -177,8 +177,8 @@ irqreturn_t dn_timer_int(int irq, void *dev_id)
 
        timer_handler(irq, dev_id);
 
-       x=*(volatile unsigned char *)(timer+3);
-       x=*(volatile unsigned char *)(timer+5);
+       x = *(volatile unsigned char *)(apollo_timer + 3);
+       x = *(volatile unsigned char *)(apollo_timer + 5);
 
        return IRQ_HANDLED;
 }
@@ -186,17 +186,17 @@ irqreturn_t dn_timer_int(int irq, void *dev_id)
 void dn_sched_init(irq_handler_t timer_routine)
 {
        /* program timer 1 */
-       *(volatile unsigned char *)(timer+3)=0x01;
-       *(volatile unsigned char *)(timer+1)=0x40;
-       *(volatile unsigned char *)(timer+5)=0x09;
-       *(volatile unsigned char *)(timer+7)=0xc4;
+       *(volatile unsigned char *)(apollo_timer + 3) = 0x01;
+       *(volatile unsigned char *)(apollo_timer + 1) = 0x40;
+       *(volatile unsigned char *)(apollo_timer + 5) = 0x09;
+       *(volatile unsigned char *)(apollo_timer + 7) = 0xc4;
 
        /* enable IRQ of PIC B */
        *(volatile unsigned char *)(pica+1)&=(~8);
 
 #if 0
-       printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3));
-       printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3));
+       printk("*(0x10803) %02x\n",*(volatile unsigned char *)(apollo_timer + 0x3));
+       printk("*(0x10803) %02x\n",*(volatile unsigned char *)(apollo_timer + 0x3));
 #endif
 
        if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine))
index eafa2539a8ee79dbcc65ea929ab082c767d93029..a74e5d95c384941583d99096bae1175634c9b4cb 100644 (file)
@@ -1,4 +1,29 @@
 include include/asm-generic/Kbuild.asm
 header-y += cachectl.h
 
+generic-y += bitsperlong.h
+generic-y += cputime.h
+generic-y += device.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += futex.h
+generic-y += ioctl.h
+generic-y += ipcbuf.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += kvm_para.h
+generic-y += local64.h
+generic-y += local.h
+generic-y += mman.h
+generic-y += mutex.h
+generic-y += percpu.h
+generic-y += resource.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += siginfo.h
+generic-y += statfs.h
+generic-y += topology.h
+generic-y += types.h
 generic-y += word-at-a-time.h
+generic-y += xor.h
diff --git a/arch/m68k/include/asm/MC68332.h b/arch/m68k/include/asm/MC68332.h
deleted file mode 100644 (file)
index 6bb8f02..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-
-/* include/asm-m68knommu/MC68332.h: '332 control registers
- *
- * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
- *
- */
-
-#ifndef _MC68332_H_
-#define _MC68332_H_
-
-#define BYTE_REF(addr) (*((volatile unsigned char*)addr))
-#define WORD_REF(addr) (*((volatile unsigned short*)addr))
-
-#define PORTE_ADDR     0xfffa11
-#define PORTE  BYTE_REF(PORTE_ADDR)
-#define DDRE_ADDR      0xfffa15
-#define DDRE   BYTE_REF(DDRE_ADDR)
-#define PEPAR_ADDR     0xfffa17
-#define PEPAR  BYTE_REF(PEPAR_ADDR)
-
-#define PORTF_ADDR     0xfffa19
-#define PORTF  BYTE_REF(PORTF_ADDR)
-#define DDRF_ADDR      0xfffa1d
-#define DDRF   BYTE_REF(DDRF_ADDR)
-#define PFPAR_ADDR     0xfffa1f
-#define PFPAR  BYTE_REF(PFPAR_ADDR)
-
-#define PORTQS_ADDR    0xfffc15
-#define PORTQS BYTE_REF(PORTQS_ADDR)
-#define DDRQS_ADDR     0xfffc17
-#define DDRQS  BYTE_REF(DDRQS_ADDR)
-#define PQSPAR_ADDR    0xfffc16
-#define PQSPAR BYTE_REF(PQSPAR_ADDR)
-
-#define CSPAR0_ADDR 0xFFFA44
-#define CSPAR0 WORD_REF(CSPAR0_ADDR)
-#define CSPAR1_ADDR 0xFFFA46
-#define CSPAR1 WORD_REF(CSPAR1_ADDR)
-#define CSARBT_ADDR 0xFFFA48
-#define CSARBT WORD_REF(CSARBT_ADDR)
-#define CSOPBT_ADDR 0xFFFA4A
-#define CSOPBT WORD_REF(CSOPBT_ADDR)
-#define CSBAR0_ADDR 0xFFFA4C
-#define CSBAR0 WORD_REF(CSBAR0_ADDR)
-#define CSOR0_ADDR 0xFFFA4E
-#define CSOR0 WORD_REF(CSOR0_ADDR)
-#define CSBAR1_ADDR 0xFFFA50
-#define CSBAR1 WORD_REF(CSBAR1_ADDR)
-#define CSOR1_ADDR 0xFFFA52
-#define CSOR1 WORD_REF(CSOR1_ADDR)
-#define CSBAR2_ADDR 0xFFFA54
-#define CSBAR2 WORD_REF(CSBAR2_ADDR)
-#define CSOR2_ADDR 0xFFFA56
-#define CSOR2 WORD_REF(CSOR2_ADDR)
-#define CSBAR3_ADDR 0xFFFA58
-#define CSBAR3 WORD_REF(CSBAR3_ADDR)
-#define CSOR3_ADDR 0xFFFA5A
-#define CSOR3 WORD_REF(CSOR3_ADDR)
-#define CSBAR4_ADDR 0xFFFA5C
-#define CSBAR4 WORD_REF(CSBAR4_ADDR)
-#define CSOR4_ADDR 0xFFFA5E
-#define CSOR4 WORD_REF(CSOR4_ADDR)
-#define CSBAR5_ADDR 0xFFFA60
-#define CSBAR5 WORD_REF(CSBAR5_ADDR)
-#define CSOR5_ADDR 0xFFFA62
-#define CSOR5 WORD_REF(CSOR5_ADDR)
-#define CSBAR6_ADDR 0xFFFA64
-#define CSBAR6 WORD_REF(CSBAR6_ADDR)
-#define CSOR6_ADDR 0xFFFA66
-#define CSOR6 WORD_REF(CSOR6_ADDR)
-#define CSBAR7_ADDR 0xFFFA68
-#define CSBAR7 WORD_REF(CSBAR7_ADDR)
-#define CSOR7_ADDR 0xFFFA6A
-#define CSOR7 WORD_REF(CSOR7_ADDR)
-#define CSBAR8_ADDR 0xFFFA6C
-#define CSBAR8 WORD_REF(CSBAR8_ADDR)
-#define CSOR8_ADDR 0xFFFA6E
-#define CSOR8 WORD_REF(CSOR8_ADDR)
-#define CSBAR9_ADDR 0xFFFA70
-#define CSBAR9 WORD_REF(CSBAR9_ADDR)
-#define CSOR9_ADDR 0xFFFA72
-#define CSOR9 WORD_REF(CSOR9_ADDR)
-#define CSBAR10_ADDR 0xFFFA74
-#define CSBAR10 WORD_REF(CSBAR10_ADDR)
-#define CSOR10_ADDR 0xFFFA76
-#define CSOR10 WORD_REF(CSOR10_ADDR)
-
-#define CSOR_MODE_ASYNC        0x0000
-#define CSOR_MODE_SYNC 0x8000
-#define CSOR_MODE_MASK 0x8000
-#define CSOR_BYTE_DISABLE      0x0000
-#define CSOR_BYTE_UPPER                0x4000
-#define CSOR_BYTE_LOWER                0x2000
-#define CSOR_BYTE_BOTH         0x6000
-#define CSOR_BYTE_MASK         0x6000
-#define CSOR_RW_RSVD           0x0000
-#define CSOR_RW_READ           0x0800
-#define CSOR_RW_WRITE          0x1000
-#define CSOR_RW_BOTH           0x1800
-#define CSOR_RW_MASK           0x1800
-#define CSOR_STROBE_DS         0x0400
-#define CSOR_STROBE_AS         0x0000
-#define CSOR_STROBE_MASK       0x0400
-#define CSOR_DSACK_WAIT(x)     (wait << 6)
-#define CSOR_DSACK_FTERM       (14 << 6)
-#define CSOR_DSACK_EXTERNAL    (15 << 6)
-#define CSOR_DSACK_MASK                0x03c0
-#define CSOR_SPACE_CPU         0x0000
-#define CSOR_SPACE_USER                0x0010
-#define CSOR_SPACE_SU          0x0020
-#define CSOR_SPACE_BOTH                0x0030
-#define CSOR_SPACE_MASK                0x0030
-#define CSOR_IPL_ALL           0x0000
-#define CSOR_IPL_PRIORITY(x)   (x << 1)
-#define CSOR_IPL_MASK          0x000e
-#define CSOR_AVEC_ON           0x0001
-#define CSOR_AVEC_OFF          0x0000
-#define CSOR_AVEC_MASK         0x0001
-
-#define CSBAR_ADDR(x)          ((addr >> 11) << 3) 
-#define CSBAR_ADDR_MASK                0xfff8
-#define CSBAR_BLKSIZE_2K       0x0000
-#define CSBAR_BLKSIZE_8K       0x0001
-#define CSBAR_BLKSIZE_16K      0x0002
-#define CSBAR_BLKSIZE_64K      0x0003
-#define CSBAR_BLKSIZE_128K     0x0004
-#define CSBAR_BLKSIZE_256K     0x0005
-#define CSBAR_BLKSIZE_512K     0x0006
-#define CSBAR_BLKSIZE_1M       0x0007
-#define CSBAR_BLKSIZE_MASK     0x0007
-
-#define CSPAR_DISC     0
-#define CSPAR_ALT      1
-#define CSPAR_CS8      2
-#define CSPAR_CS16     3
-#define CSPAR_MASK     3
-
-#define CSPAR0_CSBOOT(x) (x << 0)
-#define CSPAR0_CS0(x)  (x << 2)
-#define CSPAR0_CS1(x)  (x << 4)
-#define CSPAR0_CS2(x)  (x << 6)
-#define CSPAR0_CS3(x)  (x << 8)
-#define CSPAR0_CS4(x)  (x << 10)
-#define CSPAR0_CS5(x)  (x << 12)
-
-#define CSPAR1_CS6(x)  (x << 0)
-#define CSPAR1_CS7(x)  (x << 2)
-#define CSPAR1_CS8(x)  (x << 4)
-#define CSPAR1_CS9(x)  (x << 6)
-#define CSPAR1_CS10(x) (x << 8)
-
-#endif
diff --git a/arch/m68k/include/asm/apollodma.h b/arch/m68k/include/asm/apollodma.h
deleted file mode 100644 (file)
index 954adc8..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
- * Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen
- * and John Boyd, Nov. 1992.
- */
-
-#ifndef _ASM_APOLLO_DMA_H
-#define _ASM_APOLLO_DMA_H
-
-#include <asm/apollohw.h>              /* need byte IO */
-#include <linux/spinlock.h>            /* And spinlocks */
-#include <linux/delay.h>
-
-
-#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val))
-#define dma_inb(addr)     (*((volatile unsigned char *)(addr+IO_BASE)))
-
-/*
- * NOTES about DMA transfers:
- *
- *  controller 1: channels 0-3, byte operations, ports 00-1F
- *  controller 2: channels 4-7, word operations, ports C0-DF
- *
- *  - ALL registers are 8 bits only, regardless of transfer size
- *  - channel 4 is not used - cascades 1 into 2.
- *  - channels 0-3 are byte - addresses/counts are for physical bytes
- *  - channels 5-7 are word - addresses/counts are for physical words
- *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
- *  - transfer count loaded to registers is 1 less than actual count
- *  - controller 2 offsets are all even (2x offsets for controller 1)
- *  - page registers for 5-7 don't use data bit 0, represent 128K pages
- *  - page registers for 0-3 use bit 0, represent 64K pages
- *
- * DMA transfers are limited to the lower 16MB of _physical_ memory.
- * Note that addresses loaded into registers must be _physical_ addresses,
- * not logical addresses (which may differ if paging is active).
- *
- *  Address mapping for channels 0-3:
- *
- *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
- *    |  ...  |   |  ... |   |  ... |
- *    |  ...  |   |  ... |   |  ... |
- *    |  ...  |   |  ... |   |  ... |
- *   P7  ...  P0  A7 ... A0  A7 ... A0
- * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
- *
- *  Address mapping for channels 5-7:
- *
- *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
- *    |  ...  |   \   \   ... \  \  \  ... \  \
- *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
- *    |  ...  |     \   \   ... \  \  \  ... \
- *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0
- * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
- *
- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
- * the hardware level, so odd-byte transfers aren't possible).
- *
- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
- * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
- * and up to 128K bytes may be transferred on channels 5-7 in one operation.
- *
- */
-
-#define MAX_DMA_CHANNELS       8
-
-/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x1000000)
-
-/* 8237 DMA controllers */
-#define IO_DMA1_BASE   0x10C00 /* 8 bit slave DMA, channels 0..3 */
-#define IO_DMA2_BASE   0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */
-
-/* DMA controller registers */
-#define DMA1_CMD_REG           (IO_DMA1_BASE+0x08) /* command register (w) */
-#define DMA1_STAT_REG          (IO_DMA1_BASE+0x08) /* status register (r) */
-#define DMA1_REQ_REG            (IO_DMA1_BASE+0x09) /* request register (w) */
-#define DMA1_MASK_REG          (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */
-#define DMA1_MODE_REG          (IO_DMA1_BASE+0x0B) /* mode register (w) */
-#define DMA1_CLEAR_FF_REG      (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */
-#define DMA1_TEMP_REG           (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */
-#define DMA1_RESET_REG         (IO_DMA1_BASE+0x0D) /* Master Clear (w) */
-#define DMA1_CLR_MASK_REG       (IO_DMA1_BASE+0x0E) /* Clear Mask */
-#define DMA1_MASK_ALL_REG       (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */
-
-#define DMA2_CMD_REG           (IO_DMA2_BASE+0x10) /* command register (w) */
-#define DMA2_STAT_REG          (IO_DMA2_BASE+0x10) /* status register (r) */
-#define DMA2_REQ_REG            (IO_DMA2_BASE+0x12) /* request register (w) */
-#define DMA2_MASK_REG          (IO_DMA2_BASE+0x14) /* single-channel mask (w) */
-#define DMA2_MODE_REG          (IO_DMA2_BASE+0x16) /* mode register (w) */
-#define DMA2_CLEAR_FF_REG      (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */
-#define DMA2_TEMP_REG           (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */
-#define DMA2_RESET_REG         (IO_DMA2_BASE+0x1A) /* Master Clear (w) */
-#define DMA2_CLR_MASK_REG       (IO_DMA2_BASE+0x1C) /* Clear Mask */
-#define DMA2_MASK_ALL_REG       (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */
-
-#define DMA_ADDR_0              (IO_DMA1_BASE+0x00) /* DMA address registers */
-#define DMA_ADDR_1              (IO_DMA1_BASE+0x02)
-#define DMA_ADDR_2              (IO_DMA1_BASE+0x04)
-#define DMA_ADDR_3              (IO_DMA1_BASE+0x06)
-#define DMA_ADDR_4              (IO_DMA2_BASE+0x00)
-#define DMA_ADDR_5              (IO_DMA2_BASE+0x04)
-#define DMA_ADDR_6              (IO_DMA2_BASE+0x08)
-#define DMA_ADDR_7              (IO_DMA2_BASE+0x0C)
-
-#define DMA_CNT_0               (IO_DMA1_BASE+0x01)   /* DMA count registers */
-#define DMA_CNT_1               (IO_DMA1_BASE+0x03)
-#define DMA_CNT_2               (IO_DMA1_BASE+0x05)
-#define DMA_CNT_3               (IO_DMA1_BASE+0x07)
-#define DMA_CNT_4               (IO_DMA2_BASE+0x02)
-#define DMA_CNT_5               (IO_DMA2_BASE+0x06)
-#define DMA_CNT_6               (IO_DMA2_BASE+0x0A)
-#define DMA_CNT_7               (IO_DMA2_BASE+0x0E)
-
-#define DMA_MODE_READ  0x44    /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE 0x48    /* memory to I/O, no autoinit, increment, single mode */
-#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
-
-#define DMA_AUTOINIT   0x10
-
-#define DMA_8BIT 0
-#define DMA_16BIT 1
-#define DMA_BUSMASTER 2
-
-extern spinlock_t  dma_spin_lock;
-
-static __inline__ unsigned long claim_dma_lock(void)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&dma_spin_lock, flags);
-       return flags;
-}
-
-static __inline__ void release_dma_lock(unsigned long flags)
-{
-       spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
-       if (dmanr<=3)
-               dma_outb(dmanr,  DMA1_MASK_REG);
-       else
-               dma_outb(dmanr & 3,  DMA2_MASK_REG);
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
-       if (dmanr<=3)
-               dma_outb(dmanr | 4,  DMA1_MASK_REG);
-       else
-               dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
-}
-
-/* Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while holding the DMA lock ! ---
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-       if (dmanr<=3)
-               dma_outb(0,  DMA1_CLEAR_FF_REG);
-       else
-               dma_outb(0,  DMA2_CLEAR_FF_REG);
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-       if (dmanr<=3)
-               dma_outb(mode | dmanr,  DMA1_MODE_REG);
-       else
-               dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
-}
-
-/* Set transfer address & page bits for specific DMA channel.
- * Assumes dma flipflop is clear.
- */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
-       if (dmanr <= 3)  {
-           dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
-            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
-       }  else  {
-           dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
-           dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
-       }
-}
-
-
-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
- * a specific DMA channel.
- * You must ensure the parameters are valid.
- * NOTE: from a manual: "the number of transfers is one more
- * than the initial word count"! This is taken into account.
- * Assumes dma flip-flop is clear.
- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-        count--;
-       if (dmanr <= 3)  {
-           dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
-           dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
-        } else {
-           dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
-           dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
-        }
-}
-
-
-/* Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * If called before the channel has been used, it may return 1.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- *
- * Assumes DMA flip-flop is clear.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
-       unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
-                                        : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
-
-       /* using short to get 16-bit wrap around */
-       unsigned short count;
-
-       count = 1 + dma_inb(io_port);
-       count += dma_inb(io_port) << 8;
-
-       return (dmanr<=3)? count : (count<<1);
-}
-
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char * device_id);    /* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);      /* release it again */
-
-/* These are in arch/m68k/apollo/dma.c: */
-extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type);
-extern void dma_unmap_page(unsigned short dma_addr);
-
-#endif /* _ASM_APOLLO_DMA_H */
index a1373b9aa2811535728a5e95c07fdd827b6099b1..635ef4f890102b187ef86710ceb341c5af91bdb5 100644 (file)
@@ -98,7 +98,7 @@ extern u_long timer_physaddr;
 #define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr))
 #define pica (IO_BASE + pica_physaddr)
 #define picb (IO_BASE + picb_physaddr)
-#define timer (IO_BASE + timer_physaddr)
+#define apollo_timer (IO_BASE + timer_physaddr)
 #define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000))
 
 #define isaIO2mem(x) (((((x) & 0x3f8)  << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE)
diff --git a/arch/m68k/include/asm/bitsperlong.h b/arch/m68k/include/asm/bitsperlong.h
deleted file mode 100644 (file)
index 6dc0bb0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/bitsperlong.h>
diff --git a/arch/m68k/include/asm/cputime.h b/arch/m68k/include/asm/cputime.h
deleted file mode 100644 (file)
index c79c5e8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __M68K_CPUTIME_H
-#define __M68K_CPUTIME_H
-
-#include <asm-generic/cputime.h>
-
-#endif /* __M68K_CPUTIME_H */
index 9c09becfd4c97fa96c249288f8ef3056832e8f4e..12d8fe4f1d30b5e6fe0f86b191b05bd2b0307251 100644 (file)
@@ -43,7 +43,7 @@ static inline void __delay(unsigned long loops)
 extern void __bad_udelay(void);
 
 
-#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
+#ifdef CONFIG_CPU_HAS_NO_MULDIV64
 /*
  * The simpler m68k and ColdFire processors do not have a 32*32->64
  * multiply instruction. So we need to handle them a little differently.
diff --git a/arch/m68k/include/asm/device.h b/arch/m68k/include/asm/device.h
deleted file mode 100644 (file)
index d8f9872..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * Arch specific extensions to struct device
- *
- * This file is released under the GPLv2
- */
-#include <asm-generic/device.h>
-
diff --git a/arch/m68k/include/asm/emergency-restart.h b/arch/m68k/include/asm/emergency-restart.h
deleted file mode 100644 (file)
index 108d8c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
-
-#include <asm-generic/emergency-restart.h>
-
-#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/m68k/include/asm/errno.h b/arch/m68k/include/asm/errno.h
deleted file mode 100644 (file)
index 0d4e188..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_ERRNO_H
-#define _M68K_ERRNO_H
-
-#include <asm-generic/errno.h>
-
-#endif /* _M68K_ERRNO_H */
diff --git a/arch/m68k/include/asm/futex.h b/arch/m68k/include/asm/futex.h
deleted file mode 100644 (file)
index 6a332a9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
-
-#include <asm-generic/futex.h>
-
-#endif
diff --git a/arch/m68k/include/asm/ioctl.h b/arch/m68k/include/asm/ioctl.h
deleted file mode 100644 (file)
index b279fe0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ioctl.h>
diff --git a/arch/m68k/include/asm/ipcbuf.h b/arch/m68k/include/asm/ipcbuf.h
deleted file mode 100644 (file)
index 84c7e51..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipcbuf.h>
diff --git a/arch/m68k/include/asm/irq_regs.h b/arch/m68k/include/asm/irq_regs.h
deleted file mode 100644 (file)
index 3dd9c0b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/irq_regs.h>
diff --git a/arch/m68k/include/asm/kdebug.h b/arch/m68k/include/asm/kdebug.h
deleted file mode 100644 (file)
index 6ece1b0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kdebug.h>
diff --git a/arch/m68k/include/asm/kmap_types.h b/arch/m68k/include/asm/kmap_types.h
deleted file mode 100644 (file)
index 3413cc1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-#include <asm-generic/kmap_types.h>
-
-#endif /* __ASM_M68K_KMAP_TYPES_H */
diff --git a/arch/m68k/include/asm/kvm_para.h b/arch/m68k/include/asm/kvm_para.h
deleted file mode 100644 (file)
index 14fab8f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kvm_para.h>
diff --git a/arch/m68k/include/asm/local.h b/arch/m68k/include/asm/local.h
deleted file mode 100644 (file)
index 6c25926..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_M68K_LOCAL_H
-#define _ASM_M68K_LOCAL_H
-
-#include <asm-generic/local.h>
-
-#endif /* _ASM_M68K_LOCAL_H */
diff --git a/arch/m68k/include/asm/local64.h b/arch/m68k/include/asm/local64.h
deleted file mode 100644 (file)
index 36c93b5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/local64.h>
diff --git a/arch/m68k/include/asm/mac_mouse.h b/arch/m68k/include/asm/mac_mouse.h
deleted file mode 100644 (file)
index 39a5c29..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _ASM_MAC_MOUSE_H
-#define _ASM_MAC_MOUSE_H
-
-/*
- * linux/include/asm-m68k/mac_mouse.h
- * header file for Macintosh ADB mouse driver
- * 27-10-97 Michael Schmitz
- * copied from:
- * header file for Atari Mouse driver
- * by Robert de Vries (robert@and.nl) on 19Jul93
- */
-
-struct mouse_status {
-       char            buttons;
-       short           dx;
-       short           dy;
-       int             ready;
-       int             active;
-       wait_queue_head_t wait;
-       struct fasync_struct *fasyncptr;
-};
-
-#endif
diff --git a/arch/m68k/include/asm/mcfmbus.h b/arch/m68k/include/asm/mcfmbus.h
deleted file mode 100644 (file)
index 319899c..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************/
-
-/*
- *      mcfmbus.h -- Coldfire MBUS support defines.
- *
- *      (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de) 
- */
-
-/****************************************************************************/
-
-
-#ifndef mcfmbus_h
-#define mcfmbus_h
-
-
-#define MCFMBUS_BASE           0x280
-#define MCFMBUS_IRQ_VECTOR     0x19
-#define MCFMBUS_IRQ            0x1
-#define MCFMBUS_CLK            0x3f
-#define MCFMBUS_IRQ_LEVEL      0x07    /*IRQ Level 1*/
-#define MCFMBUS_ADDRESS                0x01
-
-
-/*
-*      Define the 5307 MBUS register set addresses
-*/
-
-#define MCFMBUS_MADR   0x00
-#define MCFMBUS_MFDR   0x04
-#define MCFMBUS_MBCR   0x08
-#define MCFMBUS_MBSR   0x0C
-#define MCFMBUS_MBDR   0x10
-
-
-#define MCFMBUS_MADR_ADDR(a)   (((a)&0x7F)<<0x01) /*Slave Address*/
-
-#define MCFMBUS_MFDR_MBC(a)    ((a)&0x3F)         /*M-Bus Clock*/
-
-/*
-*      Define bit flags in Control Register
-*/
-
-#define MCFMBUS_MBCR_MEN           (0x80)  /* M-Bus Enable                 */
-#define MCFMBUS_MBCR_MIEN          (0x40)  /* M-Bus Interrupt Enable       */
-#define MCFMBUS_MBCR_MSTA          (0x20)  /* Master/Slave Mode Select Bit */
-#define MCFMBUS_MBCR_MTX           (0x10)  /* Transmit/Rcv Mode Select Bit */
-#define MCFMBUS_MBCR_TXAK          (0x08)  /* Transmit Acknowledge Enable  */
-#define MCFMBUS_MBCR_RSTA          (0x04)  /* Repeat Start                 */
-
-/*
-*      Define bit flags in Status Register
-*/
-
-#define MCFMBUS_MBSR_MCF           (0x80)  /* Data Transfer Complete       */
-#define MCFMBUS_MBSR_MAAS          (0x40)  /* Addressed as a Slave         */
-#define MCFMBUS_MBSR_MBB           (0x20)  /* Bus Busy                     */
-#define MCFMBUS_MBSR_MAL           (0x10)  /* Arbitration Lost             */
-#define MCFMBUS_MBSR_SRW           (0x04)  /* Slave Transmit               */
-#define MCFMBUS_MBSR_MIF           (0x02)  /* M-Bus Interrupt              */
-#define MCFMBUS_MBSR_RXAK          (0x01)  /* No Acknowledge Received      */
-
-/*
-*      Define bit flags in DATA I/O Register
-*/
-
-#define MCFMBUS_MBDR_READ          (0x01)  /* 1=read 0=write MBUS */
-
-#define MBUSIOCSCLOCK          1
-#define MBUSIOCGCLOCK          2
-#define MBUSIOCSADDR                   3
-#define MBUSIOCGADDR                   4
-#define MBUSIOCSSLADDR                 5
-#define MBUSIOCGSLADDR                 6
-#define MBUSIOCSSUBADDR                        7
-#define MBUSIOCGSUBADDR                        8
-
-#endif
diff --git a/arch/m68k/include/asm/mman.h b/arch/m68k/include/asm/mman.h
deleted file mode 100644 (file)
index 8eebf89..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/mman.h>
diff --git a/arch/m68k/include/asm/mutex.h b/arch/m68k/include/asm/mutex.h
deleted file mode 100644 (file)
index 458c1f7..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Pull in the generic implementation for the mutex fastpath.
- *
- * TODO: implement optimized primitives instead, or leave the generic
- * implementation in place, or pick the atomic_xchg() based generic
- * implementation. (see asm-generic/mutex-xchg.h for details)
- */
-
-#include <asm-generic/mutex-dec.h>
diff --git a/arch/m68k/include/asm/percpu.h b/arch/m68k/include/asm/percpu.h
deleted file mode 100644 (file)
index 0859d04..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_M68K_PERCPU_H
-#define __ASM_M68K_PERCPU_H
-
-#include <asm-generic/percpu.h>
-
-#endif /* __ASM_M68K_PERCPU_H */
diff --git a/arch/m68k/include/asm/resource.h b/arch/m68k/include/asm/resource.h
deleted file mode 100644 (file)
index e7d3501..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_RESOURCE_H
-#define _M68K_RESOURCE_H
-
-#include <asm-generic/resource.h>
-
-#endif /* _M68K_RESOURCE_H */
diff --git a/arch/m68k/include/asm/sbus.h b/arch/m68k/include/asm/sbus.h
deleted file mode 100644 (file)
index bfe3ba1..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * some sbus structures and macros to make usage of sbus drivers possible
- */
-
-#ifndef __M68K_SBUS_H
-#define __M68K_SBUS_H
-
-struct sbus_dev {
-       struct {
-               unsigned int which_io;
-               unsigned int phys_addr;
-       } reg_addrs[1];
-};
-
-/* sbus IO functions stolen from include/asm-sparc/io.h for the serial driver */
-/* No SBUS on the Sun3, kludge -- sam */
-
-static inline void _sbus_writeb(unsigned char val, unsigned long addr)
-{
-       *(volatile unsigned char *)addr = val;
-}
-
-static inline unsigned char _sbus_readb(unsigned long addr)
-{
-       return *(volatile unsigned char *)addr;
-}
-
-static inline void _sbus_writel(unsigned long val, unsigned long addr)
-{
-       *(volatile unsigned long *)addr = val;
-
-}
-
-extern inline unsigned long _sbus_readl(unsigned long addr)
-{
-       return *(volatile unsigned long *)addr;
-}
-
-
-#define sbus_readb(a) _sbus_readb((unsigned long)a)
-#define sbus_writeb(v, a) _sbus_writeb(v, (unsigned long)a)
-#define sbus_readl(a) _sbus_readl((unsigned long)a)
-#define sbus_writel(v, a) _sbus_writel(v, (unsigned long)a)
-
-#endif
diff --git a/arch/m68k/include/asm/scatterlist.h b/arch/m68k/include/asm/scatterlist.h
deleted file mode 100644 (file)
index 3125054..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_SCATTERLIST_H
-#define _M68K_SCATTERLIST_H
-
-#include <asm-generic/scatterlist.h>
-
-#endif /* !(_M68K_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/sections.h b/arch/m68k/include/asm/sections.h
deleted file mode 100644 (file)
index 5277e52..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _ASM_M68K_SECTIONS_H
-#define _ASM_M68K_SECTIONS_H
-
-#include <asm-generic/sections.h>
-
-extern char _sbss[], _ebss[];
-
-#endif /* _ASM_M68K_SECTIONS_H */
diff --git a/arch/m68k/include/asm/shm.h b/arch/m68k/include/asm/shm.h
deleted file mode 100644 (file)
index fa56ec8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _M68K_SHM_H
-#define _M68K_SHM_H
-
-
-/* format of page table entries that correspond to shared memory pages
-   currently out in swap space (see also mm/swap.c):
-   bits 0-1 (PAGE_PRESENT) is  = 0
-   bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE
-   bits 31..9 are used like this:
-   bits 15..9 (SHM_ID) the id of the shared memory segment
-   bits 30..16 (SHM_IDX) the index of the page within the shared memory segment
-                    (actually only bits 25..16 get used since SHMMAX is so low)
-   bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach
-*/
-/* on the m68k both bits 0 and 1 must be zero */
-/* format on the sun3 is similar, but bits 30, 31 are set to zero and all
-   others are reduced by 2. --m */
-
-#ifndef CONFIG_SUN3
-#define SHM_ID_SHIFT   9
-#else
-#define SHM_ID_SHIFT   7
-#endif
-#define _SHM_ID_BITS   7
-#define SHM_ID_MASK    ((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT  (SHM_ID_SHIFT+_SHM_ID_BITS)
-#define _SHM_IDX_BITS  15
-#define SHM_IDX_MASK   ((1<<_SHM_IDX_BITS)-1)
-
-#endif /* _M68K_SHM_H */
diff --git a/arch/m68k/include/asm/siginfo.h b/arch/m68k/include/asm/siginfo.h
deleted file mode 100644 (file)
index 851d3d7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_SIGINFO_H
-#define _M68K_SIGINFO_H
-
-#include <asm-generic/siginfo.h>
-
-#endif
diff --git a/arch/m68k/include/asm/statfs.h b/arch/m68k/include/asm/statfs.h
deleted file mode 100644 (file)
index 08d93f1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_STATFS_H
-#define _M68K_STATFS_H
-
-#include <asm-generic/statfs.h>
-
-#endif /* _M68K_STATFS_H */
diff --git a/arch/m68k/include/asm/topology.h b/arch/m68k/include/asm/topology.h
deleted file mode 100644 (file)
index ca173e9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_M68K_TOPOLOGY_H
-#define _ASM_M68K_TOPOLOGY_H
-
-#include <asm-generic/topology.h>
-
-#endif /* _ASM_M68K_TOPOLOGY_H */
diff --git a/arch/m68k/include/asm/types.h b/arch/m68k/include/asm/types.h
deleted file mode 100644 (file)
index 89705ad..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _M68K_TYPES_H
-#define _M68K_TYPES_H
-
-/*
- * This file is never included by application software unless
- * explicitly requested (e.g., via linux/types.h) in which case the
- * application is Linux specific so (user-) name space pollution is
- * not a major issue.  However, for interoperability, libraries still
- * need to be careful to avoid a name clashes.
- */
-#include <asm-generic/int-ll64.h>
-
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-#ifdef __KERNEL__
-
-#define BITS_PER_LONG 32
-
-#endif /* __KERNEL__ */
-
-#endif /* _M68K_TYPES_H */
index f4043ae63db1292889957f28cee8d4375d5719e3..2b3ca0bf7a0df900b6442a9611e9da857020c0dc 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_M68K_UNALIGNED_H
 
 
-#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68000)
+#ifdef CONFIG_CPU_HAS_NO_UNALIGNED
 #include <linux/unaligned/be_struct.h>
 #include <linux/unaligned/le_byteshift.h>
 #include <linux/unaligned/generic.h>
@@ -12,7 +12,7 @@
 
 #else
 /*
- * The m68k can do unaligned accesses itself. 
+ * The m68k can do unaligned accesses itself.
  */
 #include <linux/unaligned/access_ok.h>
 #include <linux/unaligned/generic.h>
diff --git a/arch/m68k/include/asm/xor.h b/arch/m68k/include/asm/xor.h
deleted file mode 100644 (file)
index c82eb12..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/xor.h>
index 7dc186b7a85fb27a098858a4106ac64d95abc1b4..71fb29938dba260b6e5895c3d7eb5f10f2afbb16 100644 (file)
@@ -218,13 +218,10 @@ void __init setup_arch(char **cmdline_p)
        printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n");
 #endif
 
-       pr_debug("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
-                "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
-                (int) &_sdata, (int) &_edata,
-                (int) &_sbss, (int) &_ebss);
-       pr_debug("MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ",
-                (int) &_ebss, (int) memory_start,
-                (int) memory_start, (int) memory_end);
+       pr_debug("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n",
+                _stext, _etext, _sdata, _edata, __bss_start, __bss_stop);
+       pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n ",
+                __bss_stop, memory_start, memory_start, memory_end);
 
        /* Keep a copy of command line */
        *cmdline_p = &command_line[0];
index 8623f8dc16f8a03c9da88910537ae93fc47bc510..9a5932ec368946bf808c5faf527cbf39731b5540 100644 (file)
@@ -479,9 +479,13 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
                        goto bad_access;
                }
 
-               mem_value = *mem;
+               /*
+                * No need to check for EFAULT; we know that the page is
+                * present and writable.
+                */
+               __get_user(mem_value, mem);
                if (mem_value == oldval)
-                       *mem = newval;
+                       __put_user(newval, mem);
 
                pte_unmap_unlock(pte, ptl);
                up_read(&mm->mmap_sem);
index 40e02d9c38b4df4bac25bf659d44885dd99f9fa8..06a763f49fd34643d5330221a48011be00889b0e 100644 (file)
@@ -78,9 +78,7 @@ SECTIONS {
                __init_end = .;
        }
 
-       _sbss = .;
        BSS_SECTION(0, 0, 0)
-       _ebss = .;
 
        _end = .;
 
index 63407c836826842a9dc2648c84fb3c50ba5c4f79..d0993594f558b3408317aede57c634c407ea580f 100644 (file)
@@ -31,9 +31,7 @@ SECTIONS
 
   RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
 
-  _sbss = .;
   BSS_SECTION(0, 0, 0)
-  _ebss = .;
 
   _edata = .;                  /* End of data section */
 
index ad0f46d64c0b66a8d6b6cf4f82ffeaeeabbda084..8080469ee6c11c3e86ab59febaa4773790a2ffc7 100644 (file)
@@ -44,9 +44,7 @@ __init_begin = .;
        . = ALIGN(PAGE_SIZE);
        __init_end = .;
 
-  _sbss = .;
   BSS_SECTION(0, 0, 0)
-  _ebss = .;
 
   _end = . ;
 
index 79e928a525d078169e0617270e1fcea9da08b5f2..ee5f0b1b5c5dd9b86c78552f42e4e7e9210a74cb 100644 (file)
@@ -19,7 +19,7 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
+#ifdef CONFIG_CPU_HAS_NO_MULDIV64
 
 #define SI_TYPE_SIZE 32
 #define __BITS4 (SI_TYPE_SIZE / 4)
index f77f258dce3aca67fbfbc2e02ba33718c918903f..282f9de68966ee20409af3e4d2244af716323ca8 100644 (file)
@@ -104,7 +104,7 @@ void __init print_memmap(void)
                MLK_ROUNDUP(__init_begin, __init_end),
                MLK_ROUNDUP(_stext, _etext),
                MLK_ROUNDUP(_sdata, _edata),
-               MLK_ROUNDUP(_sbss, _ebss));
+               MLK_ROUNDUP(__bss_start, __bss_stop));
 }
 
 void __init mem_init(void)
index 345ec0d83e3d4ab825ff89afd0f4b022f0c67246..688e3664aea072ef2e2ee951b9991db2ab7abb78 100644 (file)
@@ -91,7 +91,7 @@ void __init mem_init(void)
        totalram_pages = free_all_bootmem();
 
        codek = (_etext - _stext) >> 10;
-       datak = (_ebss - _sdata) >> 10;
+       datak = (__bss_stop - _sdata) >> 10;
        initk = (__init_begin - __init_end) >> 10;
 
        tmp = nr_free_pages() << PAGE_SHIFT;
index f632fdcb93e913b218b7e5a7743d089ac0f8172f..537d3245b539a9c7006dfc7abc03b1f9f4f5ff04 100644 (file)
@@ -60,8 +60,8 @@ _start:
  *     Move ROM filesystem above bss :-)
  */
 
-       moveal  #_sbss, %a0                     /* romfs at the start of bss */
-       moveal  #_ebss, %a1                     /* Set up destination  */
+       moveal  #__bss_start, %a0               /* romfs at the start of bss */
+       moveal  #__bss_stop, %a1                /* Set up destination  */
        movel   %a0, %a2                        /* Copy of bss start */
 
        movel   8(%a0), %d1                     /* Get size of ROMFS */
@@ -84,8 +84,8 @@ _start:
  * Initialize BSS segment to 0
  */
 
-       lea     _sbss, %a0
-       lea     _ebss, %a1
+       lea     __bss_start, %a0
+       lea     __bss_stop, %a1
 
        /* Copy 0 to %a0 until %a0 == %a1 */
 2:     cmpal   %a0, %a1
index 2ebfd642081855acb3af3e35dac9066ed886038c..45a9dad29e3d3948ba0f52dadd2d54cae7b4a31a 100644 (file)
@@ -110,7 +110,7 @@ L0:
        movel   #CONFIG_VECTORBASE, %d7
        addl    #16, %d7
        moveal  %d7, %a0
-       moveal  #_ebss, %a1
+       moveal  #__bss_stop, %a1
        lea     %a1@(512), %a2
 
        DBG_PUTC('C')
@@ -138,8 +138,8 @@ LD1:
 
        DBG_PUTC('E')
 
-       moveal  #_sbss, %a0
-       moveal  #_ebss, %a1
+       moveal  #__bss_start, %a0
+       moveal  #__bss_stop, %a1
 
        /* Copy 0 to %a0 until %a0 == %a1 */
 L1:
@@ -150,7 +150,7 @@ L1:
        DBG_PUTC('F')
 
        /* Copy command line from end of bss to command line */
-       moveal  #_ebss, %a0
+       moveal  #__bss_stop, %a0
        moveal  #command_line, %a1
        lea     %a1@(512), %a2
 
@@ -165,7 +165,7 @@ L3:
 
        movel   #_sdata, %d0    
        movel   %d0, _rambase   
-       movel   #_ebss, %d0
+       movel   #__bss_stop, %d0
        movel   %d0, _ramstart
 
        movel   %a4, %d0
index 7f1aeeacb219a7525f3b142f4e27fefa5cb99ba5..5189ef9260986c31e0baaafec7ba770846ae118f 100644 (file)
@@ -76,8 +76,8 @@ pclp3:
        beq     pclp3
 #endif /* DEBUG */
        moveal  #0x007ffff0, %ssp
-       moveal  #_sbss, %a0
-       moveal  #_ebss, %a1
+       moveal  #__bss_start, %a0
+       moveal  #__bss_stop, %a1
 
        /* Copy 0 to %a0 until %a0 >= %a1 */
 L1:
index a5ff96d0295f069e28ded27ace22a5d1296e6cff..3dff98ba2e97df254743af9eebb5b297d539e548 100644 (file)
@@ -59,8 +59,8 @@ _stext:       movew   #0x2700,%sr
        cmpal   %a1, %a2
        bhi     1b
 
-       moveal  #_sbss, %a0
-       moveal  #_ebss, %a1
+       moveal  #__bss_start, %a0
+       moveal  #__bss_stop, %a1
        /* Copy 0 to %a0 until %a0 == %a1 */
        
 1:
@@ -70,7 +70,7 @@ _stext:       movew   #0x2700,%sr
 
         movel   #_sdata, %d0    
         movel   %d0, _rambase        
-        movel   #_ebss, %d0
+        movel   #__bss_stop, %d0
         movel   %d0, _ramstart
        movel   #RAMEND-CONFIG_MEMORY_RESERVE*0x100000, %d0
        movel   %d0, _ramend
index 8eb94fb6b971a3c35867f558096af9a6f7cd6b0e..acd213170d80fe6ae1e74cddd2fcbd90c7b65115 100644 (file)
@@ -219,8 +219,8 @@ LD1:
        cmp.l   #_edata, %a1
        blt     LD1
 
-       moveal  #_sbss, %a0
-       moveal  #_ebss, %a1
+       moveal  #__bss_start, %a0
+       moveal  #__bss_stop, %a1
 
        /* Copy 0 to %a0 until %a0 == %a1 */
 L1:
@@ -234,7 +234,7 @@ load_quicc:
 store_ram_size:
        /* Set ram size information */
        move.l  #_sdata, _rambase
-       move.l  #_ebss, _ramstart
+       move.l  #__bss_stop, _ramstart
        move.l  #RAMEND, %d0
        sub.l   #0x1000, %d0                    /* Reserve 4K for stack space.*/
        move.l  %d0, _ramend                    /* Different from RAMEND.*/
index 97510e55b802a587ad547c9f36005540ae2c8fc5..dfc756d998861823e48ac2b87a291ea7d04cbbb2 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 .global _stext
-.global _sbss
+.global __bss_start
 .global _start
 
 .global _rambase
@@ -229,8 +229,8 @@ LD1:
        cmp.l   #_edata, %a1
        blt     LD1
 
-       moveal  #_sbss, %a0
-       moveal  #_ebss, %a1
+       moveal  #__bss_start, %a0
+       moveal  #__bss_stop, %a1
 
        /* Copy 0 to %a0 until %a0 == %a1 */
 L1:
@@ -244,7 +244,7 @@ load_quicc:
 store_ram_size:
        /* Set ram size information */
        move.l  #_sdata, _rambase
-       move.l  #_ebss, _ramstart
+       move.l  #__bss_stop, _ramstart
        move.l  #RAMEND, %d0
        sub.l   #0x1000, %d0                    /* Reserve 4K for stack space.*/
        move.l  %d0, _ramend                    /* Different from RAMEND.*/
index 4e0c9eb3bd1f437df4d8c469f58070b3558e8f5a..b88f5716f357b7acecc2e38a2f1bed8676ced43e 100644 (file)
@@ -230,8 +230,8 @@ _vstart:
        /*
         *      Move ROM filesystem above bss :-)
         */
-       lea     _sbss,%a0                       /* get start of bss */
-       lea     _ebss,%a1                       /* set up destination  */
+       lea     __bss_start,%a0                 /* get start of bss */
+       lea     __bss_stop,%a1                  /* set up destination  */
        movel   %a0,%a2                         /* copy of bss start */
 
        movel   8(%a0),%d0                      /* get size of ROMFS */
@@ -249,7 +249,7 @@ _copy_romfs:
        bne     _copy_romfs
 
 #else /* CONFIG_ROMFS_FS */
-       lea     _ebss,%a1
+       lea     __bss_stop,%a1
        movel   %a1,_ramstart
 #endif /* CONFIG_ROMFS_FS */
 
@@ -257,8 +257,8 @@ _copy_romfs:
        /*
         *      Zero out the bss region.
         */
-       lea     _sbss,%a0                       /* get start of bss */
-       lea     _ebss,%a1                       /* get end of bss */
+       lea     __bss_start,%a0                 /* get start of bss */
+       lea     __bss_stop,%a1                  /* get end of bss */
        clrl    %d0                             /* set value */
 _clear_bss:
        movel   %d0,(%a0)+                      /* clear each word */
index d8e6349336b4f54e9f03d26ebfc095821f1da30a..eeba067d565f4470937da6a40a61dcaf8caaae18 100644 (file)
@@ -22,57 +22,13 @@ int prom_root_node;
 struct linux_nodeops *prom_nodeops;
 
 /* You must call prom_init() before you attempt to use any of the
- * routines in the prom library.  It returns 0 on success, 1 on
- * failure.  It gets passed the pointer to the PROM vector.
+ * routines in the prom library.
+ * It gets passed the pointer to the PROM vector.
  */
 
-extern void prom_meminit(void);
-extern void prom_ranges_init(void);
-
 void __init prom_init(struct linux_romvec *rp)
 {
        romvec = rp;
-#ifndef CONFIG_SUN3
-       switch(romvec->pv_romvers) {
-       case 0:
-               prom_vers = PROM_V0;
-               break;
-       case 2:
-               prom_vers = PROM_V2;
-               break;
-       case 3:
-               prom_vers = PROM_V3;
-               break;
-       case 4:
-               prom_vers = PROM_P1275;
-               prom_printf("PROMLIB: Sun IEEE Prom not supported yet\n");
-               prom_halt();
-               break;
-       default:
-               prom_printf("PROMLIB: Bad PROM version %d\n",
-                           romvec->pv_romvers);
-               prom_halt();
-               break;
-       };
-
-       prom_rev = romvec->pv_plugin_revision;
-       prom_prev = romvec->pv_printrev;
-       prom_nodeops = romvec->pv_nodeops;
-
-       prom_root_node = prom_getsibling(0);
-       if((prom_root_node == 0) || (prom_root_node == -1))
-               prom_halt();
-
-       if((((unsigned long) prom_nodeops) == 0) ||
-          (((unsigned long) prom_nodeops) == -1))
-               prom_halt();
-
-       prom_meminit();
-
-       prom_ranges_init();
-#endif
-//     printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n",
-//            romvec->pv_romvers, prom_rev);
 
        /* Initialization successful. */
        return;
index 4487e150b4555d2815417551cbdafc200234bb5a..c07ed5d2a82034f11cbadc6e836d4e31761d380f 100644 (file)
@@ -18,10 +18,6 @@ extern char _ssbss[], _esbss[];
 extern unsigned long __ivt_start[], __ivt_end[];
 extern char _etext[], _stext[];
 
-#  ifdef CONFIG_MTD_UCLINUX
-extern char *_ebss;
-#  endif
-
 extern u32 _fdt_start[], _fdt_end[];
 
 # endif /* !__ASSEMBLY__ */
index bb4907c828dcb4c64ba4f3f291af06046c86c8a7..2b25bcf05c0022e44bdd46eff061f0782b309c7d 100644 (file)
@@ -21,9 +21,6 @@
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
 
-extern char *_ebss;
-EXPORT_SYMBOL_GPL(_ebss);
-
 #ifdef CONFIG_FUNCTION_TRACER
 extern void _mcount(void);
 EXPORT_SYMBOL(_mcount);
index 16d8dfd9094b1a0df25eaa48799576449a8b234b..4da971d4392f6fc79c4fa2040c87cd0c224c46fc 100644 (file)
@@ -121,7 +121,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
 
        /* Move ROMFS out of BSS before clearing it */
        if (romfs_size > 0) {
-               memmove(&_ebss, (int *)romfs_base, romfs_size);
+               memmove(&__bss_stop, (int *)romfs_base, romfs_size);
                klimit += romfs_size;
        }
 #endif
@@ -165,7 +165,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
        BUG_ON(romfs_size < 0); /* What else can we do? */
 
        printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
-                       romfs_size, romfs_base, (unsigned)&_ebss);
+                       romfs_size, romfs_base, (unsigned)&__bss_stop);
 
        printk("New klimit: 0x%08x\n", (unsigned)klimit);
 #endif
index 109e9d86ade4e46051f25c1d375eac1cd9f83224..936d01a689d74157f3a63e53eff1de725fa67f9d 100644 (file)
@@ -131,7 +131,6 @@ SECTIONS {
                        *(COMMON)
                . = ALIGN (4) ;
                __bss_stop = . ;
-               _ebss = . ;
        }
        . = ALIGN(PAGE_SIZE);
        _end = .;
index 331d574df99c8d86ecdce41c9366164fac63f396..faf65286574e9f28d32d9cf31e1c097afcfc7acb 100644 (file)
@@ -89,6 +89,7 @@ config ATH79
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
+       select HAVE_CLK
        select IRQ_CPU
        select MIPS_MACHINE
        select SYS_HAS_CPU_MIPS32_R2
index 99969484c475c7fc7366d12fa50efd495656a9b9..a124c251c0c92a2bbbcc8f86ab2674aa5a8ad6a4 100644 (file)
@@ -228,6 +228,8 @@ static int mtx1_pci_idsel(unsigned int devsel, int assert)
         * adapter on the mtx-1 "singleboard" variant. It triggers a custom
         * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
         */
+       udelay(1);
+
        if (assert && devsel != 0)
                /* Suppress signal to Cardbus */
                alchemy_gpio_set_value(1, 0);   /* set EXT_IO3 OFF */
index 36e9570e7bc4a250fbbc05c6312c5b2bf53adcb5..b2a2311ec85b492d1dbbbd22df5a57db0ba978c4 100644 (file)
@@ -145,6 +145,8 @@ static void __init ar7240_usb_setup(void)
 
        ath79_ohci_resources[0].start = AR7240_OHCI_BASE;
        ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1;
+       ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB;
+       ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB;
        platform_device_register(&ath79_ohci_device);
 }
 
index 29054f211832505d371930d3e13f752af56f69f3..48fe762d2526885908c192545dbc70fa69d4cb9c 100644 (file)
@@ -188,8 +188,10 @@ void __init ath79_gpio_init(void)
 
        if (soc_is_ar71xx())
                ath79_gpio_count = AR71XX_GPIO_COUNT;
-       else if (soc_is_ar724x())
-               ath79_gpio_count = AR724X_GPIO_COUNT;
+       else if (soc_is_ar7240())
+               ath79_gpio_count = AR7240_GPIO_COUNT;
+       else if (soc_is_ar7241() || soc_is_ar7242())
+               ath79_gpio_count = AR7241_GPIO_COUNT;
        else if (soc_is_ar913x())
                ath79_gpio_count = AR913X_GPIO_COUNT;
        else if (soc_is_ar933x())
index e39f73048d4f653c48ba3b52a31976f290699bae..f1c9c3e2f678146e83772f3c7cb05a0989743fce 100644 (file)
@@ -106,11 +106,15 @@ int __init bcm63xx_spi_register(void)
        if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
                spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
                spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
+               spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT;
+               spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH;
        }
 
        if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
                spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
                spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
+               spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
+               spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH;
        }
 
        bcm63xx_spi_regs_init();
index 7fb1f222b8a538b9b000e99375899f37a0c069a9..274cd4fad30c4810f29a420e2dc1e4b139adba73 100644 (file)
@@ -61,6 +61,12 @@ static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,
        octeon_irq_ciu_to_irq[line][bit] = irq;
 }
 
+static void octeon_irq_force_ciu_mapping(struct irq_domain *domain,
+                                        int irq, int line, int bit)
+{
+       irq_domain_associate(domain, irq, line << 6 | bit);
+}
+
 static int octeon_coreid_for_cpu(int cpu)
 {
 #ifdef CONFIG_SMP
@@ -183,19 +189,9 @@ static void __init octeon_irq_init_core(void)
                mutex_init(&cd->core_irq_mutex);
 
                irq = OCTEON_IRQ_SW0 + i;
-               switch (irq) {
-               case OCTEON_IRQ_TIMER:
-               case OCTEON_IRQ_SW0:
-               case OCTEON_IRQ_SW1:
-               case OCTEON_IRQ_5:
-               case OCTEON_IRQ_PERF:
-                       irq_set_chip_data(irq, cd);
-                       irq_set_chip_and_handler(irq, &octeon_irq_chip_core,
-                                                handle_percpu_irq);
-                       break;
-               default:
-                       break;
-               }
+               irq_set_chip_data(irq, cd);
+               irq_set_chip_and_handler(irq, &octeon_irq_chip_core,
+                                        handle_percpu_irq);
        }
 }
 
@@ -890,7 +886,6 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,
        unsigned int type;
        unsigned int pin;
        unsigned int trigger;
-       struct octeon_irq_gpio_domain_data *gpiod;
 
        if (d->of_node != node)
                return -EINVAL;
@@ -925,8 +920,7 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,
                break;
        }
        *out_type = type;
-       gpiod = d->host_data;
-       *out_hwirq = gpiod->base_hwirq + pin;
+       *out_hwirq = pin;
 
        return 0;
 }
@@ -996,19 +990,21 @@ static int octeon_irq_ciu_map(struct irq_domain *d,
 static int octeon_irq_gpio_map(struct irq_domain *d,
                               unsigned int virq, irq_hw_number_t hw)
 {
-       unsigned int line = hw >> 6;
-       unsigned int bit = hw & 63;
+       struct octeon_irq_gpio_domain_data *gpiod = d->host_data;
+       unsigned int line, bit;
 
        if (!octeon_irq_virq_in_range(virq))
                return -EINVAL;
 
+       hw += gpiod->base_hwirq;
+       line = hw >> 6;
+       bit = hw & 63;
        if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)
                return -EINVAL;
 
        octeon_irq_set_ciu_mapping(virq, line, bit,
                                   octeon_irq_gpio_chip,
                                   octeon_irq_handle_gpio);
-
        return 0;
 }
 
@@ -1149,6 +1145,7 @@ static void __init octeon_irq_init_ciu(void)
        struct irq_chip *chip_wd;
        struct device_node *gpio_node;
        struct device_node *ciu_node;
+       struct irq_domain *ciu_domain = NULL;
 
        octeon_irq_init_ciu_percpu();
        octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
@@ -1177,31 +1174,6 @@ static void __init octeon_irq_init_ciu(void)
        /* Mips internal */
        octeon_irq_init_core();
 
-       /* CIU_0 */
-       for (i = 0; i < 16; i++)
-               octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
-
-       octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
-       octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
-
-       for (i = 0; i < 4; i++)
-               octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
-       for (i = 0; i < 4; i++)
-               octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
-
-       octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
-       for (i = 0; i < 4; i++)
-               octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq);
-
-       octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
-       octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
-
-       /* CIU_1 */
-       for (i = 0; i < 16; i++)
-               octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
-
-       octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
-
        gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
        if (gpio_node) {
                struct octeon_irq_gpio_domain_data *gpiod;
@@ -1219,10 +1191,35 @@ static void __init octeon_irq_init_ciu(void)
 
        ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
        if (ciu_node) {
-               irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
+               ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
                of_node_put(ciu_node);
        } else
-               pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n");
+               panic("Cannot find device node for cavium,octeon-3860-ciu.");
+
+       /* CIU_0 */
+       for (i = 0; i < 16; i++)
+               octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0);
+
+       octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
+       octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
+
+       for (i = 0; i < 4; i++)
+               octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36);
+       for (i = 0; i < 4; i++)
+               octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40);
+
+       octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46);
+       for (i = 0; i < 4; i++)
+               octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52);
+
+       octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56);
+       octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63);
+
+       /* CIU_1 */
+       for (i = 0; i < 16; i++)
+               octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
+
+       octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17);
 
        /* Enable the CIU lines */
        set_c0_status(STATUSF_IP3 | STATUSF_IP2);
index 1caa78ad06d5833306ee367cd44fbefe5dbd6fe3..dde504477fac1521e95f2fe60b75c7ac2fd8e5aa 100644 (file)
 #define AR71XX_GPIO_REG_FUNC           0x28
 
 #define AR71XX_GPIO_COUNT              16
-#define AR724X_GPIO_COUNT              18
+#define AR7240_GPIO_COUNT              18
+#define AR7241_GPIO_COUNT              20
 #define AR913X_GPIO_COUNT              22
 #define AR933X_GPIO_COUNT              30
 #define AR934X_GPIO_COUNT              23
index 4476fa03bf36d5eee19b26e1443b697eb4c33502..6ddae926bf79717b95a709d71c40a99a888a310a 100644 (file)
@@ -42,7 +42,6 @@
 #define cpu_has_mips64r1       0
 #define cpu_has_mips64r2       0
 
-#define cpu_has_dsp            0
 #define cpu_has_mipsmt         0
 
 #define cpu_has_64bits         0
index 7d98dbe5d4b5ef9de38b25717747436e08e6179e..c9bae1362606aac10d79c921f3c8b7374cfc1ba5 100644 (file)
@@ -9,6 +9,8 @@ int __init bcm63xx_spi_register(void);
 
 struct bcm63xx_spi_pdata {
        unsigned int    fifo_size;
+       unsigned int    msg_type_shift;
+       unsigned int    msg_ctl_width;
        int             bus_num;
        int             num_chipselect;
        u32             speed_hz;
index 4ccc2a748aff2db6913dab0e8b67e1eb6fbceeb8..61f2a2a5099d02ad281290c675604a4e897e9bf9 100644 (file)
 #define SPI_6338_FILL_BYTE             0x07
 #define SPI_6338_MSG_TAIL              0x09
 #define SPI_6338_RX_TAIL               0x0b
-#define SPI_6338_MSG_CTL               0x40
+#define SPI_6338_MSG_CTL               0x40    /* 8-bits register */
+#define SPI_6338_MSG_CTL_WIDTH         8
 #define SPI_6338_MSG_DATA              0x41
 #define SPI_6338_MSG_DATA_SIZE         0x3f
 #define SPI_6338_RX_DATA               0x80
 #define SPI_6348_FILL_BYTE             0x07
 #define SPI_6348_MSG_TAIL              0x09
 #define SPI_6348_RX_TAIL               0x0b
-#define SPI_6348_MSG_CTL               0x40
+#define SPI_6348_MSG_CTL               0x40    /* 8-bits register */
+#define SPI_6348_MSG_CTL_WIDTH         8
 #define SPI_6348_MSG_DATA              0x41
 #define SPI_6348_MSG_DATA_SIZE         0x3f
 #define SPI_6348_RX_DATA               0x80
 
 /* BCM 6358 SPI core */
 #define SPI_6358_MSG_CTL               0x00    /* 16-bits register */
+#define SPI_6358_MSG_CTL_WIDTH         16
 #define SPI_6358_MSG_DATA              0x02
 #define SPI_6358_MSG_DATA_SIZE         0x21e
 #define SPI_6358_RX_DATA               0x400
 
 /* BCM 6358 SPI core */
 #define SPI_6368_MSG_CTL               0x00    /* 16-bits register */
+#define SPI_6368_MSG_CTL_WIDTH         16
 #define SPI_6368_MSG_DATA              0x02
 #define SPI_6368_MSG_DATA_SIZE         0x21e
 #define SPI_6368_RX_DATA               0x400
 #define SPI_HD_W                       0x01
 #define SPI_HD_R                       0x02
 #define SPI_BYTE_CNT_SHIFT             0
-#define SPI_MSG_TYPE_SHIFT             14
+#define SPI_6338_MSG_TYPE_SHIFT                6
+#define SPI_6348_MSG_TYPE_SHIFT                6
+#define SPI_6358_MSG_TYPE_SHIFT                14
+#define SPI_6368_MSG_TYPE_SHIFT                14
 
 /* Command */
 #define SPI_CMD_NOOP                   0x00
index 418992042f6fcbc23f1612a82ee886cd969c5fa5..c22a3078bf11b69f2da21547fc1c337da7b51206 100644 (file)
@@ -21,14 +21,10 @@ enum octeon_irq {
        OCTEON_IRQ_TIMER,
 /* sources in CIU_INTX_EN0 */
        OCTEON_IRQ_WORKQ0,
-       OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16,
-       OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16,
+       OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 16,
        OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
        OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
        OCTEON_IRQ_MBOX1,
-       OCTEON_IRQ_UART0,
-       OCTEON_IRQ_UART1,
-       OCTEON_IRQ_UART2,
        OCTEON_IRQ_PCI_INT0,
        OCTEON_IRQ_PCI_INT1,
        OCTEON_IRQ_PCI_INT2,
@@ -38,8 +34,6 @@ enum octeon_irq {
        OCTEON_IRQ_PCI_MSI2,
        OCTEON_IRQ_PCI_MSI3,
 
-       OCTEON_IRQ_TWSI,
-       OCTEON_IRQ_TWSI2,
        OCTEON_IRQ_RML,
        OCTEON_IRQ_TIMER0,
        OCTEON_IRQ_TIMER1,
@@ -47,8 +41,6 @@ enum octeon_irq {
        OCTEON_IRQ_TIMER3,
        OCTEON_IRQ_USB0,
        OCTEON_IRQ_USB1,
-       OCTEON_IRQ_MII0,
-       OCTEON_IRQ_MII1,
        OCTEON_IRQ_BOOTDMA,
 #ifndef CONFIG_PCI_MSI
        OCTEON_IRQ_LAST = 127
index 7531ecd654d651df630d1d520e71f762c47547e3..dca8bce8c7abbe47473920ca6d9e28eb3c235dc9 100644 (file)
@@ -10,6 +10,7 @@ struct mod_arch_specific {
        struct list_head dbe_list;
        const struct exception_table_entry *dbe_start;
        const struct exception_table_entry *dbe_end;
+       struct mips_hi16 *r_mips_hi16_list;
 };
 
 typedef uint8_t Elf64_Byte;            /* Type for a 8-bit quantity.  */
index a37d12b3b61c0b3c2db45cc6a37f44fc4e6eac52..afe9e0e03fe96c5b7a710abe19075d9cf4a4f87b 100644 (file)
 
 #ifdef CONFIG_SYNC_R4K
 
-extern void synchronise_count_master(void);
-extern void synchronise_count_slave(void);
+extern void synchronise_count_master(int cpu);
+extern void synchronise_count_slave(int cpu);
 
 #else
 
-static inline void synchronise_count_master(void)
+static inline void synchronise_count_master(int cpu)
 {
 }
 
-static inline void synchronise_count_slave(void)
+static inline void synchronise_count_slave(int cpu)
 {
 }
 
index a5066b1c3de37185896fe529839c5133a158ccb0..4f8c3cba8c0c45180cdabe08ac05aa43e652395f 100644 (file)
@@ -39,8 +39,6 @@ struct mips_hi16 {
        Elf_Addr value;
 };
 
-static struct mips_hi16 *mips_hi16_list;
-
 static LIST_HEAD(dbe_list);
 static DEFINE_SPINLOCK(dbe_lock);
 
@@ -128,8 +126,8 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
 
        n->addr = (Elf_Addr *)location;
        n->value = v;
-       n->next = mips_hi16_list;
-       mips_hi16_list = n;
+       n->next = me->arch.r_mips_hi16_list;
+       me->arch.r_mips_hi16_list = n;
 
        return 0;
 }
@@ -142,18 +140,28 @@ static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
        return 0;
 }
 
+static void free_relocation_chain(struct mips_hi16 *l)
+{
+       struct mips_hi16 *next;
+
+       while (l) {
+               next = l->next;
+               kfree(l);
+               l = next;
+       }
+}
+
 static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
 {
        unsigned long insnlo = *location;
+       struct mips_hi16 *l;
        Elf_Addr val, vallo;
 
        /* Sign extend the addend we extract from the lo insn.  */
        vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
 
-       if (mips_hi16_list != NULL) {
-               struct mips_hi16 *l;
-
-               l = mips_hi16_list;
+       if (me->arch.r_mips_hi16_list != NULL) {
+               l = me->arch.r_mips_hi16_list;
                while (l != NULL) {
                        struct mips_hi16 *next;
                        unsigned long insn;
@@ -188,7 +196,7 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
                        l = next;
                }
 
-               mips_hi16_list = NULL;
+               me->arch.r_mips_hi16_list = NULL;
        }
 
        /*
@@ -201,6 +209,9 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
        return 0;
 
 out_danger:
+       free_relocation_chain(l);
+       me->arch.r_mips_hi16_list = NULL;
+
        pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name);
 
        return -ENOEXEC;
@@ -273,6 +284,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
        pr_debug("Applying relocate section %u to %u\n", relsec,
               sechdrs[relsec].sh_info);
 
+       me->arch.r_mips_hi16_list = NULL;
        for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
                /* This is where to make the change */
                location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
@@ -296,6 +308,19 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
                        return res;
        }
 
+       /*
+        * Normally the hi16 list should be deallocated at this point.  A
+        * malformed binary however could contain a series of R_MIPS_HI16
+        * relocations not followed by a R_MIPS_LO16 relocation.  In that
+        * case, free up the list and return an error.
+        */
+       if (me->arch.r_mips_hi16_list) {
+               free_relocation_chain(me->arch.r_mips_hi16_list);
+               me->arch.r_mips_hi16_list = NULL;
+
+               return -ENOEXEC;
+       }
+
        return 0;
 }
 
index 31637d8c87381f04b02bcae714e8b2165952fc9c..9005bf9fb859552101d7e68638adc73ba4978ee7 100644 (file)
@@ -130,7 +130,7 @@ asmlinkage __cpuinit void start_secondary(void)
 
        cpu_set(cpu, cpu_callin_map);
 
-       synchronise_count_slave();
+       synchronise_count_slave(cpu);
 
        /*
         * irq will be enabled in ->smp_finish(), enabling it too early
@@ -173,7 +173,6 @@ void smp_send_stop(void)
 void __init smp_cpus_done(unsigned int max_cpus)
 {
        mp_ops->cpus_done();
-       synchronise_count_master();
 }
 
 /* called from main before smp_init() */
@@ -206,6 +205,7 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
        while (!cpu_isset(cpu, cpu_callin_map))
                udelay(100);
 
+       synchronise_count_master(cpu);
        return 0;
 }
 
index 842d55e411fd396479b611ba0a1c0c2af2d4cb92..7f1eca3858def1845dc98dd1264206be19159b01 100644 (file)
@@ -28,12 +28,11 @@ static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0);
 #define COUNTON        100
 #define NR_LOOPS 5
 
-void __cpuinit synchronise_count_master(void)
+void __cpuinit synchronise_count_master(int cpu)
 {
        int i;
        unsigned long flags;
        unsigned int initcount;
-       int nslaves;
 
 #ifdef CONFIG_MIPS_MT_SMTC
        /*
@@ -43,8 +42,7 @@ void __cpuinit synchronise_count_master(void)
        return;
 #endif
 
-       printk(KERN_INFO "Synchronize counters across %u CPUs: ",
-              num_online_cpus());
+       printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
 
        local_irq_save(flags);
 
@@ -52,7 +50,7 @@ void __cpuinit synchronise_count_master(void)
         * Notify the slaves that it's time to start
         */
        atomic_set(&count_reference, read_c0_count());
-       atomic_set(&count_start_flag, 1);
+       atomic_set(&count_start_flag, cpu);
        smp_wmb();
 
        /* Count will be initialised to current timer for all CPU's */
@@ -69,10 +67,9 @@ void __cpuinit synchronise_count_master(void)
         * two CPUs.
         */
 
-       nslaves = num_online_cpus()-1;
        for (i = 0; i < NR_LOOPS; i++) {
-               /* slaves loop on '!= ncpus' */
-               while (atomic_read(&count_count_start) != nslaves)
+               /* slaves loop on '!= 2' */
+               while (atomic_read(&count_count_start) != 1)
                        mb();
                atomic_set(&count_count_stop, 0);
                smp_wmb();
@@ -89,7 +86,7 @@ void __cpuinit synchronise_count_master(void)
                /*
                 * Wait for all slaves to leave the synchronization point:
                 */
-               while (atomic_read(&count_count_stop) != nslaves)
+               while (atomic_read(&count_count_stop) != 1)
                        mb();
                atomic_set(&count_count_start, 0);
                smp_wmb();
@@ -97,6 +94,7 @@ void __cpuinit synchronise_count_master(void)
        }
        /* Arrange for an interrupt in a short while */
        write_c0_compare(read_c0_count() + COUNTON);
+       atomic_set(&count_start_flag, 0);
 
        local_irq_restore(flags);
 
@@ -108,11 +106,10 @@ void __cpuinit synchronise_count_master(void)
        printk("done.\n");
 }
 
-void __cpuinit synchronise_count_slave(void)
+void __cpuinit synchronise_count_slave(int cpu)
 {
        int i;
        unsigned int initcount;
-       int ncpus;
 
 #ifdef CONFIG_MIPS_MT_SMTC
        /*
@@ -127,16 +124,15 @@ void __cpuinit synchronise_count_slave(void)
         * so we first wait for the master to say everyone is ready
         */
 
-       while (!atomic_read(&count_start_flag))
+       while (atomic_read(&count_start_flag) != cpu)
                mb();
 
        /* Count will be initialised to next expire for all CPU's */
        initcount = atomic_read(&count_reference);
 
-       ncpus = num_online_cpus();
        for (i = 0; i < NR_LOOPS; i++) {
                atomic_inc(&count_count_start);
-               while (atomic_read(&count_count_start) != ncpus)
+               while (atomic_read(&count_count_start) != 2)
                        mb();
 
                /*
@@ -146,7 +142,7 @@ void __cpuinit synchronise_count_slave(void)
                        write_c0_count(initcount);
 
                atomic_inc(&count_count_stop);
-               while (atomic_read(&count_count_stop) != ncpus)
+               while (atomic_read(&count_count_stop) != 2)
                        mb();
        }
        /* Arrange for an interrupt in a short while */
index 284dea54faf5a9f629e9d2cab18121cc5db328c6..2147cb34e705a2dca85355aa529c03ca878744a6 100644 (file)
@@ -252,16 +252,3 @@ void __init mips_pcibios_init(void)
 
        register_pci_controller(controller);
 }
-
-/* Enable PCI 2.1 compatibility in PIIX4 */
-static void __devinit quirk_dlcsetup(struct pci_dev *dev)
-{
-       u8 odlc, ndlc;
-       (void) pci_read_config_byte(dev, 0x82, &odlc);
-       /* Enable passive releases and delayed transaction */
-       ndlc = odlc | 7;
-       (void) pci_write_config_byte(dev, 0x82, ndlc);
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
-       quirk_dlcsetup);
index 414a7459858d4e06b837a08d375eccbc96804dae..86d77a666458bae80c60f94c9fc405dca5f8459c 100644 (file)
 #define AR724X_PCI_MEM_BASE    0x10000000
 #define AR724X_PCI_MEM_SIZE    0x08000000
 
+#define AR724X_PCI_REG_RESET           0x18
 #define AR724X_PCI_REG_INT_STATUS      0x4c
 #define AR724X_PCI_REG_INT_MASK                0x50
 
+#define AR724X_PCI_RESET_LINK_UP       BIT(0)
+
 #define AR724X_PCI_INT_DEV0            BIT(14)
 
 #define AR724X_PCI_IRQ_COUNT           1
@@ -38,6 +41,15 @@ static void __iomem *ar724x_pci_ctrl_base;
 
 static u32 ar724x_pci_bar0_value;
 static bool ar724x_pci_bar0_is_cached;
+static bool ar724x_pci_link_up;
+
+static inline bool ar724x_pci_check_link(void)
+{
+       u32 reset;
+
+       reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET);
+       return reset & AR724X_PCI_RESET_LINK_UP;
+}
 
 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
                            int size, uint32_t *value)
@@ -46,6 +58,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
        void __iomem *base;
        u32 data;
 
+       if (!ar724x_pci_link_up)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
        if (devfn)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -96,6 +111,9 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
        u32 data;
        int s;
 
+       if (!ar724x_pci_link_up)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
        if (devfn)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -280,6 +298,10 @@ int __init ar724x_pcibios_init(int irq)
        if (ar724x_pci_ctrl_base == NULL)
                goto err_unmap_devcfg;
 
+       ar724x_pci_link_up = ar724x_pci_check_link();
+       if (!ar724x_pci_link_up)
+               pr_warn("ar724x: PCIe link is down\n");
+
        ar724x_pci_irq_init(irq);
        register_pci_controller(&ar724x_pci_controller);
 
index 6c6defc24619fbab673b6296387c1dead503158b..af9cf30ed47430720ffb4736378336ee04edc9fa 100644 (file)
@@ -141,7 +141,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
 
 #define atomic_sub_and_test(i,v)       (atomic_sub_return((i),(v)) == 0)
 
-#define ATOMIC_INIT(i) ((atomic_t) { (i) })
+#define ATOMIC_INIT(i) { (i) }
 
 #define smp_mb__before_atomic_dec()    smp_mb()
 #define smp_mb__after_atomic_dec()     smp_mb()
@@ -150,7 +150,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
 
 #ifdef CONFIG_64BIT
 
-#define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
+#define ATOMIC64_INIT(i) { (i) }
 
 static __inline__ s64
 __atomic64_add_return(s64 i, atomic64_t *v)
index d4b94b395c1641f6a3c88bf9b50795b36e86d09f..2c05a9292a81cb1138a28af59216eef1d829c421 100644 (file)
@@ -309,7 +309,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
                cregs->ksp = (unsigned long)stack
                        + (pregs->gr[21] & (THREAD_SIZE - 1));
                cregs->gr[30] = usp;
-               if (p->personality == PER_HPUX) {
+               if (personality(p->personality) == PER_HPUX) {
 #ifdef CONFIG_HPUX
                        cregs->kpc = (unsigned long) &hpux_child_return;
 #else
index c9b932260f4713969cc8df8c51a9813110fb622f..7426e40699bdbf08575d0b69722e6594a1535076 100644 (file)
@@ -225,12 +225,12 @@ long parisc_personality(unsigned long personality)
        long err;
 
        if (personality(current->personality) == PER_LINUX32
-           && personality == PER_LINUX)
-               personality = PER_LINUX32;
+           && personality(personality) == PER_LINUX)
+               personality = (personality & ~PER_MASK) | PER_LINUX32;
 
        err = sys_personality(personality);
-       if (err == PER_LINUX32)
-               err = PER_LINUX;
+       if (personality(err) == PER_LINUX32)
+               err = (err & ~PER_MASK) | PER_LINUX;
 
        return err;
 }
index 8d35d2c1f694772ae733fc4d20c0d1fad683948a..4f9c9f682ecfe14b074869b7e93e79fa74326026 100644 (file)
 /include/ "qoriq-duart-1.dtsi"
 /include/ "qoriq-gpio-0.dtsi"
 /include/ "qoriq-usb2-mph-0.dtsi"
+       usb@210000 {
+               compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+               port0;
+       };
 /include/ "qoriq-usb2-dr-0.dtsi"
+       usb@211000 {
+               compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+       };
 /include/ "qoriq-sec4.0-0.dtsi"
 };
index f4337bacd0e7c2692396954a5f51a4ba02e1416b..26e541c4662b27ce2c4429a2325083f8f065bf35 100644 (file)
@@ -6,28 +6,27 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_AUDIT=y
-CONFIG_SPARSE_IRQ=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_EMBEDDED=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
 CONFIG_P1023_RDS=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
 CONFIG_CPM2=y
-CONFIG_GPIO_MPC8XXX=y
 CONFIG_HIGHMEM=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
@@ -63,11 +62,11 @@ CONFIG_INET_ESP=y
 CONFIG_IPV6=y
 CONFIG_IP_SCTP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
@@ -80,15 +79,14 @@ CONFIG_SATA_FSL=y
 CONFIG_SATA_SIL24=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
+CONFIG_FS_ENET=y
+CONFIG_FSL_PQ_MDIO=y
+CONFIG_E1000E=y
 CONFIG_MARVELL_PHY=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_FIXED_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_FS_ENET=y
-CONFIG_E1000E=y
-CONFIG_FSL_PQ_MDIO=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
@@ -98,16 +96,15 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
 CONFIG_SERIAL_QE=m
-CONFIG_HW_RANDOM=y
 CONFIG_NVRAM=y
 CONFIG_I2C=y
 CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
+CONFIG_GPIO_MPC8XXX=y
 # CONFIG_HWMON is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_SOUND=y
@@ -123,7 +120,6 @@ CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
 # CONFIG_NET_DMA is not set
 CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -150,22 +146,15 @@ CONFIG_QNX4FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
 CONFIG_CRC_T10DIF=y
 CONFIG_FRAME_WARN=8092
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_SHA512=y
index cbb98c1234fdea1040292542a4ec4277e5bf76e2..8b3d57c1ebe81312673642db4765408a7de5c322 100644 (file)
@@ -6,8 +6,8 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_AUDIT=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_RCU_TRACE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -21,23 +21,22 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
 CONFIG_P2041_RDB=y
 CONFIG_P3041_DS=y
 CONFIG_P4080_DS=y
 CONFIG_P5020_DS=y
 CONFIG_HIGHMEM=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_KEXEC=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_FORCE_MAX_ZONEORDER=13
-CONFIG_FSL_LBC=y
 CONFIG_PCI=y
 CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_MSI=y
 # CONFIG_PCIEASPM is not set
+CONFIG_PCI_MSI=y
 CONFIG_RAPIDIO=y
 CONFIG_FSL_RIO=y
 CONFIG_NET=y
@@ -70,6 +69,7 @@ CONFIG_INET_IPCOMP=y
 CONFIG_IPV6=y
 CONFIG_IP_SCTP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
@@ -77,17 +77,14 @@ CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_MTD_NAND_FSL_ELBC=y
-CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_MISC_DEVICES=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
@@ -115,11 +112,9 @@ CONFIG_SERIO_LIBPS2=y
 CONFIG_PPC_EPAPR_HV_BYTECHAN=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
-CONFIG_HW_RANDOM=y
 CONFIG_NVRAM=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
@@ -132,7 +127,6 @@ CONFIG_SPI_FSL_ESPI=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_USB_HID=m
 CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_FSL=y
@@ -142,8 +136,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF=y
-CONFIG_MMC_SDHCI_OF_ESDHC=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_EDAC_MPC85XX=y
@@ -170,19 +162,16 @@ CONFIG_HUGETLBFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_UTF8=m
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_RCU_TRACE=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MD4=y
index dd89de8b0b7f59945eb656564d49d19bcf2af121..0516e22ca3de3c16b89cdf0b4d9c7865e2d791c9 100644 (file)
@@ -56,6 +56,7 @@ CONFIG_INET_ESP=y
 CONFIG_IPV6=y
 CONFIG_IP_SCTP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
index 15130066e5e24ee15fb2d9442bb1e3c6c36c912a..07b7f2af2dca7ed9e06f7baea8e46f904fcb8aba 100644 (file)
@@ -1,8 +1,10 @@
+CONFIG_PPC64=y
+CONFIG_ALTIVEC=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_BLK_DEV_INITRD=y
@@ -13,15 +15,16 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=4
-CONFIG_KEXEC=y
-# CONFIG_RELOCATABLE is not set
+# CONFIG_PPC_PSERIES is not set
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_PMAC64=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_KEXEC=y
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_MIGRATION is not set
 CONFIG_PCI_MSI=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -49,6 +52,7 @@ CONFIG_NF_CT_NETLINK=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
@@ -56,6 +60,8 @@ CONFIG_BLK_DEV_RAM_SIZE=65536
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
@@ -79,24 +85,33 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
-CONFIG_MACINTOSH_DRIVERS=y
+CONFIG_IEEE1394=y
+CONFIG_IEEE1394_OHCI1394=y
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_RAWIO=y
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_ADB_PMU=y
+CONFIG_PMAC_SMU=y
 CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_THERM_PM72=y
+CONFIG_WINDFARM=y
+CONFIG_WINDFARM_PM81=y
+CONFIG_WINDFARM_PM91=y
+CONFIG_WINDFARM_PM112=y
+CONFIG_WINDFARM_PM121=y
 CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
 CONFIG_DUMMY=m
-CONFIG_MII=y
+CONFIG_BONDING=m
 CONFIG_TUN=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SUNGEM=y
 CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
-CONFIG_TIGON3=y
 CONFIG_E1000=y
-CONFIG_SUNGEM=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
+CONFIG_TIGON3=y
 CONFIG_USB_CATC=m
 CONFIG_USB_KAWETH=m
 CONFIG_USB_PEGASUS=m
@@ -106,24 +121,36 @@ CONFIG_USB_USBNET=m
 # CONFIG_USB_NET_NET1080 is not set
 # CONFIG_USB_NET_CDC_SUBSET is not set
 # CONFIG_USB_NET_ZAURUS is not set
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_JOYDEV=m
 CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 CONFIG_RAW_DRIVER=y
 CONFIG_I2C_CHARDEV=y
 # CONFIG_HWMON is not set
-CONFIG_AGP=y
-CONFIG_DRM=y
-CONFIG_DRM_NOUVEAU=y
+CONFIG_AGP=m
+CONFIG_AGP_UNINORTH=m
 CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_OF=y
+CONFIG_FB_NVIDIA=y
+CONFIG_FB_NVIDIA_I2C=y
 CONFIG_FB_RADEON=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_SND=m
@@ -131,7 +158,15 @@ CONFIG_SND_SEQUENCER=m
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_AOA=m
+CONFIG_SND_AOA_FABRIC_LAYOUT=m
+CONFIG_SND_AOA_ONYX=m
+CONFIG_SND_AOA_TAS=m
+CONFIG_SND_AOA_TOONIE=m
 CONFIG_SND_USB_AUDIO=m
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
 CONFIG_HID_GYRATION=y
 CONFIG_LOGITECH_FF=y
 CONFIG_HID_PANTHERLORD=y
@@ -139,12 +174,13 @@ CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
-CONFIG_HID_PID=y
-CONFIG_USB_HIDDEV=y
 CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=y
 CONFIG_USB_STORAGE=y
@@ -208,6 +244,8 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
 CONFIG_REISERFS_FS_SECURITY=y
 CONFIG_XFS_FS=m
 CONFIG_XFS_POSIX_ACL=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS_FS=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
@@ -221,12 +259,14 @@ CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_1250=y
 CONFIG_NLS_CODEPAGE_1251=y
@@ -234,23 +274,29 @@ CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_15=y
 CONFIG_NLS_UTF8=y
+CONFIG_CRC_T10DIF=y
+CONFIG_LIBCRC32C=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_MUTEXES=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_LATENCYTOP=y
-CONFIG_STRICT_DEVMEM=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_BOOTX_TEXT=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
@@ -260,6 +306,3 @@ CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
-# CONFIG_VIRTUALIZATION is not set
-CONFIG_CRC_T10DIF=y
-CONFIG_LIBCRC32C=m
index 5aac9a8bc53b2294dfbcb64df800d6aea078fdec..9352e4430c3b05419fdff7ee3b3ec91cfeaeee5d 100644 (file)
@@ -2,12 +2,12 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_83xx=y
@@ -25,7 +25,6 @@ CONFIG_ASP834x=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
 CONFIG_MATH_EMULATION=y
-CONFIG_SPARSE_IRQ=y
 CONFIG_PCI=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -42,10 +41,9 @@ CONFIG_INET_ESP=y
 # CONFIG_INET_LRO is not set
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
@@ -64,15 +62,14 @@ CONFIG_ATA=y
 CONFIG_SATA_FSL=y
 CONFIG_SATA_SIL=y
 CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_UCC_GETH=y
+CONFIG_GIANFAR=y
 CONFIG_MARVELL_PHY=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_VITESSE_PHY=y
 CONFIG_ICPLUS_PHY=y
 CONFIG_FIXED_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_GIANFAR=y
-CONFIG_UCC_GETH=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
@@ -112,17 +109,12 @@ CONFIG_RTC_DRV_DS1374=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_CRC_T10DIF=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_SHA256=y
index 03ee911c45775410c141ab108019b278ae726d17..8b5bda27d248047b43d59ffdd9af22922e599936 100644 (file)
@@ -5,7 +5,9 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_AUDIT=y
-CONFIG_SPARSE_IRQ=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -17,6 +19,8 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
 CONFIG_MPC8540_ADS=y
 CONFIG_MPC8560_ADS=y
 CONFIG_MPC85xx_CDS=y
@@ -40,8 +44,6 @@ CONFIG_SBC8548=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
 CONFIG_HIGHMEM=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
 CONFIG_FORCE_MAX_ZONEORDER=12
@@ -74,36 +76,25 @@ CONFIG_INET_ESP=y
 CONFIG_IPV6=y
 CONFIG_IP_SCTP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
 CONFIG_FTL=y
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
+CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_FSL_ELBC=y
 CONFIG_MTD_NAND_FSL_IFC=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_M25P80=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
@@ -115,6 +106,7 @@ CONFIG_ATA=y
 CONFIG_SATA_AHCI=y
 CONFIG_SATA_FSL=y
 CONFIG_PATA_ALI=y
+CONFIG_PATA_VIA=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
 CONFIG_FS_ENET=y
@@ -134,7 +126,6 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
@@ -183,7 +174,6 @@ CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
 CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_FSL=y
@@ -229,18 +219,13 @@ CONFIG_QNX4FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
 CONFIG_CRC_T10DIF=y
 CONFIG_DEBUG_FS=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_SHA512=y
index fdfa84dc908f21c318f0b0409f0604524f99a2c2..b0974e7e98aefc6f4e7b39a0025c3435e5ebafe1 100644 (file)
@@ -7,7 +7,9 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_AUDIT=y
-CONFIG_SPARSE_IRQ=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -19,6 +21,8 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
 CONFIG_MPC8540_ADS=y
 CONFIG_MPC8560_ADS=y
 CONFIG_MPC85xx_CDS=y
@@ -42,8 +46,6 @@ CONFIG_SBC8548=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
 CONFIG_HIGHMEM=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
 CONFIG_IRQ_ALL_CPUS=y
@@ -77,36 +79,25 @@ CONFIG_INET_ESP=y
 CONFIG_IPV6=y
 CONFIG_IP_SCTP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
 CONFIG_FTL=y
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
+CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_FSL_ELBC=y
 CONFIG_MTD_NAND_FSL_IFC=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_M25P80=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
@@ -137,7 +128,6 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
@@ -186,7 +176,6 @@ CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
 CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_FSL=y
@@ -232,18 +221,13 @@ CONFIG_QNX4FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
 CONFIG_CRC_T10DIF=y
 CONFIG_DEBUG_FS=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_SHA512=y
index 50d82c8a037f4cec2903504541b39a6eb2352331..b3c083de17ad5d3d06739eecdde3926df8b1c39c 100644 (file)
@@ -553,9 +553,7 @@ static inline int cpu_has_feature(unsigned long feature)
                & feature);
 }
 
-#ifdef CONFIG_HAVE_HW_BREAKPOINT
 #define HBP_NUM 1
-#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
 #endif /* !__ASSEMBLY__ */
 
index 50ea12fd7bf5eeab23e6fc1bccafdf4dbe2ad89b..a8bf5c673a3c430c7aa6f45cbfd43e290dd3a95c 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/processor.h>
 #include <asm/page.h>
+#include <asm/cacheflush.h>
 
 #define KVM_MAX_VCPUS          NR_CPUS
 #define KVM_MAX_VCORES         NR_CPUS
index 0124937a23b97e104260f9cd4bbe1c409bdf1ff5..e006f0bdea95f1a9464c688928dc7206690f5c14 100644 (file)
@@ -219,4 +219,16 @@ void kvmppc_claim_lpid(long lpid);
 void kvmppc_free_lpid(long lpid);
 void kvmppc_init_lpid(unsigned long nr_lpids);
 
+static inline void kvmppc_mmu_flush_icache(pfn_t pfn)
+{
+       /* Clear i-cache for new pages */
+       struct page *page;
+       page = pfn_to_page(pfn);
+       if (!test_bit(PG_arch_1, &page->flags)) {
+               flush_dcache_icache_page(page);
+               set_bit(PG_arch_1, &page->flags);
+       }
+}
+
+
 #endif /* __POWERPC_KVM_PPC_H__ */
index 326d33ca55cdc33e8b3cb112f0fefb8117bab3af..d4f471fb10310b75c056345e3094e8180930048a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <asm/smp.h>
+#include <asm/io.h>
 
 struct mpic_msgr {
        u32 __iomem *base;
index 2d7bb8ced136c1e618d1e25229553a70512dc927..e4897523de41e45476bf002a64a3ab68d3e85e22 100644 (file)
@@ -83,11 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask)
                return 0;
        }
 
-       if ((tbl->it_offset + tbl->it_size) > (mask >> IOMMU_PAGE_SHIFT)) {
-               dev_info(dev, "Warning: IOMMU window too big for device mask\n");
-               dev_info(dev, "mask: 0x%08llx, table end: 0x%08lx\n",
-                               mask, (tbl->it_offset + tbl->it_size) <<
-                               IOMMU_PAGE_SHIFT);
+       if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT)) {
+               dev_info(dev, "Warning: IOMMU offset too big for device mask\n");
+               dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n",
+                               mask, tbl->it_offset << IOMMU_PAGE_SHIFT);
                return 0;
        } else
                return 1;
index f3a82dde61dbfe8b469a63d4874f2de53bf1b476..956a4c496de942d93853f42f2db1067f45cf0085 100644 (file)
@@ -253,7 +253,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
 
        /* Do not emulate user-space instructions, instead single-step them */
        if (user_mode(regs)) {
-               bp->ctx->task->thread.last_hit_ubp = bp;
+               current->thread.last_hit_ubp = bp;
                regs->msr |= MSR_SE;
                goto out;
        }
index 782bd0a3c2f0f95496b1b144ebb3ec6e6218e0f8..c470a40b29f5d4937883cfcd8a40dd1c6bbdcfd1 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/processor.h>
 #include <asm/machdep.h>
 #include <asm/debug.h>
+#include <linux/slab.h>
 
 /*
  * This table contains the mapping between PowerPC hardware trap types, and
@@ -101,6 +102,21 @@ static int computeSignal(unsigned int tt)
        return SIGHUP;          /* default for things we don't know about */
 }
 
+/**
+ *
+ *     kgdb_skipexception - Bail out of KGDB when we've been triggered.
+ *     @exception: Exception vector number
+ *     @regs: Current &struct pt_regs.
+ *
+ *     On some architectures we need to skip a breakpoint exception when
+ *     it occurs after a breakpoint has been removed.
+ *
+ */
+int kgdb_skipexception(int exception, struct pt_regs *regs)
+{
+       return kgdb_isremovedbreak(regs->nip);
+}
+
 static int kgdb_call_nmi_hook(struct pt_regs *regs)
 {
        kgdb_nmicallback(raw_smp_processor_id(), regs);
@@ -138,6 +154,8 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)
 static int kgdb_singlestep(struct pt_regs *regs)
 {
        struct thread_info *thread_info, *exception_thread_info;
+       struct thread_info *backup_current_thread_info = \
+               (struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL);
 
        if (user_mode(regs))
                return 0;
@@ -155,13 +173,17 @@ static int kgdb_singlestep(struct pt_regs *regs)
        thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));
        exception_thread_info = current_thread_info();
 
-       if (thread_info != exception_thread_info)
+       if (thread_info != exception_thread_info) {
+               /* Save the original current_thread_info. */
+               memcpy(backup_current_thread_info, exception_thread_info, sizeof *thread_info);
                memcpy(exception_thread_info, thread_info, sizeof *thread_info);
+       }
 
        kgdb_handle_exception(0, SIGTRAP, 0, regs);
 
        if (thread_info != exception_thread_info)
-               memcpy(thread_info, exception_thread_info, sizeof *thread_info);
+               /* Restore current_thread_info lastly. */
+               memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);
 
        return 1;
 }
@@ -410,7 +432,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
 #else
                        linux_regs->msr |= MSR_SE;
 #endif
-                       kgdb_single_step = 1;
                        atomic_set(&kgdb_cpu_doing_single_step,
                                   raw_smp_processor_id());
                }
index f2496f2faeccc37231110392363d0914d599e5b5..4e3cc47f26b90e157ebb5c2a1cd156918e655930 100644 (file)
@@ -107,11 +107,11 @@ long ppc64_personality(unsigned long personality)
        long ret;
 
        if (personality(current->personality) == PER_LINUX32
-           && personality == PER_LINUX)
-               personality = PER_LINUX32;
+           && personality(personality) == PER_LINUX)
+               personality = (personality & ~PER_MASK) | PER_LINUX32;
        ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+       if (personality(ret) == PER_LINUX32)
+               ret = (ret & ~PER_MASK) | PER_LINUX;
        return ret;
 }
 #endif
index f922c29bb234d9bc6f2baf44175e934b63de5f86..837f13e7b6bfc1be3f7ed65a1000964f04825ebe 100644 (file)
@@ -211,6 +211,9 @@ next_pteg:
                pteg1 |= PP_RWRX;
        }
 
+       if (orig_pte->may_execute)
+               kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT);
+
        local_irq_disable();
 
        if (pteg[rr]) {
index 10fc8ec9d2a8b7e1e8e7ad8113e8dce633a5d977..0688b6b3958594fce84a62cfbd2f3564b5650781 100644 (file)
@@ -126,6 +126,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
 
        if (!orig_pte->may_execute)
                rflags |= HPTE_R_N;
+       else
+               kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT);
 
        hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M);
 
index 5a84c8d3d04050b98ab818c9d83cedeb74b8f235..44b72feaff7d9876fad230253be42c1aee6e8af7 100644 (file)
@@ -1421,13 +1421,13 @@ _GLOBAL(kvmppc_h_cede)
        sync                    /* order setting ceded vs. testing prodded */
        lbz     r5,VCPU_PRODDED(r3)
        cmpwi   r5,0
-       bne     1f
+       bne     kvm_cede_prodded
        li      r0,0            /* set trap to 0 to say hcall is handled */
        stw     r0,VCPU_TRAP(r3)
        li      r0,H_SUCCESS
        std     r0,VCPU_GPR(R3)(r3)
 BEGIN_FTR_SECTION
-       b       2f              /* just send it up to host on 970 */
+       b       kvm_cede_exit   /* just send it up to host on 970 */
 END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
 
        /*
@@ -1446,7 +1446,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
        or      r4,r4,r0
        PPC_POPCNTW(R7,R4)
        cmpw    r7,r8
-       bge     2f
+       bge     kvm_cede_exit
        stwcx.  r4,0,r6
        bne     31b
        li      r0,1
@@ -1555,7 +1555,8 @@ kvm_end_cede:
        b       hcall_real_fallback
 
        /* cede when already previously prodded case */
-1:     li      r0,0
+kvm_cede_prodded:
+       li      r0,0
        stb     r0,VCPU_PRODDED(r3)
        sync                    /* order testing prodded vs. clearing ceded */
        stb     r0,VCPU_CEDED(r3)
@@ -1563,7 +1564,8 @@ kvm_end_cede:
        blr
 
        /* we've ceded but we want to give control to the host */
-2:     li      r3,H_TOO_HARD
+kvm_cede_exit:
+       li      r3,H_TOO_HARD
        blr
 
 secondary_too_late:
index c510fc961302c2d1ae1284cc3d1aab1139002fbd..a2b66717813dfef6c43e9bf23864f8766266f0a5 100644 (file)
@@ -322,11 +322,11 @@ static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref)
 static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500)
 {
        if (vcpu_e500->g2h_tlb1_map)
-               memset(vcpu_e500->g2h_tlb1_map,
-                      sizeof(u64) * vcpu_e500->gtlb_params[1].entries, 0);
+               memset(vcpu_e500->g2h_tlb1_map, 0,
+                      sizeof(u64) * vcpu_e500->gtlb_params[1].entries);
        if (vcpu_e500->h2g_tlb1_rmap)
-               memset(vcpu_e500->h2g_tlb1_rmap,
-                      sizeof(unsigned int) * host_tlb_params[1].entries, 0);
+               memset(vcpu_e500->h2g_tlb1_rmap, 0,
+                      sizeof(unsigned int) * host_tlb_params[1].entries);
 }
 
 static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500)
@@ -539,6 +539,9 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
 
        kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize,
                                ref, gvaddr, stlbe);
+
+       /* Clear i-cache for new pages */
+       kvmppc_mmu_flush_icache(pfn);
 }
 
 /* XXX only map the one-one case, for now use TLB0 */
index f9ede7c6606e54d36f4b54fddc5b3101085ee5ef..0d24ff15f5f6fb197af85a4d9e537eb8880f099c 100644 (file)
@@ -288,7 +288,7 @@ err1;       stb     r0,0(r3)
        std     r0,16(r1)
        stdu    r1,-STACKFRAMESIZE(r1)
        bl      .enter_vmx_usercopy
-       cmpwi   r3,0
+       cmpwi   cr1,r3,0
        ld      r0,STACKFRAMESIZE+16(r1)
        ld      r3,STACKFRAMESIZE+48(r1)
        ld      r4,STACKFRAMESIZE+56(r1)
@@ -326,38 +326,7 @@ err1;      stb     r0,0(r3)
        dcbt    r0,r8,0b01010   /* GO */
 .machine pop
 
-       /*
-        * We prefetch both the source and destination using enhanced touch
-        * instructions. We use a stream ID of 0 for the load side and
-        * 1 for the store side.
-        */
-       clrrdi  r6,r4,7
-       clrrdi  r9,r3,7
-       ori     r9,r9,1         /* stream=1 */
-
-       srdi    r7,r5,7         /* length in cachelines, capped at 0x3FF */
-       cmpldi  cr1,r7,0x3FF
-       ble     cr1,1f
-       li      r7,0x3FF
-1:     lis     r0,0x0E00       /* depth=7 */
-       sldi    r7,r7,7
-       or      r7,r7,r0
-       ori     r10,r7,1        /* stream=1 */
-
-       lis     r8,0x8000       /* GO=1 */
-       clrldi  r8,r8,32
-
-.machine push
-.machine "power4"
-       dcbt    r0,r6,0b01000
-       dcbt    r0,r7,0b01010
-       dcbtst  r0,r9,0b01000
-       dcbtst  r0,r10,0b01010
-       eieio
-       dcbt    r0,r8,0b01010   /* GO */
-.machine pop
-
-       beq     .Lunwind_stack_nonvmx_copy
+       beq     cr1,.Lunwind_stack_nonvmx_copy
 
        /*
         * If source and destination are not relatively aligned we use a
index 0efdc51bc7164cf9a1089189a8c6fc64e35002a4..7ba6c96de77856e426fe5cf83ff360280e239194 100644 (file)
@@ -222,7 +222,7 @@ _GLOBAL(memcpy_power7)
        std     r0,16(r1)
        stdu    r1,-STACKFRAMESIZE(r1)
        bl      .enter_vmx_copy
-       cmpwi   r3,0
+       cmpwi   cr1,r3,0
        ld      r0,STACKFRAMESIZE+16(r1)
        ld      r3,STACKFRAMESIZE+48(r1)
        ld      r4,STACKFRAMESIZE+56(r1)
@@ -260,7 +260,7 @@ _GLOBAL(memcpy_power7)
        dcbt    r0,r8,0b01010   /* GO */
 .machine pop
 
-       beq     .Lunwind_stack_nonvmx_copy
+       beq     cr1,.Lunwind_stack_nonvmx_copy
 
        /*
         * If source and destination are not relatively aligned we use a
index baaafde7d13596af850a9d7452e596d84a52935a..fbdad0e3929a8ddfbcb0f714a6480f0ca33ba6f6 100644 (file)
@@ -469,6 +469,7 @@ void flush_dcache_icache_page(struct page *page)
        __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
 #endif
 }
+EXPORT_SYMBOL(flush_dcache_icache_page);
 
 void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
 {
index 77b49ddda9d3675ed816d65af7f8c242578c01a0..7cd2dbd6e4c4fa615ae4442c5d00af106f3e17dd 100644 (file)
@@ -1431,7 +1431,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
                if (!event->hw.idx || is_limited_pmc(event->hw.idx))
                        continue;
                val = read_pmc(event->hw.idx);
-               if ((int)val < 0) {
+               if (pmc_overflow(val)) {
                        /* event has overflowed */
                        found = 1;
                        record_and_restart(event, val, regs);
index a7b2a600d0a4d0aa7878a633eb3549f0a0d3a373..c37f46136321272465327a106383fb440e48fa75 100644 (file)
@@ -465,7 +465,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
                        iounmap(hose->cfg_data);
                iounmap(hose->cfg_addr);
                pcibios_free_controller(hose);
-               return 0;
+               return -ENODEV;
        }
 
        setup_pci_cmd(hose);
@@ -827,6 +827,7 @@ struct device_node *fsl_pci_primary;
 
 void __devinit fsl_pci_init(void)
 {
+       int ret;
        struct device_node *node;
        struct pci_controller *hose;
        dma_addr_t max = 0xffffffff;
@@ -855,10 +856,12 @@ void __devinit fsl_pci_init(void)
                        if (!fsl_pci_primary)
                                fsl_pci_primary = node;
 
-                       fsl_add_bridge(node, fsl_pci_primary == node);
-                       hose = pci_find_hose_for_OF_device(node);
-                       max = min(max, hose->dma_window_base_cur +
-                                       hose->dma_window_size);
+                       ret = fsl_add_bridge(node, fsl_pci_primary == node);
+                       if (ret == 0) {
+                               hose = pci_find_hose_for_OF_device(node);
+                               max = min(max, hose->dma_window_base_cur +
+                                               hose->dma_window_size);
+                       }
                }
        }
 
index 483d8fa72e8ba3bc6bca736faf2f007399282e13..e961f8c4a8f070f341c2b80bbd8a18456a323ade 100644 (file)
@@ -14,6 +14,9 @@
 #include <linux/list.h>
 #include <linux/of_platform.h>
 #include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/hw_irq.h>
 #include <asm/ppc-pci.h>
index eab3492a45c5c5244eca42d58354cf6d8a092836..9b49c65ee7a42f6f9d0b8dc436628c34bafb262b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/kallsyms.h>
+#include <linux/kmsg_dump.h>
 #include <linux/cpumask.h>
 #include <linux/export.h>
 #include <linux/sysrq.h>
@@ -894,13 +895,13 @@ cmds(struct pt_regs *excp)
 #endif
                default:
                        printf("Unrecognized command: ");
-                       do {
+                       do {
                                if (' ' < cmd && cmd <= '~')
                                        putchar(cmd);
                                else
                                        printf("\\x%x", cmd);
                                cmd = inchar();
-                       } while (cmd != '\n'); 
+                       } while (cmd != '\n');
                        printf(" (type ? for help)\n");
                        break;
                }
@@ -1097,7 +1098,7 @@ static long check_bp_loc(unsigned long addr)
        return 1;
 }
 
-static char *breakpoint_help_string = 
+static char *breakpoint_help_string =
     "Breakpoint command usage:\n"
     "b                show breakpoints\n"
     "b <addr> [cnt]   set breakpoint at given instr addr\n"
@@ -1193,7 +1194,7 @@ bpt_cmds(void)
 
        default:
                termch = cmd;
-               cmd = skipbl();
+               cmd = skipbl();
                if (cmd == '?') {
                        printf(breakpoint_help_string);
                        break;
@@ -1359,7 +1360,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
                                       sp + REGS_OFFSET);
                                break;
                        }
-                        printf("--- Exception: %lx %s at ", regs.trap,
+                       printf("--- Exception: %lx %s at ", regs.trap,
                               getvecname(TRAP(&regs)));
                        pc = regs.nip;
                        lr = regs.link;
@@ -1623,14 +1624,14 @@ static void super_regs(void)
 
        cmd = skipbl();
        if (cmd == '\n') {
-               unsigned long sp, toc;
+               unsigned long sp, toc;
                asm("mr %0,1" : "=r" (sp) :);
                asm("mr %0,2" : "=r" (toc) :);
 
                printf("msr  = "REG"  sprg0= "REG"\n",
                       mfmsr(), mfspr(SPRN_SPRG0));
                printf("pvr  = "REG"  sprg1= "REG"\n",
-                      mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 
+                      mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
                printf("dec  = "REG"  sprg2= "REG"\n",
                       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
                printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
@@ -1783,7 +1784,7 @@ byterev(unsigned char *val, int size)
 static int brev;
 static int mnoread;
 
-static char *memex_help_string = 
+static char *memex_help_string =
     "Memory examine command usage:\n"
     "m [addr] [flags] examine/change memory\n"
     "  addr is optional.  will start where left off.\n"
@@ -1798,7 +1799,7 @@ static char *memex_help_string =
     "NOTE: flags are saved as defaults\n"
     "";
 
-static char *memex_subcmd_help_string = 
+static char *memex_subcmd_help_string =
     "Memory examine subcommands:\n"
     "  hexval   write this val to current location\n"
     "  'string' write chars from string to this location\n"
@@ -2064,7 +2065,7 @@ prdump(unsigned long adrs, long ndump)
                nr = mread(adrs, temp, r);
                adrs += nr;
                for (m = 0; m < r; ++m) {
-                       if ((m & (sizeof(long) - 1)) == 0 && m > 0)
+                       if ((m & (sizeof(long) - 1)) == 0 && m > 0)
                                putchar(' ');
                        if (m < nr)
                                printf("%.2x", temp[m]);
@@ -2072,7 +2073,7 @@ prdump(unsigned long adrs, long ndump)
                                printf("%s", fault_chars[fault_type]);
                }
                for (; m < 16; ++m) {
-                       if ((m & (sizeof(long) - 1)) == 0)
+                       if ((m & (sizeof(long) - 1)) == 0)
                                putchar(' ');
                        printf("  ");
                }
@@ -2148,45 +2149,28 @@ print_address(unsigned long addr)
 void
 dump_log_buf(void)
 {
-        const unsigned long size = 128;
-        unsigned long end, addr;
-        unsigned char buf[size + 1];
-
-        addr = 0;
-        buf[size] = '\0';
-
-        if (setjmp(bus_error_jmp) != 0) {
-                printf("Unable to lookup symbol __log_buf!\n");
-                return;
-        }
-
-        catch_memory_errors = 1;
-        sync();
-        addr = kallsyms_lookup_name("__log_buf");
-
-        if (! addr)
-                printf("Symbol __log_buf not found!\n");
-        else {
-                end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
-                while (addr < end) {
-                        if (! mread(addr, buf, size)) {
-                                printf("Can't read memory at address 0x%lx\n", addr);
-                                break;
-                        }
-
-                        printf("%s", buf);
-
-                        if (strlen(buf) < size)
-                                break;
-
-                        addr += size;
-                }
-        }
-
-        sync();
-        /* wait a little while to see if we get a machine check */
-        __delay(200);
-        catch_memory_errors = 0;
+       struct kmsg_dumper dumper = { .active = 1 };
+       unsigned char buf[128];
+       size_t len;
+
+       if (setjmp(bus_error_jmp) != 0) {
+               printf("Error dumping printk buffer!\n");
+               return;
+       }
+
+       catch_memory_errors = 1;
+       sync();
+
+       kmsg_dump_rewind_nolock(&dumper);
+       while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
+               buf[len] = '\0';
+               printf("%s", buf);
+       }
+
+       sync();
+       /* wait a little while to see if we get a machine check */
+       __delay(200);
+       catch_memory_errors = 0;
 }
 
 /*
index 76de6b68487c8a44aa4eabecc1dddc7d916546e2..107610e01a295e27a7fdb1d82fbf8ad0270a4bfc 100644 (file)
@@ -124,6 +124,7 @@ config S390
        select GENERIC_TIME_VSYSCALL
        select GENERIC_CLOCKEVENTS
        select KTIME_SCALAR if 32BIT
+       select HAVE_ARCH_SECCOMP_FILTER
 
 config SCHED_OMIT_FRAME_POINTER
        def_bool y
index 32e8449640facbef375b0a5cb1d33610290c3a7e..9b94a160fe7f06399222ead8530e5a2da2b94f78 100644 (file)
@@ -180,7 +180,8 @@ extern char elf_platform[];
 #define ELF_PLATFORM (elf_platform)
 
 #ifndef CONFIG_64BIT
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+       set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 #else /* CONFIG_64BIT */
 #define SET_PERSONALITY(ex)                                    \
 do {                                                           \
index 7bcc14e395f0a2fd1d85ded571010e05c5c0392e..bf2a2ad2f8004ab36e98d49fccb084a67fba0049 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 typedef unsigned long   __kernel_size_t;
+typedef long            __kernel_ssize_t;
 #define __kernel_size_t __kernel_size_t
 
 typedef unsigned short __kernel_old_dev_t;
@@ -25,7 +26,6 @@ typedef unsigned short  __kernel_mode_t;
 typedef unsigned short  __kernel_ipc_pid_t;
 typedef unsigned short  __kernel_uid_t;
 typedef unsigned short  __kernel_gid_t;
-typedef int             __kernel_ssize_t;
 typedef int             __kernel_ptrdiff_t;
 
 #else /* __s390x__ */
@@ -35,7 +35,6 @@ typedef unsigned int    __kernel_mode_t;
 typedef int             __kernel_ipc_pid_t;
 typedef unsigned int    __kernel_uid_t;
 typedef unsigned int    __kernel_gid_t;
-typedef long            __kernel_ssize_t;
 typedef long            __kernel_ptrdiff_t;
 typedef unsigned long   __kernel_sigset_t;      /* at least 32 bits */
 
index a0a8340daafafb90ad25c822949b6ace5a84a595..ce26ac3cb162899a285e5812a39ea9b1b6ec0484 100644 (file)
@@ -44,6 +44,7 @@ static inline void smp_call_online_cpu(void (*func)(void *), void *data)
 }
 
 static inline int smp_find_processor_id(int address) { return 0; }
+static inline int smp_store_status(int cpu) { return 0; }
 static inline int smp_vcpu_scheduled(int cpu) { return 1; }
 static inline void smp_yield_cpu(int cpu) { }
 static inline void smp_yield(void) { }
index 0fb34027d3f6fbdc5a851f796a0e23d368bea071..a60d085ddb4d90089d7e73850955432ca2372eb6 100644 (file)
@@ -4,13 +4,11 @@
 #ifdef CONFIG_64BIT
 
 #define SECTION_SIZE_BITS      28
-#define MAX_PHYSADDR_BITS      46
 #define MAX_PHYSMEM_BITS       46
 
 #else
 
 #define SECTION_SIZE_BITS      25
-#define MAX_PHYSADDR_BITS      31
 #define MAX_PHYSMEM_BITS       31
 
 #endif /* CONFIG_64BIT */
index fb214dd9b7e0631606072a00a6b3994de4e8a97b..fe7b99759e12ffcdf5f2df9880f86f91df3c9800 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _ASM_SYSCALL_H
 #define _ASM_SYSCALL_H 1
 
+#include <linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <asm/ptrace.h>
@@ -87,4 +88,13 @@ static inline void syscall_set_arguments(struct task_struct *task,
                regs->orig_gpr2 = args[0];
 }
 
+static inline int syscall_get_arch(struct task_struct *task,
+                                  struct pt_regs *regs)
+{
+#ifdef CONFIG_COMPAT
+       if (test_tsk_thread_flag(task, TIF_31BIT))
+               return AUDIT_ARCH_S390;
+#endif
+       return sizeof(long) == 8 ? AUDIT_ARCH_S390X : AUDIT_ARCH_S390;
+}
 #endif /* _ASM_SYSCALL_H */
index d1225089a4bbe09519555c4f5336e283394ff03e..f606d935f4950dcbec6fca5f67b88ac70760dcda 100644 (file)
@@ -620,7 +620,6 @@ asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
                return -EFAULT;
        if (a.offset & ~PAGE_MASK)
                return -EINVAL;
-       a.addr = (unsigned long) compat_ptr(a.addr);
        return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
                              a.offset >> PAGE_SHIFT);
 }
@@ -631,7 +630,6 @@ asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
 
        if (copy_from_user(&a, arg, sizeof(a)))
                return -EFAULT;
-       a.addr = (unsigned long) compat_ptr(a.addr);
        return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
 }
 
index e835d6d5b7fdc94ee90e5293087328d638c2f74f..2d82cfcbce5b8cae9127aa115902fa6a2f3b5123 100644 (file)
@@ -1635,7 +1635,7 @@ ENTRY(compat_sys_process_vm_readv_wrapper)
        llgfr   %r6,%r6                 # unsigned long
        llgf    %r0,164(%r15)           # unsigned long
        stg     %r0,160(%r15)
-       jg      sys_process_vm_readv
+       jg      compat_sys_process_vm_readv
 
 ENTRY(compat_sys_process_vm_writev_wrapper)
        lgfr    %r2,%r2                 # compat_pid_t
@@ -1645,4 +1645,4 @@ ENTRY(compat_sys_process_vm_writev_wrapper)
        llgfr   %r6,%r6                 # unsigned long
        llgf    %r0,164(%r15)           # unsigned long
        stg     %r0,160(%r15)
-       jg      sys_process_vm_writev
+       jg      compat_sys_process_vm_writev
index f4eb37680b9152b458938ff37b875754823be695..e4be113fbac62de564bc8566263ae40bd6b4771b 100644 (file)
@@ -719,7 +719,11 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
        long ret = 0;
 
        /* Do the secure computing check first. */
-       secure_computing_strict(regs->gprs[2]);
+       if (secure_computing(regs->gprs[2])) {
+               /* seccomp failures shouldn't expose any additional code. */
+               ret = -1;
+               goto out;
+       }
 
        /*
         * The sysc_tracesys code in entry.S stored the system
@@ -745,6 +749,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                            regs->gprs[2], regs->orig_gpr2,
                            regs->gprs[3], regs->gprs[4],
                            regs->gprs[5]);
+out:
        return ret ?: regs->gprs[2];
 }
 
index b4a29eee41b8d59a7542ce040019a62b0e5f4be8..d0964d22adb5aecb66d94005483e04c7c282b657 100644 (file)
@@ -81,11 +81,12 @@ SYSCALL_DEFINE1(s390_personality, unsigned int, personality)
 {
        unsigned int ret;
 
-       if (current->personality == PER_LINUX32 && personality == PER_LINUX)
-               personality = PER_LINUX32;
+       if (personality(current->personality) == PER_LINUX32 &&
+           personality(personality) == PER_LINUX)
+               personality |= PER_LINUX32;
        ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+       if (personality(ret) == PER_LINUX32)
+               ret &= ~PER_LINUX32;
 
        return ret;
 }
index 4c171f13b0e8792b5f88a564c1fef52e15218c22..b2256562314298e0e63918b7f60323691e08d5b3 100644 (file)
@@ -335,7 +335,7 @@ static int dmae_irq_init(void)
 
        for (n = 0; n < NR_DMAE; n++) {
                int i = request_irq(get_dma_error_irq(n), dma_err,
-                                   IRQF_SHARED, dmae_name[n], NULL);
+                                   IRQF_SHARED, dmae_name[n], (void *)dmae_name[n]);
                if (unlikely(i < 0)) {
                        printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]);
                        return i;
index 4a5350037c8f59217a06e6e6ea1c429594d51073..1b6199740e98ab7e554f1676d615983f451e56a7 100644 (file)
@@ -6,7 +6,6 @@
 extern long __nosave_begin, __nosave_end;
 extern long __machvec_start, __machvec_end;
 extern char __uncached_start, __uncached_end;
-extern char _ebss[];
 extern char __start_eh_frame[], __stop_eh_frame[];
 
 #endif /* __ASM_SH_SECTIONS_H */
index 48d14498e7740aaf76fcdafa0bae17a3ec7b6ec6..2a0ca8780f0d8c343fb87e434cf6acec73acaddb 100644 (file)
@@ -183,18 +183,30 @@ enum {
        GPIO_FN_DV_DATA1, GPIO_FN_DV_DATA0,
        GPIO_FN_LCD_CLK, GPIO_FN_LCD_EXTCLK,
        GPIO_FN_LCD_VSYNC, GPIO_FN_LCD_HSYNC, GPIO_FN_LCD_DE,
-       GPIO_FN_LCD_DATA23, GPIO_FN_LCD_DATA22,
-       GPIO_FN_LCD_DATA21, GPIO_FN_LCD_DATA20,
-       GPIO_FN_LCD_DATA19, GPIO_FN_LCD_DATA18,
-       GPIO_FN_LCD_DATA17, GPIO_FN_LCD_DATA16,
-       GPIO_FN_LCD_DATA15, GPIO_FN_LCD_DATA14,
-       GPIO_FN_LCD_DATA13, GPIO_FN_LCD_DATA12,
-       GPIO_FN_LCD_DATA11, GPIO_FN_LCD_DATA10,
-       GPIO_FN_LCD_DATA9, GPIO_FN_LCD_DATA8,
-       GPIO_FN_LCD_DATA7, GPIO_FN_LCD_DATA6,
-       GPIO_FN_LCD_DATA5, GPIO_FN_LCD_DATA4,
-       GPIO_FN_LCD_DATA3, GPIO_FN_LCD_DATA2,
-       GPIO_FN_LCD_DATA1, GPIO_FN_LCD_DATA0,
+       GPIO_FN_LCD_DATA23_PG23, GPIO_FN_LCD_DATA22_PG22,
+       GPIO_FN_LCD_DATA21_PG21, GPIO_FN_LCD_DATA20_PG20,
+       GPIO_FN_LCD_DATA19_PG19, GPIO_FN_LCD_DATA18_PG18,
+       GPIO_FN_LCD_DATA17_PG17, GPIO_FN_LCD_DATA16_PG16,
+       GPIO_FN_LCD_DATA15_PG15, GPIO_FN_LCD_DATA14_PG14,
+       GPIO_FN_LCD_DATA13_PG13, GPIO_FN_LCD_DATA12_PG12,
+       GPIO_FN_LCD_DATA11_PG11, GPIO_FN_LCD_DATA10_PG10,
+       GPIO_FN_LCD_DATA9_PG9, GPIO_FN_LCD_DATA8_PG8,
+       GPIO_FN_LCD_DATA7_PG7, GPIO_FN_LCD_DATA6_PG6,
+       GPIO_FN_LCD_DATA5_PG5, GPIO_FN_LCD_DATA4_PG4,
+       GPIO_FN_LCD_DATA3_PG3, GPIO_FN_LCD_DATA2_PG2,
+       GPIO_FN_LCD_DATA1_PG1, GPIO_FN_LCD_DATA0_PG0,
+       GPIO_FN_LCD_DATA23_PJ23, GPIO_FN_LCD_DATA22_PJ22,
+       GPIO_FN_LCD_DATA21_PJ21, GPIO_FN_LCD_DATA20_PJ20,
+       GPIO_FN_LCD_DATA19_PJ19, GPIO_FN_LCD_DATA18_PJ18,
+       GPIO_FN_LCD_DATA17_PJ17, GPIO_FN_LCD_DATA16_PJ16,
+       GPIO_FN_LCD_DATA15_PJ15, GPIO_FN_LCD_DATA14_PJ14,
+       GPIO_FN_LCD_DATA13_PJ13, GPIO_FN_LCD_DATA12_PJ12,
+       GPIO_FN_LCD_DATA11_PJ11, GPIO_FN_LCD_DATA10_PJ10,
+       GPIO_FN_LCD_DATA9_PJ9, GPIO_FN_LCD_DATA8_PJ8,
+       GPIO_FN_LCD_DATA7_PJ7, GPIO_FN_LCD_DATA6_PJ6,
+       GPIO_FN_LCD_DATA5_PJ5, GPIO_FN_LCD_DATA4_PJ4,
+       GPIO_FN_LCD_DATA3_PJ3, GPIO_FN_LCD_DATA2_PJ2,
+       GPIO_FN_LCD_DATA1_PJ1, GPIO_FN_LCD_DATA0_PJ0,
        GPIO_FN_LCD_M_DISP,
 };
 
index f25127c46ecaff2df0e7bb7b38eca237903c7838..039e4587dd9b8cf2959e2d19159098f02136f7fd 100644 (file)
@@ -758,12 +758,22 @@ enum {
        DV_DATA3_MARK, DV_DATA2_MARK, DV_DATA1_MARK, DV_DATA0_MARK,
        LCD_CLK_MARK, LCD_EXTCLK_MARK,
        LCD_VSYNC_MARK, LCD_HSYNC_MARK, LCD_DE_MARK,
-       LCD_DATA23_MARK, LCD_DATA22_MARK, LCD_DATA21_MARK, LCD_DATA20_MARK,
-       LCD_DATA19_MARK, LCD_DATA18_MARK, LCD_DATA17_MARK, LCD_DATA16_MARK,
-       LCD_DATA15_MARK, LCD_DATA14_MARK, LCD_DATA13_MARK, LCD_DATA12_MARK,
-       LCD_DATA11_MARK, LCD_DATA10_MARK, LCD_DATA9_MARK, LCD_DATA8_MARK,
-       LCD_DATA7_MARK, LCD_DATA6_MARK, LCD_DATA5_MARK, LCD_DATA4_MARK,
-       LCD_DATA3_MARK, LCD_DATA2_MARK, LCD_DATA1_MARK, LCD_DATA0_MARK,
+       LCD_DATA23_PG23_MARK, LCD_DATA22_PG22_MARK, LCD_DATA21_PG21_MARK,
+       LCD_DATA20_PG20_MARK, LCD_DATA19_PG19_MARK, LCD_DATA18_PG18_MARK,
+       LCD_DATA17_PG17_MARK, LCD_DATA16_PG16_MARK, LCD_DATA15_PG15_MARK,
+       LCD_DATA14_PG14_MARK, LCD_DATA13_PG13_MARK, LCD_DATA12_PG12_MARK,
+       LCD_DATA11_PG11_MARK, LCD_DATA10_PG10_MARK, LCD_DATA9_PG9_MARK,
+       LCD_DATA8_PG8_MARK, LCD_DATA7_PG7_MARK, LCD_DATA6_PG6_MARK,
+       LCD_DATA5_PG5_MARK, LCD_DATA4_PG4_MARK, LCD_DATA3_PG3_MARK,
+       LCD_DATA2_PG2_MARK, LCD_DATA1_PG1_MARK, LCD_DATA0_PG0_MARK,
+       LCD_DATA23_PJ23_MARK, LCD_DATA22_PJ22_MARK, LCD_DATA21_PJ21_MARK,
+       LCD_DATA20_PJ20_MARK, LCD_DATA19_PJ19_MARK, LCD_DATA18_PJ18_MARK,
+       LCD_DATA17_PJ17_MARK, LCD_DATA16_PJ16_MARK, LCD_DATA15_PJ15_MARK,
+       LCD_DATA14_PJ14_MARK, LCD_DATA13_PJ13_MARK, LCD_DATA12_PJ12_MARK,
+       LCD_DATA11_PJ11_MARK, LCD_DATA10_PJ10_MARK, LCD_DATA9_PJ9_MARK,
+       LCD_DATA8_PJ8_MARK, LCD_DATA7_PJ7_MARK, LCD_DATA6_PJ6_MARK,
+       LCD_DATA5_PJ5_MARK, LCD_DATA4_PJ4_MARK, LCD_DATA3_PJ3_MARK,
+       LCD_DATA2_PJ2_MARK, LCD_DATA1_PJ1_MARK, LCD_DATA0_PJ0_MARK,
        LCD_TCON6_MARK, LCD_TCON5_MARK, LCD_TCON4_MARK,
        LCD_TCON3_MARK, LCD_TCON2_MARK, LCD_TCON1_MARK, LCD_TCON0_MARK,
        LCD_M_DISP_MARK,
@@ -1036,6 +1046,7 @@ static pinmux_enum_t pinmux_data[] = {
 
        PINMUX_DATA(PF1_DATA, PF1MD_000),
        PINMUX_DATA(BACK_MARK, PF1MD_001),
+       PINMUX_DATA(SSL10_MARK, PF1MD_011),
        PINMUX_DATA(TIOC4B_MARK, PF1MD_100),
        PINMUX_DATA(DACK0_MARK, PF1MD_101),
 
@@ -1049,47 +1060,50 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(PG27_DATA, PG27MD_00),
        PINMUX_DATA(LCD_TCON2_MARK, PG27MD_10),
        PINMUX_DATA(LCD_EXTCLK_MARK, PG27MD_11),
+       PINMUX_DATA(LCD_DE_MARK, PG27MD_11),
 
        PINMUX_DATA(PG26_DATA, PG26MD_00),
        PINMUX_DATA(LCD_TCON1_MARK, PG26MD_10),
+       PINMUX_DATA(LCD_HSYNC_MARK, PG26MD_10),
 
        PINMUX_DATA(PG25_DATA, PG25MD_00),
        PINMUX_DATA(LCD_TCON0_MARK, PG25MD_10),
+       PINMUX_DATA(LCD_VSYNC_MARK, PG25MD_10),
 
        PINMUX_DATA(PG24_DATA, PG24MD_00),
        PINMUX_DATA(LCD_CLK_MARK, PG24MD_10),
 
        PINMUX_DATA(PG23_DATA, PG23MD_000),
-       PINMUX_DATA(LCD_DATA23_MARK, PG23MD_010),
+       PINMUX_DATA(LCD_DATA23_PG23_MARK, PG23MD_010),
        PINMUX_DATA(LCD_TCON6_MARK, PG23MD_011),
        PINMUX_DATA(TXD5_MARK, PG23MD_100),
 
        PINMUX_DATA(PG22_DATA, PG22MD_000),
-       PINMUX_DATA(LCD_DATA22_MARK, PG22MD_010),
+       PINMUX_DATA(LCD_DATA22_PG22_MARK, PG22MD_010),
        PINMUX_DATA(LCD_TCON5_MARK, PG22MD_011),
        PINMUX_DATA(RXD5_MARK, PG22MD_100),
 
        PINMUX_DATA(PG21_DATA, PG21MD_000),
        PINMUX_DATA(DV_DATA7_MARK, PG21MD_001),
-       PINMUX_DATA(LCD_DATA21_MARK, PG21MD_010),
+       PINMUX_DATA(LCD_DATA21_PG21_MARK, PG21MD_010),
        PINMUX_DATA(LCD_TCON4_MARK, PG21MD_011),
        PINMUX_DATA(TXD4_MARK, PG21MD_100),
 
        PINMUX_DATA(PG20_DATA, PG20MD_000),
        PINMUX_DATA(DV_DATA6_MARK, PG20MD_001),
-       PINMUX_DATA(LCD_DATA20_MARK, PG21MD_010),
+       PINMUX_DATA(LCD_DATA20_PG20_MARK, PG21MD_010),
        PINMUX_DATA(LCD_TCON3_MARK, PG20MD_011),
        PINMUX_DATA(RXD4_MARK, PG20MD_100),
 
        PINMUX_DATA(PG19_DATA, PG19MD_000),
        PINMUX_DATA(DV_DATA5_MARK, PG19MD_001),
-       PINMUX_DATA(LCD_DATA19_MARK, PG19MD_010),
+       PINMUX_DATA(LCD_DATA19_PG19_MARK, PG19MD_010),
        PINMUX_DATA(SPDIF_OUT_MARK, PG19MD_011),
        PINMUX_DATA(SCK5_MARK, PG19MD_100),
 
        PINMUX_DATA(PG18_DATA, PG18MD_000),
        PINMUX_DATA(DV_DATA4_MARK, PG18MD_001),
-       PINMUX_DATA(LCD_DATA18_MARK, PG18MD_010),
+       PINMUX_DATA(LCD_DATA18_PG18_MARK, PG18MD_010),
        PINMUX_DATA(SPDIF_IN_MARK, PG18MD_011),
        PINMUX_DATA(SCK4_MARK, PG18MD_100),
 
@@ -1097,103 +1111,103 @@ static pinmux_enum_t pinmux_data[] = {
 // we're going with 2 bits
        PINMUX_DATA(PG17_DATA, PG17MD_00),
        PINMUX_DATA(WE3ICIOWRAHDQMUU_MARK, PG17MD_01),
-       PINMUX_DATA(LCD_DATA17_MARK, PG17MD_10),
+       PINMUX_DATA(LCD_DATA17_PG17_MARK, PG17MD_10),
 
 // TODO hardware manual has PG16 3 bits wide in reg picture and 2 bits in description
 // we're going with 2 bits
        PINMUX_DATA(PG16_DATA, PG16MD_00),
        PINMUX_DATA(WE2ICIORDDQMUL_MARK, PG16MD_01),
-       PINMUX_DATA(LCD_DATA16_MARK, PG16MD_10),
+       PINMUX_DATA(LCD_DATA16_PG16_MARK, PG16MD_10),
 
        PINMUX_DATA(PG15_DATA, PG15MD_00),
        PINMUX_DATA(D31_MARK, PG15MD_01),
-       PINMUX_DATA(LCD_DATA15_MARK, PG15MD_10),
+       PINMUX_DATA(LCD_DATA15_PG15_MARK, PG15MD_10),
        PINMUX_DATA(PINT7_PG_MARK, PG15MD_11),
 
        PINMUX_DATA(PG14_DATA, PG14MD_00),
        PINMUX_DATA(D30_MARK, PG14MD_01),
-       PINMUX_DATA(LCD_DATA14_MARK, PG14MD_10),
+       PINMUX_DATA(LCD_DATA14_PG14_MARK, PG14MD_10),
        PINMUX_DATA(PINT6_PG_MARK, PG14MD_11),
 
        PINMUX_DATA(PG13_DATA, PG13MD_00),
        PINMUX_DATA(D29_MARK, PG13MD_01),
-       PINMUX_DATA(LCD_DATA13_MARK, PG13MD_10),
+       PINMUX_DATA(LCD_DATA13_PG13_MARK, PG13MD_10),
        PINMUX_DATA(PINT5_PG_MARK, PG13MD_11),
 
        PINMUX_DATA(PG12_DATA, PG12MD_00),
        PINMUX_DATA(D28_MARK, PG12MD_01),
-       PINMUX_DATA(LCD_DATA12_MARK, PG12MD_10),
+       PINMUX_DATA(LCD_DATA12_PG12_MARK, PG12MD_10),
        PINMUX_DATA(PINT4_PG_MARK, PG12MD_11),
 
        PINMUX_DATA(PG11_DATA, PG11MD_000),
        PINMUX_DATA(D27_MARK, PG11MD_001),
-       PINMUX_DATA(LCD_DATA11_MARK, PG11MD_010),
+       PINMUX_DATA(LCD_DATA11_PG11_MARK, PG11MD_010),
        PINMUX_DATA(PINT3_PG_MARK, PG11MD_011),
        PINMUX_DATA(TIOC3D_MARK, PG11MD_100),
 
        PINMUX_DATA(PG10_DATA, PG10MD_000),
        PINMUX_DATA(D26_MARK, PG10MD_001),
-       PINMUX_DATA(LCD_DATA10_MARK, PG10MD_010),
+       PINMUX_DATA(LCD_DATA10_PG10_MARK, PG10MD_010),
        PINMUX_DATA(PINT2_PG_MARK, PG10MD_011),
        PINMUX_DATA(TIOC3C_MARK, PG10MD_100),
 
        PINMUX_DATA(PG9_DATA, PG9MD_000),
        PINMUX_DATA(D25_MARK, PG9MD_001),
-       PINMUX_DATA(LCD_DATA9_MARK, PG9MD_010),
+       PINMUX_DATA(LCD_DATA9_PG9_MARK, PG9MD_010),
        PINMUX_DATA(PINT1_PG_MARK, PG9MD_011),
        PINMUX_DATA(TIOC3B_MARK, PG9MD_100),
 
        PINMUX_DATA(PG8_DATA, PG8MD_000),
        PINMUX_DATA(D24_MARK, PG8MD_001),
-       PINMUX_DATA(LCD_DATA8_MARK, PG8MD_010),
+       PINMUX_DATA(LCD_DATA8_PG8_MARK, PG8MD_010),
        PINMUX_DATA(PINT0_PG_MARK, PG8MD_011),
        PINMUX_DATA(TIOC3A_MARK, PG8MD_100),
 
        PINMUX_DATA(PG7_DATA, PG7MD_000),
        PINMUX_DATA(D23_MARK, PG7MD_001),
-       PINMUX_DATA(LCD_DATA7_MARK, PG7MD_010),
+       PINMUX_DATA(LCD_DATA7_PG7_MARK, PG7MD_010),
        PINMUX_DATA(IRQ7_PG_MARK, PG7MD_011),
        PINMUX_DATA(TIOC2B_MARK, PG7MD_100),
 
        PINMUX_DATA(PG6_DATA, PG6MD_000),
        PINMUX_DATA(D22_MARK, PG6MD_001),
-       PINMUX_DATA(LCD_DATA6_MARK, PG6MD_010),
+       PINMUX_DATA(LCD_DATA6_PG6_MARK, PG6MD_010),
        PINMUX_DATA(IRQ6_PG_MARK, PG6MD_011),
        PINMUX_DATA(TIOC2A_MARK, PG6MD_100),
 
        PINMUX_DATA(PG5_DATA, PG5MD_000),
        PINMUX_DATA(D21_MARK, PG5MD_001),
-       PINMUX_DATA(LCD_DATA5_MARK, PG5MD_010),
+       PINMUX_DATA(LCD_DATA5_PG5_MARK, PG5MD_010),
        PINMUX_DATA(IRQ5_PG_MARK, PG5MD_011),
        PINMUX_DATA(TIOC1B_MARK, PG5MD_100),
 
        PINMUX_DATA(PG4_DATA, PG4MD_000),
        PINMUX_DATA(D20_MARK, PG4MD_001),
-       PINMUX_DATA(LCD_DATA4_MARK, PG4MD_010),
+       PINMUX_DATA(LCD_DATA4_PG4_MARK, PG4MD_010),
        PINMUX_DATA(IRQ4_PG_MARK, PG4MD_011),
        PINMUX_DATA(TIOC1A_MARK, PG4MD_100),
 
        PINMUX_DATA(PG3_DATA, PG3MD_000),
        PINMUX_DATA(D19_MARK, PG3MD_001),
-       PINMUX_DATA(LCD_DATA3_MARK, PG3MD_010),
+       PINMUX_DATA(LCD_DATA3_PG3_MARK, PG3MD_010),
        PINMUX_DATA(IRQ3_PG_MARK, PG3MD_011),
        PINMUX_DATA(TIOC0D_MARK, PG3MD_100),
 
        PINMUX_DATA(PG2_DATA, PG2MD_000),
        PINMUX_DATA(D18_MARK, PG2MD_001),
-       PINMUX_DATA(LCD_DATA2_MARK, PG2MD_010),
+       PINMUX_DATA(LCD_DATA2_PG2_MARK, PG2MD_010),
        PINMUX_DATA(IRQ2_PG_MARK, PG2MD_011),
        PINMUX_DATA(TIOC0C_MARK, PG2MD_100),
 
        PINMUX_DATA(PG1_DATA, PG1MD_000),
        PINMUX_DATA(D17_MARK, PG1MD_001),
-       PINMUX_DATA(LCD_DATA1_MARK, PG1MD_010),
+       PINMUX_DATA(LCD_DATA1_PG1_MARK, PG1MD_010),
        PINMUX_DATA(IRQ1_PG_MARK, PG1MD_011),
        PINMUX_DATA(TIOC0B_MARK, PG1MD_100),
 
        PINMUX_DATA(PG0_DATA, PG0MD_000),
        PINMUX_DATA(D16_MARK, PG0MD_001),
-       PINMUX_DATA(LCD_DATA0_MARK, PG0MD_010),
+       PINMUX_DATA(LCD_DATA0_PG0_MARK, PG0MD_010),
        PINMUX_DATA(IRQ0_PG_MARK, PG0MD_011),
        PINMUX_DATA(TIOC0A_MARK, PG0MD_100),
 
@@ -1275,14 +1289,14 @@ static pinmux_enum_t pinmux_data[] = {
 
        PINMUX_DATA(PJ23_DATA, PJ23MD_000),
        PINMUX_DATA(DV_DATA23_MARK, PJ23MD_001),
-       PINMUX_DATA(LCD_DATA23_MARK, PJ23MD_010),
+       PINMUX_DATA(LCD_DATA23_PJ23_MARK, PJ23MD_010),
        PINMUX_DATA(LCD_TCON6_MARK, PJ23MD_011),
        PINMUX_DATA(IRQ3_PJ_MARK, PJ23MD_100),
        PINMUX_DATA(CTX1_MARK, PJ23MD_101),
 
        PINMUX_DATA(PJ22_DATA, PJ22MD_000),
        PINMUX_DATA(DV_DATA22_MARK, PJ22MD_001),
-       PINMUX_DATA(LCD_DATA22_MARK, PJ22MD_010),
+       PINMUX_DATA(LCD_DATA22_PJ22_MARK, PJ22MD_010),
        PINMUX_DATA(LCD_TCON5_MARK, PJ22MD_011),
        PINMUX_DATA(IRQ2_PJ_MARK, PJ22MD_100),
        PINMUX_DATA(CRX1_MARK, PJ22MD_101),
@@ -1290,14 +1304,14 @@ static pinmux_enum_t pinmux_data[] = {
 
        PINMUX_DATA(PJ21_DATA, PJ21MD_000),
        PINMUX_DATA(DV_DATA21_MARK, PJ21MD_001),
-       PINMUX_DATA(LCD_DATA21_MARK, PJ21MD_010),
+       PINMUX_DATA(LCD_DATA21_PJ21_MARK, PJ21MD_010),
        PINMUX_DATA(LCD_TCON4_MARK, PJ21MD_011),
        PINMUX_DATA(IRQ1_PJ_MARK, PJ21MD_100),
        PINMUX_DATA(CTX2_MARK, PJ21MD_101),
 
        PINMUX_DATA(PJ20_DATA, PJ20MD_000),
        PINMUX_DATA(DV_DATA20_MARK, PJ20MD_001),
-       PINMUX_DATA(LCD_DATA20_MARK, PJ20MD_010),
+       PINMUX_DATA(LCD_DATA20_PJ20_MARK, PJ20MD_010),
        PINMUX_DATA(LCD_TCON3_MARK, PJ20MD_011),
        PINMUX_DATA(IRQ0_PJ_MARK, PJ20MD_100),
        PINMUX_DATA(CRX2_MARK, PJ20MD_101),
@@ -1305,7 +1319,7 @@ static pinmux_enum_t pinmux_data[] = {
 
        PINMUX_DATA(PJ19_DATA, PJ19MD_000),
        PINMUX_DATA(DV_DATA19_MARK, PJ19MD_001),
-       PINMUX_DATA(LCD_DATA19_MARK, PJ19MD_010),
+       PINMUX_DATA(LCD_DATA19_PJ19_MARK, PJ19MD_010),
        PINMUX_DATA(MISO0_PJ19_MARK, PJ19MD_011),
        PINMUX_DATA(TIOC0D_MARK, PJ19MD_100),
        PINMUX_DATA(SIOFRXD_MARK, PJ19MD_101),
@@ -1313,126 +1327,126 @@ static pinmux_enum_t pinmux_data[] = {
 
        PINMUX_DATA(PJ18_DATA, PJ18MD_000),
        PINMUX_DATA(DV_DATA18_MARK, PJ18MD_001),
-       PINMUX_DATA(LCD_DATA18_MARK, PJ18MD_010),
+       PINMUX_DATA(LCD_DATA18_PJ18_MARK, PJ18MD_010),
        PINMUX_DATA(MOSI0_PJ18_MARK, PJ18MD_011),
        PINMUX_DATA(TIOC0C_MARK, PJ18MD_100),
        PINMUX_DATA(SIOFTXD_MARK, PJ18MD_101),
 
        PINMUX_DATA(PJ17_DATA, PJ17MD_000),
        PINMUX_DATA(DV_DATA17_MARK, PJ17MD_001),
-       PINMUX_DATA(LCD_DATA17_MARK, PJ17MD_010),
+       PINMUX_DATA(LCD_DATA17_PJ17_MARK, PJ17MD_010),
        PINMUX_DATA(SSL00_PJ17_MARK, PJ17MD_011),
        PINMUX_DATA(TIOC0B_MARK, PJ17MD_100),
        PINMUX_DATA(SIOFSYNC_MARK, PJ17MD_101),
 
        PINMUX_DATA(PJ16_DATA, PJ16MD_000),
        PINMUX_DATA(DV_DATA16_MARK, PJ16MD_001),
-       PINMUX_DATA(LCD_DATA16_MARK, PJ16MD_010),
+       PINMUX_DATA(LCD_DATA16_PJ16_MARK, PJ16MD_010),
        PINMUX_DATA(RSPCK0_PJ16_MARK, PJ16MD_011),
        PINMUX_DATA(TIOC0A_MARK, PJ16MD_100),
        PINMUX_DATA(SIOFSCK_MARK, PJ16MD_101),
 
        PINMUX_DATA(PJ15_DATA, PJ15MD_000),
        PINMUX_DATA(DV_DATA15_MARK, PJ15MD_001),
-       PINMUX_DATA(LCD_DATA15_MARK, PJ15MD_010),
+       PINMUX_DATA(LCD_DATA15_PJ15_MARK, PJ15MD_010),
        PINMUX_DATA(PINT7_PJ_MARK, PJ15MD_011),
        PINMUX_DATA(PWM2H_MARK, PJ15MD_100),
        PINMUX_DATA(TXD7_MARK, PJ15MD_101),
 
        PINMUX_DATA(PJ14_DATA, PJ14MD_000),
        PINMUX_DATA(DV_DATA14_MARK, PJ14MD_001),
-       PINMUX_DATA(LCD_DATA14_MARK, PJ14MD_010),
+       PINMUX_DATA(LCD_DATA14_PJ14_MARK, PJ14MD_010),
        PINMUX_DATA(PINT6_PJ_MARK, PJ14MD_011),
        PINMUX_DATA(PWM2G_MARK, PJ14MD_100),
        PINMUX_DATA(TXD6_MARK, PJ14MD_101),
 
        PINMUX_DATA(PJ13_DATA, PJ13MD_000),
        PINMUX_DATA(DV_DATA13_MARK, PJ13MD_001),
-       PINMUX_DATA(LCD_DATA13_MARK, PJ13MD_010),
+       PINMUX_DATA(LCD_DATA13_PJ13_MARK, PJ13MD_010),
        PINMUX_DATA(PINT5_PJ_MARK, PJ13MD_011),
        PINMUX_DATA(PWM2F_MARK, PJ13MD_100),
        PINMUX_DATA(TXD5_MARK, PJ13MD_101),
 
        PINMUX_DATA(PJ12_DATA, PJ12MD_000),
        PINMUX_DATA(DV_DATA12_MARK, PJ12MD_001),
-       PINMUX_DATA(LCD_DATA12_MARK, PJ12MD_010),
+       PINMUX_DATA(LCD_DATA12_PJ12_MARK, PJ12MD_010),
        PINMUX_DATA(PINT4_PJ_MARK, PJ12MD_011),
        PINMUX_DATA(PWM2E_MARK, PJ12MD_100),
        PINMUX_DATA(SCK7_MARK, PJ12MD_101),
 
        PINMUX_DATA(PJ11_DATA, PJ11MD_000),
        PINMUX_DATA(DV_DATA11_MARK, PJ11MD_001),
-       PINMUX_DATA(LCD_DATA11_MARK, PJ11MD_010),
+       PINMUX_DATA(LCD_DATA11_PJ11_MARK, PJ11MD_010),
        PINMUX_DATA(PINT3_PJ_MARK, PJ11MD_011),
        PINMUX_DATA(PWM2D_MARK, PJ11MD_100),
        PINMUX_DATA(SCK6_MARK, PJ11MD_101),
 
        PINMUX_DATA(PJ10_DATA, PJ10MD_000),
        PINMUX_DATA(DV_DATA10_MARK, PJ10MD_001),
-       PINMUX_DATA(LCD_DATA10_MARK, PJ10MD_010),
+       PINMUX_DATA(LCD_DATA10_PJ10_MARK, PJ10MD_010),
        PINMUX_DATA(PINT2_PJ_MARK, PJ10MD_011),
        PINMUX_DATA(PWM2C_MARK, PJ10MD_100),
        PINMUX_DATA(SCK5_MARK, PJ10MD_101),
 
        PINMUX_DATA(PJ9_DATA, PJ9MD_000),
        PINMUX_DATA(DV_DATA9_MARK, PJ9MD_001),
-       PINMUX_DATA(LCD_DATA9_MARK, PJ9MD_010),
+       PINMUX_DATA(LCD_DATA9_PJ9_MARK, PJ9MD_010),
        PINMUX_DATA(PINT1_PJ_MARK, PJ9MD_011),
        PINMUX_DATA(PWM2B_MARK, PJ9MD_100),
        PINMUX_DATA(RTS5_MARK, PJ9MD_101),
 
        PINMUX_DATA(PJ8_DATA, PJ8MD_000),
        PINMUX_DATA(DV_DATA8_MARK, PJ8MD_001),
-       PINMUX_DATA(LCD_DATA8_MARK, PJ8MD_010),
+       PINMUX_DATA(LCD_DATA8_PJ8_MARK, PJ8MD_010),
        PINMUX_DATA(PINT0_PJ_MARK, PJ8MD_011),
        PINMUX_DATA(PWM2A_MARK, PJ8MD_100),
        PINMUX_DATA(CTS5_MARK, PJ8MD_101),
 
        PINMUX_DATA(PJ7_DATA, PJ7MD_000),
        PINMUX_DATA(DV_DATA7_MARK, PJ7MD_001),
-       PINMUX_DATA(LCD_DATA7_MARK, PJ7MD_010),
+       PINMUX_DATA(LCD_DATA7_PJ7_MARK, PJ7MD_010),
        PINMUX_DATA(SD_D2_MARK, PJ7MD_011),
        PINMUX_DATA(PWM1H_MARK, PJ7MD_100),
 
        PINMUX_DATA(PJ6_DATA, PJ6MD_000),
        PINMUX_DATA(DV_DATA6_MARK, PJ6MD_001),
-       PINMUX_DATA(LCD_DATA6_MARK, PJ6MD_010),
+       PINMUX_DATA(LCD_DATA6_PJ6_MARK, PJ6MD_010),
        PINMUX_DATA(SD_D3_MARK, PJ6MD_011),
        PINMUX_DATA(PWM1G_MARK, PJ6MD_100),
 
        PINMUX_DATA(PJ5_DATA, PJ5MD_000),
        PINMUX_DATA(DV_DATA5_MARK, PJ5MD_001),
-       PINMUX_DATA(LCD_DATA5_MARK, PJ5MD_010),
+       PINMUX_DATA(LCD_DATA5_PJ5_MARK, PJ5MD_010),
        PINMUX_DATA(SD_CMD_MARK, PJ5MD_011),
        PINMUX_DATA(PWM1F_MARK, PJ5MD_100),
 
        PINMUX_DATA(PJ4_DATA, PJ4MD_000),
        PINMUX_DATA(DV_DATA4_MARK, PJ4MD_001),
-       PINMUX_DATA(LCD_DATA4_MARK, PJ4MD_010),
+       PINMUX_DATA(LCD_DATA4_PJ4_MARK, PJ4MD_010),
        PINMUX_DATA(SD_CLK_MARK, PJ4MD_011),
        PINMUX_DATA(PWM1E_MARK, PJ4MD_100),
 
        PINMUX_DATA(PJ3_DATA, PJ3MD_000),
        PINMUX_DATA(DV_DATA3_MARK, PJ3MD_001),
-       PINMUX_DATA(LCD_DATA3_MARK, PJ3MD_010),
+       PINMUX_DATA(LCD_DATA3_PJ3_MARK, PJ3MD_010),
        PINMUX_DATA(SD_D0_MARK, PJ3MD_011),
        PINMUX_DATA(PWM1D_MARK, PJ3MD_100),
 
        PINMUX_DATA(PJ2_DATA, PJ2MD_000),
        PINMUX_DATA(DV_DATA2_MARK, PJ2MD_001),
-       PINMUX_DATA(LCD_DATA2_MARK, PJ2MD_010),
+       PINMUX_DATA(LCD_DATA2_PJ2_MARK, PJ2MD_010),
        PINMUX_DATA(SD_D1_MARK, PJ2MD_011),
        PINMUX_DATA(PWM1C_MARK, PJ2MD_100),
 
        PINMUX_DATA(PJ1_DATA, PJ1MD_000),
        PINMUX_DATA(DV_DATA1_MARK, PJ1MD_001),
-       PINMUX_DATA(LCD_DATA1_MARK, PJ1MD_010),
+       PINMUX_DATA(LCD_DATA1_PJ1_MARK, PJ1MD_010),
        PINMUX_DATA(SD_WP_MARK, PJ1MD_011),
        PINMUX_DATA(PWM1B_MARK, PJ1MD_100),
 
        PINMUX_DATA(PJ0_DATA, PJ0MD_000),
        PINMUX_DATA(DV_DATA0_MARK, PJ0MD_001),
-       PINMUX_DATA(LCD_DATA0_MARK, PJ0MD_010),
+       PINMUX_DATA(LCD_DATA0_PJ0_MARK, PJ0MD_010),
        PINMUX_DATA(SD_CD_MARK, PJ0MD_011),
        PINMUX_DATA(PWM1A_MARK, PJ0MD_100),
 };
@@ -1877,30 +1891,55 @@ static struct pinmux_gpio pinmux_gpios[] = {
        PINMUX_GPIO(GPIO_FN_LCD_HSYNC, LCD_HSYNC_MARK),
        PINMUX_GPIO(GPIO_FN_LCD_DE, LCD_DE_MARK),
 
-       PINMUX_GPIO(GPIO_FN_LCD_DATA23, LCD_DATA23_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA22, LCD_DATA22_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA21, LCD_DATA21_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA20, LCD_DATA20_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA19, LCD_DATA19_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA18, LCD_DATA18_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA17, LCD_DATA17_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA16, LCD_DATA16_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA15, LCD_DATA15_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA14, LCD_DATA14_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA13, LCD_DATA13_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA12, LCD_DATA12_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA11, LCD_DATA11_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA10, LCD_DATA10_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA9, LCD_DATA9_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA8, LCD_DATA8_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA7, LCD_DATA7_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA6, LCD_DATA6_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA5, LCD_DATA5_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA4, LCD_DATA4_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA3, LCD_DATA3_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA2, LCD_DATA2_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA1, LCD_DATA1_MARK),
-       PINMUX_GPIO(GPIO_FN_LCD_DATA0, LCD_DATA0_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA23_PG23, LCD_DATA23_PG23_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA22_PG22, LCD_DATA22_PG22_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA21_PG21, LCD_DATA21_PG21_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA20_PG20, LCD_DATA20_PG20_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA19_PG19, LCD_DATA19_PG19_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA18_PG18, LCD_DATA18_PG18_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA17_PG17, LCD_DATA17_PG17_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA16_PG16, LCD_DATA16_PG16_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA15_PG15, LCD_DATA15_PG15_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA14_PG14, LCD_DATA14_PG14_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA13_PG13, LCD_DATA13_PG13_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA12_PG12, LCD_DATA12_PG12_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA11_PG11, LCD_DATA11_PG11_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA10_PG10, LCD_DATA10_PG10_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA9_PG9, LCD_DATA9_PG9_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA8_PG8, LCD_DATA8_PG8_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA7_PG7, LCD_DATA7_PG7_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA6_PG6, LCD_DATA6_PG6_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA5_PG5, LCD_DATA5_PG5_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA4_PG4, LCD_DATA4_PG4_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA3_PG3, LCD_DATA3_PG3_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA2_PG2, LCD_DATA2_PG2_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA1_PG1, LCD_DATA1_PG1_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA0_PG0, LCD_DATA0_PG0_MARK),
+
+       PINMUX_GPIO(GPIO_FN_LCD_DATA23_PJ23, LCD_DATA23_PJ23_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA22_PJ22, LCD_DATA22_PJ22_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA21_PJ21, LCD_DATA21_PJ21_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA20_PJ20, LCD_DATA20_PJ20_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA19_PJ19, LCD_DATA19_PJ19_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA18_PJ18, LCD_DATA18_PJ18_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA17_PJ17, LCD_DATA17_PJ17_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA16_PJ16, LCD_DATA16_PJ16_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA15_PJ15, LCD_DATA15_PJ15_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA14_PJ14, LCD_DATA14_PJ14_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA13_PJ13, LCD_DATA13_PJ13_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA12_PJ12, LCD_DATA12_PJ12_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA11_PJ11, LCD_DATA11_PJ11_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA10_PJ10, LCD_DATA10_PJ10_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA9_PJ9, LCD_DATA9_PJ9_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA8_PJ8, LCD_DATA8_PJ8_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA7_PJ7, LCD_DATA7_PJ7_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA6_PJ6, LCD_DATA6_PJ6_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA5_PJ5, LCD_DATA5_PJ5_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA4_PJ4, LCD_DATA4_PJ4_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA3_PJ3, LCD_DATA3_PJ3_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA2_PJ2, LCD_DATA2_PJ2_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA1_PJ1, LCD_DATA1_PJ1_MARK),
+       PINMUX_GPIO(GPIO_FN_LCD_DATA0_PJ0, LCD_DATA0_PJ0_MARK),
 
        PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK),
 };
index 7b57bf1dc85510c08b40a9f88892ffacbf78c379..ebe7a7d97215e4978252af8a3512821e64148064 100644 (file)
@@ -273,7 +273,7 @@ void __init setup_arch(char **cmdline_p)
        data_resource.start = virt_to_phys(_etext);
        data_resource.end = virt_to_phys(_edata)-1;
        bss_resource.start = virt_to_phys(__bss_start);
-       bss_resource.end = virt_to_phys(_ebss)-1;
+       bss_resource.end = virt_to_phys(__bss_stop)-1;
 
 #ifdef CONFIG_CMDLINE_OVERWRITE
        strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
index 3896f26efa4a5c9466943dbe10bcfd87028c0011..2a0a596ebf67d948663df3009d1ca14c8b09dabc 100644 (file)
@@ -19,7 +19,6 @@ EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(_ebss);
 EXPORT_SYMBOL(empty_zero_page);
 
 #define DECLARE_EXPORT(name)           \
index c98905f71e28ce78a1ab06e7b310653efa2156a9..db88cbf9eafdc815d76d72784c18e4df42b361e5 100644 (file)
@@ -78,7 +78,6 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);
        __init_end = .;
        BSS_SECTION(0, PAGE_SIZE, 4)
-       _ebss = .;                      /* uClinux MTD sucks */
        _end = . ;
 
        STABS_DEBUG
index 84a57761f17e90ee8cfdfd71dfce2b02480002a4..60164e65d66551c4375121e984fd0ea28a9525fa 100644 (file)
@@ -39,7 +39,7 @@
  *
  * Make sure the stack pointer contains a valid address. Valid
  * addresses for kernel stacks are anywhere after the bss
- * (after _ebss) and anywhere in init_thread_union (init_stack).
+ * (after __bss_stop) and anywhere in init_thread_union (init_stack).
  */
 #define STACK_CHECK()                                  \
        mov     #(THREAD_SIZE >> 10), r0;               \
@@ -60,7 +60,7 @@
        cmp/hi  r2, r1;                                 \
        bf      stack_panic;                            \
                                                        \
-       /* If sp > _ebss then we're OK. */              \
+       /* If sp > __bss_stop then we're OK. */         \
        mov.l   .L_ebss, r1;                            \
        cmp/hi  r1, r15;                                \
        bt      1f;                                     \
@@ -70,7 +70,7 @@
        cmp/hs  r1, r15;                                \
        bf      stack_panic;                            \
                                                        \
-       /* If sp > init_stack && sp < _ebss, not OK. */ \
+       /* If sp > init_stack && sp < __bss_stop, not OK. */    \
        add     r0, r1;                                 \
        cmp/hs  r1, r15;                                \
        bt      stack_panic;                            \
@@ -292,8 +292,6 @@ stack_panic:
         nop
 
        .align 2
-.L_ebss:
-       .long   _ebss
 .L_init_thread_union:
        .long   init_thread_union
 .Lpanic:
index 0dc1f578608131002da0b869dcfa7c56b4b149e3..11c6c9603e71f03995a3c17fcdf2f28957d7fa43 100644 (file)
@@ -502,12 +502,12 @@ SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality)
 {
        int ret;
 
-       if (current->personality == PER_LINUX32 &&
-           personality == PER_LINUX)
-               personality = PER_LINUX32;
+       if (personality(current->personality) == PER_LINUX32 &&
+           personality(personality) == PER_LINUX)
+               personality |= PER_LINUX32;
        ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+       if (personality(ret) == PER_LINUX32)
+               ret &= ~PER_LINUX32;
 
        return ret;
 }
index 6026fdd1b2eddedbf9dcff60e1079c176eb0d3d6..d58edf5fefdb6a4a3fdf484f46588cc411727c38 100644 (file)
@@ -2020,6 +2020,9 @@ EXPORT_SYMBOL(_PAGE_CACHE);
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 unsigned long vmemmap_table[VMEMMAP_SIZE];
 
+static long __meminitdata addr_start, addr_end;
+static int __meminitdata node_start;
+
 int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
 {
        unsigned long vstart = (unsigned long) start;
@@ -2050,15 +2053,30 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
 
                        *vmem_pp = pte_base | __pa(block);
 
-                       printk(KERN_INFO "[%p-%p] page_structs=%lu "
-                              "node=%d entry=%lu/%lu\n", start, block, nr,
-                              node,
-                              addr >> VMEMMAP_CHUNK_SHIFT,
-                              VMEMMAP_SIZE);
+                       /* check to see if we have contiguous blocks */
+                       if (addr_end != addr || node_start != node) {
+                               if (addr_start)
+                                       printk(KERN_DEBUG " [%lx-%lx] on node %d\n",
+                                              addr_start, addr_end-1, node_start);
+                               addr_start = addr;
+                               node_start = node;
+                       }
+                       addr_end = addr + VMEMMAP_CHUNK;
                }
        }
        return 0;
 }
+
+void __meminit vmemmap_populate_print_last(void)
+{
+       if (addr_start) {
+               printk(KERN_DEBUG " [%lx-%lx] on node %d\n",
+                      addr_start, addr_end-1, node_start);
+               addr_start = 0;
+               addr_end = 0;
+               node_start = 0;
+       }
+}
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 static void prot_init_common(unsigned long page_none,
index ba2657c492171c5ce5c295d1e1d4ef85391608d8..8ec3a1aa4abd3f612df4a5da31f30c67554d5182 100644 (file)
@@ -1527,7 +1527,7 @@ config SECCOMP
          If unsure, say Y. Only embedded should say N here.
 
 config CC_STACKPROTECTOR
-       bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
+       bool "Enable -fstack-protector buffer overflow detection"
        ---help---
          This option turns on the -fstack-protector GCC feature. This
          feature puts, at the beginning of functions, a canary value on
index b0c5276861ec8cc3b5713b6f83335746f812edde..682e9c210baacb99b86817adbd45ebbd17a30955 100644 (file)
@@ -27,6 +27,10 @@ ifeq ($(CONFIG_X86_32),y)
 
         KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return
 
+        # Never want PIC in a 32-bit kernel, prevent breakage with GCC built
+        # with nonstandard options
+        KBUILD_CFLAGS += -fno-pic
+
         # prevent gcc from keeping the stack 16 byte aligned
         KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
 
index 5a747dd884dbf1097916f46aaf195eb93ebe7b6c..f7535bedc33f3b73ee6c0d0b276435ae4b9fb8be 100644 (file)
@@ -57,7 +57,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
                   -Wall -Wstrict-prototypes \
                   -march=i386 -mregparm=3 \
                   -include $(srctree)/$(src)/code16gcc.h \
-                  -fno-strict-aliasing -fomit-frame-pointer \
+                  -fno-strict-aliasing -fomit-frame-pointer -fno-pic \
                   $(call cc-option, -ffreestanding) \
                   $(call cc-option, -fno-toplevel-reorder,\
                        $(call cc-option, -fno-unit-at-a-time)) \
index 441520e4174f9f08736af4368f0c74e1f1ec5b0b..a3ac52b29cbfc5abd3c178fcfbfe7d7586d6e7f2 100644 (file)
 #define MCI_STATUS_PCC   (1ULL<<57)  /* processor context corrupt */
 #define MCI_STATUS_S    (1ULL<<56)  /* Signaled machine check */
 #define MCI_STATUS_AR   (1ULL<<55)  /* Action required */
+#define MCACOD           0xffff     /* MCA Error Code */
+
+/* Architecturally defined codes from SDM Vol. 3B Chapter 15 */
+#define MCACOD_SCRUB   0x00C0  /* 0xC0-0xCF Memory Scrubbing */
+#define MCACOD_SCRUBMSK        0xfff0
+#define MCACOD_L3WB    0x017A  /* L3 Explicit Writeback */
+#define MCACOD_DATA    0x0134  /* Data Load */
+#define MCACOD_INSTR   0x0150  /* Instruction Fetch */
 
 /* MCi_MISC register defines */
 #define MCI_MISC_ADDR_LSB(m)   ((m) & 0x3f)
index dab39350e51e446917d5b5e302fe1ac2214b10d0..cb4e43bce98ab46e262f3b235765e5ebd6270ddd 100644 (file)
@@ -196,11 +196,16 @@ static inline u32 get_ibs_caps(void) { return 0; }
 extern void perf_events_lapic_init(void);
 
 /*
- * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups.
- * This flag is otherwise unused and ABI specified to be 0, so nobody should
- * care what we do with it.
+ * Abuse bits {3,5} of the cpu eflags register. These flags are otherwise
+ * unused and ABI specified to be 0, so nobody should care what we do with
+ * them.
+ *
+ * EXACT - the IP points to the exact instruction that triggered the
+ *         event (HW bugs exempt).
+ * VM    - original X86_VM_MASK; see set_linear_ip().
  */
 #define PERF_EFLAGS_EXACT      (1UL << 3)
+#define PERF_EFLAGS_VM         (1UL << 5)
 
 struct pt_regs;
 extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
index b315a33867f25963808ebe9fc81ec9889a8deca7..33692eaabab58619c7481cbfc7c6f01be929e5e9 100644 (file)
@@ -12,8 +12,7 @@
  * Simple spin lock operations.  There are two variants, one clears IRQ's
  * on the local processor, one does not.
  *
- * These are fair FIFO ticket locks, which are currently limited to 256
- * CPUs.
+ * These are fair FIFO ticket locks, which support up to 2^16 CPUs.
  *
  * (the type definitions are in asm/spinlock_types.h)
  */
index 95bf99de9058128f320356caa6cad1ce9b2727da..1b8e5a03d942439c4b58a7470f181dcb99b29e85 100644 (file)
@@ -25,10 +25,6 @@ unsigned long acpi_realmode_flags;
 static char temp_stack[4096];
 #endif
 
-asmlinkage void acpi_enter_s3(void)
-{
-       acpi_enter_sleep_state(3, wake_sleep_flags);
-}
 /**
  * acpi_suspend_lowlevel - save kernel state
  *
index 5653a5791ec92291844a55665cc50a0cb402095b..67f59f8c695651977e45d88e15bc66781777f31c 100644 (file)
@@ -2,7 +2,6 @@
  *     Variables and functions used by the code in sleep.c
  */
 
-#include <linux/linkage.h>
 #include <asm/realmode.h>
 
 extern unsigned long saved_video_mode;
@@ -11,7 +10,6 @@ extern long saved_magic;
 extern int wakeup_pmode_return;
 
 extern u8 wake_sleep_flags;
-extern asmlinkage void acpi_enter_s3(void);
 
 extern unsigned long acpi_copy_wakeup_routine(unsigned long);
 extern void wakeup_long64(void);
index 72610839f03b3d45e8fa6adb49a13fe933b477b2..13ab720573e3e31e317ac52f977e168401552f17 100644 (file)
@@ -74,7 +74,9 @@ restore_registers:
 ENTRY(do_suspend_lowlevel)
        call    save_processor_state
        call    save_registers
-       call    acpi_enter_s3
+       pushl   $3
+       call    acpi_enter_sleep_state
+       addl    $4, %esp
 
 #      In case of S3 failure, we'll emerge here.  Jump
 #      to ret_point to recover
index 014d1d28c397076606be9d50f04af06892bf2f03..8ea5164cbd0451a27b9048699f60c2420057edb3 100644 (file)
@@ -71,7 +71,9 @@ ENTRY(do_suspend_lowlevel)
        movq    %rsi, saved_rsi
 
        addq    $8, %rsp
-       call    acpi_enter_s3
+       movl    $3, %edi
+       xorl    %eax, %eax
+       call    acpi_enter_sleep_state
        /* in case something went wrong, restore the machine status and go on */
        jmp     resume_point
 
index 931280ff8299471df09b60033cdb06b46a361677..ced4534baed574f7596b014f979748b1eedc2653 100644 (file)
@@ -165,7 +165,7 @@ static const unsigned char * const k7_nops[ASM_NOP_MAX+2] =
 #endif
 
 #ifdef P6_NOP1
-static const unsigned char  __initconst_or_module p6nops[] =
+static const unsigned char p6nops[] =
 {
        P6_NOP1,
        P6_NOP2,
@@ -224,7 +224,7 @@ void __init arch_init_ideal_nops(void)
                        ideal_nops = intel_nops;
 #endif
                }
-
+               break;
        default:
 #ifdef CONFIG_X86_64
                ideal_nops = k8_nops;
index 406eee7846849990d8f87d53243e6cd171944e17..c265593ec2cdc3df35fda1586aaf91514fab62fa 100644 (file)
@@ -1204,7 +1204,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
        BUG_ON(!cfg->vector);
 
        vector = cfg->vector;
-       for_each_cpu(cpu, cfg->domain)
+       for_each_cpu_and(cpu, cfg->domain, cpu_online_mask)
                per_cpu(vector_irq, cpu)[vector] = -1;
 
        cfg->vector = 0;
@@ -1212,7 +1212,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
 
        if (likely(!cfg->move_in_progress))
                return;
-       for_each_cpu(cpu, cfg->old_domain) {
+       for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) {
                for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
                                                                vector++) {
                        if (per_cpu(vector_irq, cpu)[vector] != irq)
@@ -1356,6 +1356,16 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
        if (!IO_APIC_IRQ(irq))
                return;
 
+       /*
+        * For legacy irqs, cfg->domain starts with cpu 0. Now that IO-APIC
+        * can handle this irq and the apic driver is finialized at this point,
+        * update the cfg->domain.
+        */
+       if (irq < legacy_pic->nr_legacy_irqs &&
+           cpumask_equal(cfg->domain, cpumask_of(0)))
+               apic->vector_allocation_domain(0, cfg->domain,
+                                              apic->target_cpus());
+
        if (assign_irq_vector(irq, cfg, apic->target_cpus()))
                return;
 
index 46d8786d655e402b702cc2f19ba4eab9cb5a62cd..a5fbc3c5fccc5e60d61d9ec8f1d3f9f60a2a0467 100644 (file)
@@ -144,6 +144,8 @@ static int __init x86_xsave_setup(char *s)
 {
        setup_clear_cpu_cap(X86_FEATURE_XSAVE);
        setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
+       setup_clear_cpu_cap(X86_FEATURE_AVX);
+       setup_clear_cpu_cap(X86_FEATURE_AVX2);
        return 1;
 }
 __setup("noxsave", x86_xsave_setup);
index 413c2ced887c66c89b1f49fb18a3bac29604ccb2..13017626f9a85c0948fe99cafa1102c0c9d010da 100644 (file)
@@ -55,13 +55,6 @@ static struct severity {
 #define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S)
 #define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR)
 #define        MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV)
-#define MCACOD 0xffff
-/* Architecturally defined codes from SDM Vol. 3B Chapter 15 */
-#define MCACOD_SCRUB   0x00C0  /* 0xC0-0xCF Memory Scrubbing */
-#define MCACOD_SCRUBMSK        0xfff0
-#define MCACOD_L3WB    0x017A  /* L3 Explicit Writeback */
-#define MCACOD_DATA    0x0134  /* Data Load */
-#define MCACOD_INSTR   0x0150  /* Instruction Fetch */
 
        MCESEV(
                NO, "Invalid",
index 5e095f873e3eb731a42012c5e10310fc238ed9c7..292d0258311c82d04c5ec0aeab43924d00c669b4 100644 (file)
@@ -103,6 +103,8 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
 
 static DEFINE_PER_CPU(struct work_struct, mce_work);
 
+static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
+
 /*
  * CPU/chipset specific EDAC code can register a notifier call here to print
  * MCE errors in a human-readable form.
@@ -650,14 +652,18 @@ EXPORT_SYMBOL_GPL(machine_check_poll);
  * Do a quick check if any of the events requires a panic.
  * This decides if we keep the events around or clear them.
  */
-static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp)
+static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
+                         struct pt_regs *regs)
 {
        int i, ret = 0;
 
        for (i = 0; i < banks; i++) {
                m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
-               if (m->status & MCI_STATUS_VAL)
+               if (m->status & MCI_STATUS_VAL) {
                        __set_bit(i, validp);
+                       if (quirk_no_way_out)
+                               quirk_no_way_out(i, m, regs);
+               }
                if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
                        ret = 1;
        }
@@ -1040,7 +1046,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
        *final = m;
 
        memset(valid_banks, 0, sizeof(valid_banks));
-       no_way_out = mce_no_way_out(&m, &msg, valid_banks);
+       no_way_out = mce_no_way_out(&m, &msg, valid_banks, regs);
 
        barrier();
 
@@ -1418,6 +1424,34 @@ static void __mcheck_cpu_init_generic(void)
        }
 }
 
+/*
+ * During IFU recovery Sandy Bridge -EP4S processors set the RIPV and
+ * EIPV bits in MCG_STATUS to zero on the affected logical processor (SDM
+ * Vol 3B Table 15-20). But this confuses both the code that determines
+ * whether the machine check occurred in kernel or user mode, and also
+ * the severity assessment code. Pretend that EIPV was set, and take the
+ * ip/cs values from the pt_regs that mce_gather_info() ignored earlier.
+ */
+static void quirk_sandybridge_ifu(int bank, struct mce *m, struct pt_regs *regs)
+{
+       if (bank != 0)
+               return;
+       if ((m->mcgstatus & (MCG_STATUS_EIPV|MCG_STATUS_RIPV)) != 0)
+               return;
+       if ((m->status & (MCI_STATUS_OVER|MCI_STATUS_UC|
+                         MCI_STATUS_EN|MCI_STATUS_MISCV|MCI_STATUS_ADDRV|
+                         MCI_STATUS_PCC|MCI_STATUS_S|MCI_STATUS_AR|
+                         MCACOD)) !=
+                        (MCI_STATUS_UC|MCI_STATUS_EN|
+                         MCI_STATUS_MISCV|MCI_STATUS_ADDRV|MCI_STATUS_S|
+                         MCI_STATUS_AR|MCACOD_INSTR))
+               return;
+
+       m->mcgstatus |= MCG_STATUS_EIPV;
+       m->ip = regs->ip;
+       m->cs = regs->cs;
+}
+
 /* Add per CPU specific workarounds here */
 static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
 {
@@ -1515,6 +1549,9 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
                 */
                if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0)
                        mce_bootlog = 0;
+
+               if (c->x86 == 6 && c->x86_model == 45)
+                       quirk_no_way_out = quirk_sandybridge_ifu;
        }
        if (monarch_timeout < 0)
                monarch_timeout = 0;
index 29557aa06dda6a724add1d6be6f7744f2d801d34..915b876edd1e2b8a509786446642302648989a73 100644 (file)
@@ -32,6 +32,8 @@
 #include <asm/smp.h>
 #include <asm/alternative.h>
 #include <asm/timer.h>
+#include <asm/desc.h>
+#include <asm/ldt.h>
 
 #include "perf_event.h"
 
@@ -1738,6 +1740,29 @@ valid_user_frame(const void __user *fp, unsigned long size)
        return (__range_not_ok(fp, size, TASK_SIZE) == 0);
 }
 
+static unsigned long get_segment_base(unsigned int segment)
+{
+       struct desc_struct *desc;
+       int idx = segment >> 3;
+
+       if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) {
+               if (idx > LDT_ENTRIES)
+                       return 0;
+
+               if (idx > current->active_mm->context.size)
+                       return 0;
+
+               desc = current->active_mm->context.ldt;
+       } else {
+               if (idx > GDT_ENTRIES)
+                       return 0;
+
+               desc = __this_cpu_ptr(&gdt_page.gdt[0]);
+       }
+
+       return get_desc_base(desc + idx);
+}
+
 #ifdef CONFIG_COMPAT
 
 #include <asm/compat.h>
@@ -1746,13 +1771,17 @@ static inline int
 perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
 {
        /* 32-bit process in 64-bit kernel. */
+       unsigned long ss_base, cs_base;
        struct stack_frame_ia32 frame;
        const void __user *fp;
 
        if (!test_thread_flag(TIF_IA32))
                return 0;
 
-       fp = compat_ptr(regs->bp);
+       cs_base = get_segment_base(regs->cs);
+       ss_base = get_segment_base(regs->ss);
+
+       fp = compat_ptr(ss_base + regs->bp);
        while (entry->nr < PERF_MAX_STACK_DEPTH) {
                unsigned long bytes;
                frame.next_frame     = 0;
@@ -1765,8 +1794,8 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
                if (!valid_user_frame(fp, sizeof(frame)))
                        break;
 
-               perf_callchain_store(entry, frame.return_address);
-               fp = compat_ptr(frame.next_frame);
+               perf_callchain_store(entry, cs_base + frame.return_address);
+               fp = compat_ptr(ss_base + frame.next_frame);
        }
        return 1;
 }
@@ -1789,6 +1818,12 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
                return;
        }
 
+       /*
+        * We don't know what to do with VM86 stacks.. ignore them for now.
+        */
+       if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
+               return;
+
        fp = (void __user *)regs->bp;
 
        perf_callchain_store(entry, regs->ip);
@@ -1816,16 +1851,50 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
        }
 }
 
-unsigned long perf_instruction_pointer(struct pt_regs *regs)
+/*
+ * Deal with code segment offsets for the various execution modes:
+ *
+ *   VM86 - the good olde 16 bit days, where the linear address is
+ *          20 bits and we use regs->ip + 0x10 * regs->cs.
+ *
+ *   IA32 - Where we need to look at GDT/LDT segment descriptor tables
+ *          to figure out what the 32bit base address is.
+ *
+ *    X32 - has TIF_X32 set, but is running in x86_64
+ *
+ * X86_64 - CS,DS,SS,ES are all zero based.
+ */
+static unsigned long code_segment_base(struct pt_regs *regs)
 {
-       unsigned long ip;
+       /*
+        * If we are in VM86 mode, add the segment offset to convert to a
+        * linear address.
+        */
+       if (regs->flags & X86_VM_MASK)
+               return 0x10 * regs->cs;
+
+       /*
+        * For IA32 we look at the GDT/LDT segment base to convert the
+        * effective IP to a linear address.
+        */
+#ifdef CONFIG_X86_32
+       if (user_mode(regs) && regs->cs != __USER_CS)
+               return get_segment_base(regs->cs);
+#else
+       if (test_thread_flag(TIF_IA32)) {
+               if (user_mode(regs) && regs->cs != __USER32_CS)
+                       return get_segment_base(regs->cs);
+       }
+#endif
+       return 0;
+}
 
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
        if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-               ip = perf_guest_cbs->get_guest_ip();
-       else
-               ip = instruction_pointer(regs);
+               return perf_guest_cbs->get_guest_ip();
 
-       return ip;
+       return regs->ip + code_segment_base(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
@@ -1838,7 +1907,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
                else
                        misc |= PERF_RECORD_MISC_GUEST_KERNEL;
        } else {
-               if (!kernel_ip(regs->ip))
+               if (user_mode(regs))
                        misc |= PERF_RECORD_MISC_USER;
                else
                        misc |= PERF_RECORD_MISC_KERNEL;
index 821d53b696d1408fb1b71faffda28283052d9733..6605a81ba3399fb8c1c9044b0e7aa8c2e22ff882 100644 (file)
@@ -516,6 +516,26 @@ static inline bool kernel_ip(unsigned long ip)
 #endif
 }
 
+/*
+ * Not all PMUs provide the right context information to place the reported IP
+ * into full context. Specifically segment registers are typically not
+ * supplied.
+ *
+ * Assuming the address is a linear address (it is for IBS), we fake the CS and
+ * vm86 mode using the known zero-based code segment and 'fix up' the registers
+ * to reflect this.
+ *
+ * Intel PEBS/LBR appear to typically provide the effective address, nothing
+ * much we can do about that but pray and treat it like a linear address.
+ */
+static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
+{
+       regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS;
+       if (regs->flags & X86_VM_MASK)
+               regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
+       regs->ip = ip;
+}
+
 #ifdef CONFIG_CPU_SUP_AMD
 
 int amd_pmu_init(void);
index da9bcdcd9856666daf006c06ae6e14af4c77bca9..7bfb5bec8630ada6580dd446e8a62de847d12288 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <asm/apic.h>
 
+#include "perf_event.h"
+
 static u32 ibs_caps;
 
 #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
@@ -536,7 +538,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
        if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
                regs.flags &= ~PERF_EFLAGS_EXACT;
        } else {
-               instruction_pointer_set(&regs, ibs_data.regs[1]);
+               set_linear_ip(&regs, ibs_data.regs[1]);
                regs.flags |= PERF_EFLAGS_EXACT;
        }
 
index 382366977d4c7856d2cd354ebccc908da65e1a4b..7f2739e03e79a80fc1baaf203cf3a22eccec54dc 100644 (file)
@@ -1522,8 +1522,16 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr)
        arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
        arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
        arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
+       /*
+        * If PMU counter has PEBS enabled it is not enough to disable counter
+        * on a guest entry since PEBS memory write can overshoot guest entry
+        * and corrupt guest memory. Disabling PEBS solves the problem.
+        */
+       arr[1].msr = MSR_IA32_PEBS_ENABLE;
+       arr[1].host = cpuc->pebs_enabled;
+       arr[1].guest = 0;
 
-       *nr = 1;
+       *nr = 2;
        return arr;
 }
 
index 629ae0b7ad901c88706716966b1fd71415debe19..e38d97bf4259fc579f2b070fef85980ae7aaab7a 100644 (file)
@@ -499,7 +499,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
         * We sampled a branch insn, rewind using the LBR stack
         */
        if (ip == to) {
-               regs->ip = from;
+               set_linear_ip(regs, from);
                return 1;
        }
 
@@ -529,7 +529,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
        } while (to < ip);
 
        if (to == ip) {
-               regs->ip = old_to;
+               set_linear_ip(regs, old_to);
                return 1;
        }
 
@@ -569,7 +569,8 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
         * A possible PERF_SAMPLE_REGS will have to transfer all regs.
         */
        regs = *iregs;
-       regs.ip = pebs->ip;
+       regs.flags = pebs->flags;
+       set_linear_ip(&regs, pebs->ip);
        regs.bp = pebs->bp;
        regs.sp = pebs->sp;
 
index 7563fda9f0339b935c7b40a347409b966f7ffbdc..0a5571080e7453bc9d602061ffbe2c6ad81647a2 100644 (file)
@@ -796,7 +796,6 @@ static struct intel_uncore_type *nhm_msr_uncores[] = {
 
 DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
 DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
-DEFINE_UNCORE_FORMAT_ATTR(mm_cfg, mm_cfg, "config:63");
 DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
 DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");
 
@@ -902,16 +901,21 @@ static struct attribute_group nhmex_uncore_cbox_format_group = {
        .attrs = nhmex_uncore_cbox_formats_attr,
 };
 
+/* msr offset for each instance of cbox */
+static unsigned nhmex_cbox_msr_offsets[] = {
+       0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
+};
+
 static struct intel_uncore_type nhmex_uncore_cbox = {
        .name                   = "cbox",
        .num_counters           = 6,
-       .num_boxes              = 8,
+       .num_boxes              = 10,
        .perf_ctr_bits          = 48,
        .event_ctl              = NHMEX_C0_MSR_PMON_EV_SEL0,
        .perf_ctr               = NHMEX_C0_MSR_PMON_CTR0,
        .event_mask             = NHMEX_PMON_RAW_EVENT_MASK,
        .box_ctl                = NHMEX_C0_MSR_PMON_GLOBAL_CTL,
-       .msr_offset             = NHMEX_C_MSR_OFFSET,
+       .msr_offsets            = nhmex_cbox_msr_offsets,
        .pair_ctr_ctl           = 1,
        .ops                    = &nhmex_uncore_ops,
        .format_group           = &nhmex_uncore_cbox_format_group
@@ -1032,24 +1036,22 @@ static struct intel_uncore_type nhmex_uncore_bbox = {
 
 static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
 {
-       struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-       struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+       struct hw_perf_event *hwc = &event->hw;
+       struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+       struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
 
-       if (event->attr.config & NHMEX_S_PMON_MM_CFG_EN) {
-               reg1->config = event->attr.config1;
-               reg2->config = event->attr.config2;
-       } else {
-               reg1->config = ~0ULL;
-               reg2->config = ~0ULL;
-       }
+       /* only TO_R_PROG_EV event uses the match/mask register */
+       if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) !=
+           NHMEX_S_EVENT_TO_R_PROG_EV)
+               return 0;
 
        if (box->pmu->pmu_idx == 0)
                reg1->reg = NHMEX_S0_MSR_MM_CFG;
        else
                reg1->reg = NHMEX_S1_MSR_MM_CFG;
-
        reg1->idx = 0;
-
+       reg1->config = event->attr.config1;
+       reg2->config = event->attr.config2;
        return 0;
 }
 
@@ -1059,8 +1061,8 @@ static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct per
        struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
        struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
 
-       wrmsrl(reg1->reg, 0);
-       if (reg1->config != ~0ULL || reg2->config != ~0ULL) {
+       if (reg1->idx != EXTRA_REG_NONE) {
+               wrmsrl(reg1->reg, 0);
                wrmsrl(reg1->reg + 1, reg1->config);
                wrmsrl(reg1->reg + 2, reg2->config);
                wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
@@ -1074,7 +1076,6 @@ static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
        &format_attr_edge.attr,
        &format_attr_inv.attr,
        &format_attr_thresh8.attr,
-       &format_attr_mm_cfg.attr,
        &format_attr_match.attr,
        &format_attr_mask.attr,
        NULL,
@@ -1142,6 +1143,9 @@ static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
        EVENT_EXTRA_END
 };
 
+/* Nehalem-EX or Westmere-EX ? */
+bool uncore_nhmex;
+
 static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
 {
        struct intel_uncore_extra_reg *er;
@@ -1171,18 +1175,29 @@ static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64
                return false;
 
        /* mask of the shared fields */
-       mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
+       if (uncore_nhmex)
+               mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
+       else
+               mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
        er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
 
        raw_spin_lock_irqsave(&er->lock, flags);
        /* add mask of the non-shared field if it's in use */
-       if (__BITS_VALUE(atomic_read(&er->ref), idx, 8))
-               mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+       if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
+               if (uncore_nhmex)
+                       mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+               else
+                       mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+       }
 
        if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
                atomic_add(1 << (idx * 8), &er->ref);
-               mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
-                       NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+               if (uncore_nhmex)
+                       mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
+                               NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+               else
+                       mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
+                               WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
                er->config &= ~mask;
                er->config |= (config & mask);
                ret = true;
@@ -1216,7 +1231,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
 
        /* get the non-shared control bits and shift them */
        idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
-       config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+       if (uncore_nhmex)
+               config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+       else
+               config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
        if (new_idx > orig_idx) {
                idx = new_idx - orig_idx;
                config <<= 3 * idx;
@@ -1226,6 +1244,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
        }
 
        /* add the shared control bits back */
+       if (uncore_nhmex)
+               config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+       else
+               config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
        config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
        if (modify) {
                /* adjust the main event selector */
@@ -1264,7 +1286,8 @@ again:
        }
 
        /* for the match/mask registers */
-       if ((uncore_box_is_fake(box) || !reg2->alloc) &&
+       if (reg2->idx != EXTRA_REG_NONE &&
+           (uncore_box_is_fake(box) || !reg2->alloc) &&
            !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
                goto fail;
 
@@ -1278,7 +1301,8 @@ again:
                if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
                        nhmex_mbox_alter_er(event, idx[0], true);
                reg1->alloc |= alloc;
-               reg2->alloc = 1;
+               if (reg2->idx != EXTRA_REG_NONE)
+                       reg2->alloc = 1;
        }
        return NULL;
 fail:
@@ -1342,9 +1366,6 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event
        struct extra_reg *er;
        unsigned msr;
        int reg_idx = 0;
-
-       if (WARN_ON_ONCE(reg1->idx != -1))
-               return -EINVAL;
        /*
         * The mbox events may require 2 extra MSRs at the most. But only
         * the lower 32 bits in these MSRs are significant, so we can use
@@ -1355,11 +1376,6 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event
                        continue;
                if (event->attr.config1 & ~er->valid_mask)
                        return -EINVAL;
-               if (er->idx == __BITS_VALUE(reg1->idx, 0, 8) ||
-                   er->idx == __BITS_VALUE(reg1->idx, 1, 8))
-                       continue;
-               if (WARN_ON_ONCE(reg_idx >= 2))
-                       return -EINVAL;
 
                msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
                if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
@@ -1368,6 +1384,8 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event
                /* always use the 32~63 bits to pass the PLD config */
                if (er->idx == EXTRA_REG_NHMEX_M_PLD)
                        reg_idx = 1;
+               else if (WARN_ON_ONCE(reg_idx > 0))
+                       return -EINVAL;
 
                reg1->idx &= ~(0xff << (reg_idx * 8));
                reg1->reg &= ~(0xffff << (reg_idx * 16));
@@ -1376,17 +1394,21 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event
                reg1->config = event->attr.config1;
                reg_idx++;
        }
-       /* use config2 to pass the filter config */
-       reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
-       if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
-               reg2->config = event->attr.config2;
-       else
-               reg2->config = ~0ULL;
-       if (box->pmu->pmu_idx == 0)
-               reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
-       else
-               reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
-
+       /*
+        * The mbox only provides ability to perform address matching
+        * for the PLD events.
+        */
+       if (reg_idx == 2) {
+               reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
+               if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
+                       reg2->config = event->attr.config2;
+               else
+                       reg2->config = ~0ULL;
+               if (box->pmu->pmu_idx == 0)
+                       reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
+               else
+                       reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
+       }
        return 0;
 }
 
@@ -1422,34 +1444,36 @@ static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct per
                wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
                        nhmex_mbox_shared_reg_config(box, idx));
 
-       wrmsrl(reg2->reg, 0);
-       if (reg2->config != ~0ULL) {
-               wrmsrl(reg2->reg + 1,
-                       reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
-               wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
-                       (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
-               wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
+       if (reg2->idx != EXTRA_REG_NONE) {
+               wrmsrl(reg2->reg, 0);
+               if (reg2->config != ~0ULL) {
+                       wrmsrl(reg2->reg + 1,
+                               reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
+                       wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
+                               (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
+                       wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
+               }
        }
 
        wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
 }
 
-DEFINE_UNCORE_FORMAT_ATTR(count_mode,  count_mode,     "config:2-3");
-DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode,  "config:4-5");
-DEFINE_UNCORE_FORMAT_ATTR(wrap_mode,   wrap_mode,      "config:6");
-DEFINE_UNCORE_FORMAT_ATTR(flag_mode,   flag_mode,      "config:7");
-DEFINE_UNCORE_FORMAT_ATTR(inc_sel,     inc_sel,        "config:9-13");
-DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel,        set_flag_sel,   "config:19-21");
-DEFINE_UNCORE_FORMAT_ATTR(filter_cfg,  filter_cfg,     "config2:63");
-DEFINE_UNCORE_FORMAT_ATTR(filter_match,        filter_match,   "config2:0-33");
-DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask,    "config2:34-61");
-DEFINE_UNCORE_FORMAT_ATTR(dsp,         dsp,            "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(thr,         thr,            "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(fvc,         fvc,            "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(pgt,         pgt,            "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(map,         map,            "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(iss,         iss,            "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(pld,         pld,            "config1:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(count_mode,          count_mode,     "config:2-3");
+DEFINE_UNCORE_FORMAT_ATTR(storage_mode,                storage_mode,   "config:4-5");
+DEFINE_UNCORE_FORMAT_ATTR(wrap_mode,           wrap_mode,      "config:6");
+DEFINE_UNCORE_FORMAT_ATTR(flag_mode,           flag_mode,      "config:7");
+DEFINE_UNCORE_FORMAT_ATTR(inc_sel,             inc_sel,        "config:9-13");
+DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel,                set_flag_sel,   "config:19-21");
+DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en,       filter_cfg_en,  "config2:63");
+DEFINE_UNCORE_FORMAT_ATTR(filter_match,                filter_match,   "config2:0-33");
+DEFINE_UNCORE_FORMAT_ATTR(filter_mask,         filter_mask,    "config2:34-61");
+DEFINE_UNCORE_FORMAT_ATTR(dsp,                 dsp,            "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(thr,                 thr,            "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(fvc,                 fvc,            "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pgt,                 pgt,            "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(map,                 map,            "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(iss,                 iss,            "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pld,                 pld,            "config1:32-63");
 
 static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
        &format_attr_count_mode.attr,
@@ -1458,7 +1482,7 @@ static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
        &format_attr_flag_mode.attr,
        &format_attr_inc_sel.attr,
        &format_attr_set_flag_sel.attr,
-       &format_attr_filter_cfg.attr,
+       &format_attr_filter_cfg_en.attr,
        &format_attr_filter_match.attr,
        &format_attr_filter_mask.attr,
        &format_attr_dsp.attr,
@@ -1482,6 +1506,12 @@ static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
        { /* end: all zeroes */ },
 };
 
+static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
+       INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
+       INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
+       { /* end: all zeroes */ },
+};
+
 static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
        NHMEX_UNCORE_OPS_COMMON_INIT(),
        .enable_event   = nhmex_mbox_msr_enable_event,
@@ -1513,7 +1543,7 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
        struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
        int port;
 
-       /* adjust the main event selector */
+       /* adjust the main event selector and extra register index */
        if (reg1->idx % 2) {
                reg1->idx--;
                hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
@@ -1522,29 +1552,17 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
                hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
        }
 
-       /* adjust address or config of extra register */
+       /* adjust extra register config */
        port = reg1->idx / 6 + box->pmu->pmu_idx * 4;
        switch (reg1->idx % 6) {
-       case 0:
-               reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port);
-               break;
-       case 1:
-               reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port);
-               break;
        case 2:
-               /* the 8~15 bits to the 0~7 bits */
+               /* shift the 8~15 bits to the 0~7 bits */
                reg1->config >>= 8;
                break;
        case 3:
-               /* the 0~7 bits to the 8~15 bits */
+               /* shift the 0~7 bits to the 8~15 bits */
                reg1->config <<= 8;
                break;
-       case 4:
-               reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port);
-               break;
-       case 5:
-               reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port);
-               break;
        };
 }
 
@@ -1671,7 +1689,7 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event
        struct hw_perf_event *hwc = &event->hw;
        struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
        struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
-       int port, idx;
+       int idx;
 
        idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
                NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
@@ -1681,27 +1699,11 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event
        reg1->idx = idx;
        reg1->config = event->attr.config1;
 
-       port = idx / 6 + box->pmu->pmu_idx * 4;
-       idx %= 6;
-       switch (idx) {
-       case 0:
-               reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port);
-               break;
-       case 1:
-               reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port);
-               break;
-       case 2:
-       case 3:
-               reg1->reg = NHMEX_R_MSR_PORTN_QLX_CFG(port);
-               break;
+       switch (idx % 6) {
        case 4:
        case 5:
-               if (idx == 4)
-                       reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port);
-               else
-                       reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port);
-               reg2->config = event->attr.config2;
                hwc->config |= event->attr.config & (~0ULL << 32);
+               reg2->config = event->attr.config2;
                break;
        };
        return 0;
@@ -1727,28 +1729,34 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per
        struct hw_perf_event *hwc = &event->hw;
        struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
        struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-       int idx, er_idx;
+       int idx, port;
 
-       idx = reg1->idx % 6;
-       er_idx = idx;
-       if (er_idx > 2)
-               er_idx--;
-       er_idx += (reg1->idx / 6) * 5;
+       idx = reg1->idx;
+       port = idx / 6 + box->pmu->pmu_idx * 4;
 
-       switch (idx) {
+       switch (idx % 6) {
        case 0:
+               wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config);
+               break;
        case 1:
-               wrmsrl(reg1->reg, reg1->config);
+               wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config);
                break;
        case 2:
        case 3:
-               wrmsrl(reg1->reg, nhmex_rbox_shared_reg_config(box, er_idx));
+               wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port),
+                       nhmex_rbox_shared_reg_config(box, 2 + (idx / 6) * 5));
                break;
        case 4:
+               wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port),
+                       hwc->config >> 32);
+               wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config);
+               wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config);
+               break;
        case 5:
-               wrmsrl(reg1->reg, reg1->config);
-               wrmsrl(reg1->reg + 1, hwc->config >> 32);
-               wrmsrl(reg1->reg + 2, reg2->config);
+               wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port),
+                       hwc->config >> 32);
+               wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config);
+               wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config);
                break;
        };
 
@@ -1756,8 +1764,8 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per
                (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
 }
 
-DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config:32-63");
-DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config1:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63");
 DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
 DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
 DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");
@@ -2303,6 +2311,7 @@ int uncore_pmu_event_init(struct perf_event *event)
        event->hw.idx = -1;
        event->hw.last_tag = ~0ULL;
        event->hw.extra_reg.idx = EXTRA_REG_NONE;
+       event->hw.branch_reg.idx = EXTRA_REG_NONE;
 
        if (event->attr.config == UNCORE_FIXED_EVENT) {
                /* no fixed counter */
@@ -2373,7 +2382,7 @@ static void __init uncore_type_exit(struct intel_uncore_type *type)
        type->attr_groups[1] = NULL;
 }
 
-static void uncore_types_exit(struct intel_uncore_type **types)
+static void __init uncore_types_exit(struct intel_uncore_type **types)
 {
        int i;
        for (i = 0; types[i]; i++)
@@ -2814,7 +2823,13 @@ static int __init uncore_cpu_init(void)
                        snbep_uncore_cbox.num_boxes = max_cores;
                msr_uncores = snbep_msr_uncores;
                break;
-       case 46:
+       case 46: /* Nehalem-EX */
+               uncore_nhmex = true;
+       case 47: /* Westmere-EX aka. Xeon E7 */
+               if (!uncore_nhmex)
+                       nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
+               if (nhmex_uncore_cbox.num_boxes > max_cores)
+                       nhmex_uncore_cbox.num_boxes = max_cores;
                msr_uncores = nhmex_msr_uncores;
                break;
        default:
index f3851892e0770c540c9df3a7da4925da9ecf2198..5b81c1856aacadb95da71cdf7474bc1633ac7ecc 100644 (file)
@@ -5,7 +5,7 @@
 #include "perf_event.h"
 
 #define UNCORE_PMU_NAME_LEN            32
-#define UNCORE_PMU_HRTIMER_INTERVAL    (60 * NSEC_PER_SEC)
+#define UNCORE_PMU_HRTIMER_INTERVAL    (60LL * NSEC_PER_SEC)
 
 #define UNCORE_FIXED_EVENT             0xff
 #define UNCORE_PMC_IDX_MAX_GENERIC     8
 #define NHMEX_S1_MSR_MASK                      0xe5a
 
 #define NHMEX_S_PMON_MM_CFG_EN                 (0x1ULL << 63)
+#define NHMEX_S_EVENT_TO_R_PROG_EV             0
 
 /* NHM-EX Mbox */
 #define NHMEX_M0_MSR_GLOBAL_CTL                        0xca0
                 NHMEX_M_PMON_CTL_INC_SEL_MASK |        \
                 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
 
-
-#define NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK     0x1f
-#define NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK     (0x7 << 5)
-#define NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK      (0x7 << 8)
-#define NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR (1 << 23)
-#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK                  \
-               (NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK |   \
-                NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK |   \
-                NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK  |   \
-                NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR)
+#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK          (((1 << 11) - 1) | (1 << 23))
 #define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n)))
 
+#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK          (((1 << 12) - 1) | (1 << 24))
+#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (12 + 3 * (n)))
+
 /*
  * use the 9~13 bits to select event If the 7th bit is not set,
  * otherwise use the 19~21 bits to select event.
@@ -368,6 +363,7 @@ struct intel_uncore_type {
        unsigned num_shared_regs:8;
        unsigned single_fixed:1;
        unsigned pair_ctr_ctl:1;
+       unsigned *msr_offsets;
        struct event_constraint unconstrainted;
        struct event_constraint *constraints;
        struct intel_uncore_pmu *pmus;
@@ -485,29 +481,31 @@ unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
        return idx * 8 + box->pmu->type->perf_ctr;
 }
 
-static inline
-unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
+static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box)
+{
+       struct intel_uncore_pmu *pmu = box->pmu;
+       return pmu->type->msr_offsets ?
+               pmu->type->msr_offsets[pmu->pmu_idx] :
+               pmu->type->msr_offset * pmu->pmu_idx;
+}
+
+static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
 {
        if (!box->pmu->type->box_ctl)
                return 0;
-       return box->pmu->type->box_ctl +
-               box->pmu->type->msr_offset * box->pmu->pmu_idx;
+       return box->pmu->type->box_ctl + uncore_msr_box_offset(box);
 }
 
-static inline
-unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
+static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
 {
        if (!box->pmu->type->fixed_ctl)
                return 0;
-       return box->pmu->type->fixed_ctl +
-               box->pmu->type->msr_offset * box->pmu->pmu_idx;
+       return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box);
 }
 
-static inline
-unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
+static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
 {
-       return box->pmu->type->fixed_ctr +
-               box->pmu->type->msr_offset * box->pmu->pmu_idx;
+       return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
 }
 
 static inline
@@ -515,7 +513,7 @@ unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
 {
        return box->pmu->type->event_ctl +
                (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
-               box->pmu->type->msr_offset * box->pmu->pmu_idx;
+               uncore_msr_box_offset(box);
 }
 
 static inline
@@ -523,7 +521,7 @@ unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
 {
        return box->pmu->type->perf_ctr +
                (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
-               box->pmu->type->msr_offset * box->pmu->pmu_idx;
+               uncore_msr_box_offset(box);
 }
 
 static inline
index 1f5f1d5d2a022b21a6871c083af70f09b9def90f..d44f7829968e801cf6b32d41be0c5f297971900d 100644 (file)
@@ -270,7 +270,7 @@ void fixup_irqs(void)
 
                if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
                        break_affinity = 1;
-                       affinity = cpu_all_mask;
+                       affinity = cpu_online_mask;
                }
 
                chip = irq_data_get_irq_chip(data);
@@ -328,6 +328,7 @@ void fixup_irqs(void)
                                chip->irq_retrigger(data);
                        raw_spin_unlock(&desc->lock);
                }
+               __this_cpu_write(vector_irq[vector], -1);
        }
 }
 #endif
index 1d5d31ea686be2aaedb2790637674cc0c0fec56b..dc1404bf8e4b4c48bc6a137c372ab3b4396fc376 100644 (file)
@@ -107,7 +107,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 {
        struct setup_data_node *node;
        struct setup_data *data;
-       int error = -ENOMEM;
+       int error;
        struct dentry *d;
        struct page *pg;
        u64 pa_data;
@@ -121,8 +121,10 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 
        while (pa_data) {
                node = kmalloc(sizeof(*node), GFP_KERNEL);
-               if (!node)
+               if (!node) {
+                       error = -ENOMEM;
                        goto err_dir;
+               }
 
                pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
                if (PageHighMem(pg)) {
index 8a2ce8fd41c0e68bbedc6fce685fb52c95502d24..82746f942cd8db4d59a32631049a79146564052e 100644 (file)
@@ -143,11 +143,12 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr,
                                  unsigned int *current_size)
 {
        struct microcode_header_amd *mc_hdr;
-       unsigned int actual_size;
+       unsigned int actual_size, patch_size;
        u16 equiv_cpu_id;
 
        /* size of the current patch we're staring at */
-       *current_size = *(u32 *)(ucode_ptr + 4) + SECTION_HDR_SIZE;
+       patch_size = *(u32 *)(ucode_ptr + 4);
+       *current_size = patch_size + SECTION_HDR_SIZE;
 
        equiv_cpu_id = find_equiv_id();
        if (!equiv_cpu_id)
@@ -174,7 +175,7 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr,
        /*
         * now that the header looks sane, verify its size
         */
-       actual_size = verify_ucode_size(cpu, *current_size, leftover_size);
+       actual_size = verify_ucode_size(cpu, patch_size, leftover_size);
        if (!actual_size)
                return 0;
 
index 97d9a9914ba8d772e522911252261110cfa58677..a3b57a27be880649ac7b0ae4144bc62faf105cbc 100644 (file)
@@ -475,13 +475,26 @@ register_address(struct x86_emulate_ctxt *ctxt, unsigned long reg)
        return address_mask(ctxt, reg);
 }
 
+static void masked_increment(ulong *reg, ulong mask, int inc)
+{
+       assign_masked(reg, *reg + inc, mask);
+}
+
 static inline void
 register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc)
 {
+       ulong mask;
+
        if (ctxt->ad_bytes == sizeof(unsigned long))
-               *reg += inc;
+               mask = ~0UL;
        else
-               *reg = (*reg & ~ad_mask(ctxt)) | ((*reg + inc) & ad_mask(ctxt));
+               mask = ad_mask(ctxt);
+       masked_increment(reg, mask, inc);
+}
+
+static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc)
+{
+       masked_increment(&ctxt->regs[VCPU_REGS_RSP], stack_mask(ctxt), inc);
 }
 
 static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
@@ -1522,8 +1535,8 @@ static int push(struct x86_emulate_ctxt *ctxt, void *data, int bytes)
 {
        struct segmented_address addr;
 
-       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], -bytes);
-       addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]);
+       rsp_increment(ctxt, -bytes);
+       addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
        addr.seg = VCPU_SREG_SS;
 
        return segmented_write(ctxt, addr, data, bytes);
@@ -1542,13 +1555,13 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
        int rc;
        struct segmented_address addr;
 
-       addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]);
+       addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
        addr.seg = VCPU_SREG_SS;
        rc = segmented_read(ctxt, addr, dest, len);
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
-       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], len);
+       rsp_increment(ctxt, len);
        return rc;
 }
 
@@ -1688,8 +1701,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
 
        while (reg >= VCPU_REGS_RAX) {
                if (reg == VCPU_REGS_RSP) {
-                       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP],
-                                                       ctxt->op_bytes);
+                       rsp_increment(ctxt, ctxt->op_bytes);
                        --reg;
                }
 
@@ -2825,7 +2837,7 @@ static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
        rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes);
        if (rc != X86EMUL_CONTINUE)
                return rc;
-       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], ctxt->src.val);
+       rsp_increment(ctxt, ctxt->src.val);
        return X86EMUL_CONTINUE;
 }
 
index 1df8fb9e1d5dafc47000ef644823a748c1b31c91..e498b18f010c7b97480ccf1f1018c87a5f07daa1 100644 (file)
@@ -316,6 +316,11 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
        addr &= 1;
        if (addr == 0) {
                if (val & 0x10) {
+                       u8 edge_irr = s->irr & ~s->elcr;
+                       int i;
+                       bool found;
+                       struct kvm_vcpu *vcpu;
+
                        s->init4 = val & 1;
                        s->last_irr = 0;
                        s->irr &= s->elcr;
@@ -333,6 +338,18 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
                        if (val & 0x08)
                                pr_pic_unimpl(
                                        "level sensitive irq not supported");
+
+                       kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm)
+                               if (kvm_apic_accept_pic_intr(vcpu)) {
+                                       found = true;
+                                       break;
+                               }
+
+
+                       if (found)
+                               for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
+                                       if (edge_irr & (1 << irq))
+                                               pic_clear_isr(s, irq);
                } else if (val & 0x08) {
                        if (val & 0x04)
                                s->poll = 1;
index 01ca00423938515cfe43781403e90bfb84929fc3..7fbd0d273ea83dbec4a330fcb6d14a8ab46462b0 100644 (file)
@@ -4112,17 +4112,22 @@ static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc)
                int idx;
                LIST_HEAD(invalid_list);
 
+               /*
+                * Never scan more than sc->nr_to_scan VM instances.
+                * Will not hit this condition practically since we do not try
+                * to shrink more than one VM and it is very unlikely to see
+                * !n_used_mmu_pages so many times.
+                */
+               if (!nr_to_scan--)
+                       break;
                /*
                 * n_used_mmu_pages is accessed without holding kvm->mmu_lock
                 * here. We may skip a VM instance errorneosly, but we do not
                 * want to shrink a VM that only started to populate its MMU
                 * anyway.
                 */
-               if (kvm->arch.n_used_mmu_pages > 0) {
-                       if (!nr_to_scan--)
-                               break;
+               if (!kvm->arch.n_used_mmu_pages)
                        continue;
-               }
 
                idx = srcu_read_lock(&kvm->srcu);
                spin_lock(&kvm->mmu_lock);
index c39b60707e0262be788b6909d3e46d63d746cadf..c00f03de1b794af8fe65387747813d57ed2885a2 100644 (file)
@@ -1488,13 +1488,6 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
                loadsegment(ds, vmx->host_state.ds_sel);
                loadsegment(es, vmx->host_state.es_sel);
        }
-#else
-       /*
-        * The sysexit path does not restore ds/es, so we must set them to
-        * a reasonable value ourselves.
-        */
-       loadsegment(ds, __USER_DS);
-       loadsegment(es, __USER_DS);
 #endif
        reload_tss();
 #ifdef CONFIG_X86_64
@@ -6370,6 +6363,19 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
 #endif
              );
 
+#ifndef CONFIG_X86_64
+       /*
+        * The sysexit path does not restore ds/es, so we must set them to
+        * a reasonable value ourselves.
+        *
+        * We can't defer this to vmx_load_host_state() since that function
+        * may be executed in interrupt context, which saves and restore segments
+        * around it, nullifying its effect.
+        */
+       loadsegment(ds, __USER_DS);
+       loadsegment(es, __USER_DS);
+#endif
+
        vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
                                  | (1 << VCPU_EXREG_RFLAGS)
                                  | (1 << VCPU_EXREG_CPL)
index 59b59508ff07dc2623887d6be43859215d5bd589..148ed666e311fda2979887d6c9e9a2d440f75ffc 100644 (file)
@@ -806,7 +806,7 @@ EXPORT_SYMBOL_GPL(kvm_rdpmc);
  * kvm-specific. Those are put in the beginning of the list.
  */
 
-#define KVM_SAVE_MSRS_BEGIN    9
+#define KVM_SAVE_MSRS_BEGIN    10
 static u32 msrs_to_save[] = {
        MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
        MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
@@ -925,6 +925,10 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
         */
        getboottime(&boot);
 
+       if (kvm->arch.kvmclock_offset) {
+               struct timespec ts = ns_to_timespec(kvm->arch.kvmclock_offset);
+               boot = timespec_sub(boot, ts);
+       }
        wc.sec = boot.tv_sec;
        wc.nsec = boot.tv_nsec;
        wc.version = version;
@@ -1996,6 +2000,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
        case MSR_KVM_STEAL_TIME:
                data = vcpu->arch.st.msr_val;
                break;
+       case MSR_KVM_PV_EOI_EN:
+               data = vcpu->arch.pv_eoi.msr_val;
+               break;
        case MSR_IA32_P5_MC_ADDR:
        case MSR_IA32_P5_MC_TYPE:
        case MSR_IA32_MCG_CAP:
index f6679a7fb8ca492482f18421d78f438cc9cfba2b..b91e48512425f6f210e9406cbfc666395bad6ad1 100644 (file)
@@ -56,9 +56,16 @@ static int vma_shareable(struct vm_area_struct *vma, unsigned long addr)
 }
 
 /*
- * search for a shareable pmd page for hugetlb.
+ * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc()
+ * and returns the corresponding pte. While this is not necessary for the
+ * !shared pmd case because we can allocate the pmd later as well, it makes the
+ * code much cleaner. pmd allocation is essential for the shared case because
+ * pud has to be populated inside the same i_mmap_mutex section - otherwise
+ * racing tasks could either miss the sharing (see huge_pte_offset) or select a
+ * bad pmd for sharing.
  */
-static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
+static pte_t *
+huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
 {
        struct vm_area_struct *vma = find_vma(mm, addr);
        struct address_space *mapping = vma->vm_file->f_mapping;
@@ -68,9 +75,10 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
        struct vm_area_struct *svma;
        unsigned long saddr;
        pte_t *spte = NULL;
+       pte_t *pte;
 
        if (!vma_shareable(vma, addr))
-               return;
+               return (pte_t *)pmd_alloc(mm, pud, addr);
 
        mutex_lock(&mapping->i_mmap_mutex);
        vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) {
@@ -97,7 +105,9 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
                put_page(virt_to_page(spte));
        spin_unlock(&mm->page_table_lock);
 out:
+       pte = (pte_t *)pmd_alloc(mm, pud, addr);
        mutex_unlock(&mapping->i_mmap_mutex);
+       return pte;
 }
 
 /*
@@ -142,8 +152,9 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
                } else {
                        BUG_ON(sz != PMD_SIZE);
                        if (pud_none(*pud))
-                               huge_pmd_share(mm, addr, pud);
-                       pte = (pte_t *) pmd_alloc(mm, pud, addr);
+                               pte = huge_pmd_share(mm, addr, pud);
+                       else
+                               pte = (pte_t *)pmd_alloc(mm, pud, addr);
                }
        }
        BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
index 931930a96160b2de489b1dc9c955b676c7a250dd..a718e0d23503fdc4bb3149d4ad5c7046458f2a57 100644 (file)
@@ -919,13 +919,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
 
        /*
         * On success we use clflush, when the CPU supports it to
-        * avoid the wbindv. If the CPU does not support it, in the
-        * error case, and during early boot (for EFI) we fall back
-        * to cpa_flush_all (which uses wbinvd):
+        * avoid the wbindv. If the CPU does not support it and in the
+        * error case we fall back to cpa_flush_all (which uses
+        * wbindv):
         */
-       if (early_boot_irqs_disabled)
-               __cpa_flush_all((void *)(long)cache);
-       else if (!ret && cpu_has_clflush) {
+       if (!ret && cpu_has_clflush) {
                if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) {
                        cpa_flush_array(addr, numpages, cache,
                                        cpa.flags, pages);
index 4599c3e8bcb63f39fe618f0075ba9e52e0fbb353..4ddf497ca65beae876d17867d4cd7d32cd37f39b 100644 (file)
@@ -142,23 +142,23 @@ static inline int save_add_info(void) {return 0;}
 #endif
 
 /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
-void __init
+int __init
 acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
 {
        u64 start, end;
        int node, pxm;
 
        if (srat_disabled())
-               return;
+               return -1;
        if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) {
                bad_srat();
-               return;
+               return -1;
        }
        if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
-               return;
+               return -1;
 
        if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info())
-               return;
+               return -1;
        start = ma->base_address;
        end = start + ma->length;
        pxm = ma->proximity_domain;
@@ -168,12 +168,12 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
        if (node < 0) {
                printk(KERN_ERR "SRAT: Too many proximity domains.\n");
                bad_srat();
-               return;
+               return -1;
        }
 
        if (numa_add_memblk(node, start, end) < 0) {
                bad_srat();
-               return;
+               return -1;
        }
 
        node_set(node, numa_nodes_parsed);
@@ -181,6 +181,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
        printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
               node, pxm,
               (unsigned long long) start, (unsigned long long) end - 1);
+       return 0;
 }
 
 void __init acpi_numa_arch_fixup(void) {}
index 2dc29f51e75aadbfaa29a0c70be54ce02b291ea9..92660edaa1e72de7b027034d83bb9905d0aebe3a 100644 (file)
@@ -234,7 +234,22 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
        return status;
 }
 
-static int efi_set_rtc_mmss(unsigned long nowtime)
+static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
+                                            efi_time_cap_t *tc)
+{
+       unsigned long flags;
+       efi_status_t status;
+
+       spin_lock_irqsave(&rtc_lock, flags);
+       efi_call_phys_prelog();
+       status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm),
+                               virt_to_phys(tc));
+       efi_call_phys_epilog();
+       spin_unlock_irqrestore(&rtc_lock, flags);
+       return status;
+}
+
+int efi_set_rtc_mmss(unsigned long nowtime)
 {
        int real_seconds, real_minutes;
        efi_status_t    status;
@@ -263,7 +278,7 @@ static int efi_set_rtc_mmss(unsigned long nowtime)
        return 0;
 }
 
-static unsigned long efi_get_time(void)
+unsigned long efi_get_time(void)
 {
        efi_status_t status;
        efi_time_t eft;
@@ -606,13 +621,18 @@ static int __init efi_runtime_init(void)
        }
        /*
         * We will only need *early* access to the following
-        * EFI runtime service before set_virtual_address_map
+        * two EFI runtime services before set_virtual_address_map
         * is invoked.
         */
+       efi_phys.get_time = (efi_get_time_t *)runtime->get_time;
        efi_phys.set_virtual_address_map =
                (efi_set_virtual_address_map_t *)
                runtime->set_virtual_address_map;
-
+       /*
+        * Make efi_get_time can be called before entering
+        * virtual mode.
+        */
+       efi.get_time = phys_efi_get_time;
        early_iounmap(runtime, sizeof(efi_runtime_services_t));
 
        return 0;
@@ -700,10 +720,12 @@ void __init efi_init(void)
                efi_enabled = 0;
                return;
        }
+#ifdef CONFIG_X86_32
        if (efi_native) {
                x86_platform.get_wallclock = efi_get_time;
                x86_platform.set_wallclock = efi_set_rtc_mmss;
        }
+#endif
 
 #if EFI_DEBUG
        print_efi_memmap();
index b2d534cab25fc1500c456efbde000779d794e229..88692871823f9910aeb071ad44a86d8c5c251411 100644 (file)
@@ -72,7 +72,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ -D_WAKEUP \
                   -Wall -Wstrict-prototypes \
                   -march=i386 -mregparm=3 \
                   -include $(srctree)/$(src)/../../boot/code16gcc.h \
-                  -fno-strict-aliasing -fomit-frame-pointer \
+                  -fno-strict-aliasing -fomit-frame-pointer -fno-pic \
                   $(call cc-option, -ffreestanding) \
                   $(call cc-option, -fno-toplevel-reorder,\
                        $(call cc-option, -fno-unit-at-a-time)) \
index 51171aeff0dc31483cdc6526e641459b0d64deb3..a582bfed95bb05fd1ae4f62060f719856d49a405 100644 (file)
@@ -60,8 +60,8 @@
 51     common  getsockname             sys_getsockname
 52     common  getpeername             sys_getpeername
 53     common  socketpair              sys_socketpair
-54     common  setsockopt              sys_setsockopt
-55     common  getsockopt              sys_getsockopt
+54     64      setsockopt              sys_setsockopt
+55     64      getsockopt              sys_getsockopt
 56     common  clone                   stub_clone
 57     common  fork                    stub_fork
 58     common  vfork                   stub_vfork
 309    common  getcpu                  sys_getcpu
 310    64      process_vm_readv        sys_process_vm_readv
 311    64      process_vm_writev       sys_process_vm_writev
-312    64      kcmp                    sys_kcmp
+312    common  kcmp                    sys_kcmp
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
 538    x32     sendmmsg                compat_sys_sendmmsg
 539    x32     process_vm_readv        compat_sys_process_vm_readv
 540    x32     process_vm_writev       compat_sys_process_vm_writev
+541    x32     setsockopt              compat_sys_setsockopt
+542    x32     getsockopt              compat_sys_getsockopt
index bf4bda6d3e9ad66f19af6e4669063a12739c78db..9642d4a3860239f3203a2ff12dba5543a26ccf4f 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/pci.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
-#include <linux/syscore_ops.h>
 
 #include <xen/xen.h>
 #include <xen/interface/xen.h>
@@ -1470,130 +1469,38 @@ asmlinkage void __init xen_start_kernel(void)
 #endif
 }
 
-#ifdef CONFIG_XEN_PVHVM
-/*
- * The pfn containing the shared_info is located somewhere in RAM. This
- * will cause trouble if the current kernel is doing a kexec boot into a
- * new kernel. The new kernel (and its startup code) can not know where
- * the pfn is, so it can not reserve the page. The hypervisor will
- * continue to update the pfn, and as a result memory corruption occours
- * in the new kernel.
- *
- * One way to work around this issue is to allocate a page in the
- * xen-platform pci device's BAR memory range. But pci init is done very
- * late and the shared_info page is already in use very early to read
- * the pvclock. So moving the pfn from RAM to MMIO is racy because some
- * code paths on other vcpus could access the pfn during the small
- * window when the old pfn is moved to the new pfn. There is even a
- * small window were the old pfn is not backed by a mfn, and during that
- * time all reads return -1.
- *
- * Because it is not known upfront where the MMIO region is located it
- * can not be used right from the start in xen_hvm_init_shared_info.
- *
- * To minimise trouble the move of the pfn is done shortly before kexec.
- * This does not eliminate the race because all vcpus are still online
- * when the syscore_ops will be called. But hopefully there is no work
- * pending at this point in time. Also the syscore_op is run last which
- * reduces the risk further.
- */
-
-static struct shared_info *xen_hvm_shared_info;
-
-static void xen_hvm_connect_shared_info(unsigned long pfn)
+void __ref xen_hvm_init_shared_info(void)
 {
+       int cpu;
        struct xen_add_to_physmap xatp;
+       static struct shared_info *shared_info_page = 0;
 
+       if (!shared_info_page)
+               shared_info_page = (struct shared_info *)
+                       extend_brk(PAGE_SIZE, PAGE_SIZE);
        xatp.domid = DOMID_SELF;
        xatp.idx = 0;
        xatp.space = XENMAPSPACE_shared_info;
-       xatp.gpfn = pfn;
+       xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
        if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
                BUG();
 
-}
-static void xen_hvm_set_shared_info(struct shared_info *sip)
-{
-       int cpu;
-
-       HYPERVISOR_shared_info = sip;
+       HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
 
        /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
         * page, we use it in the event channel upcall and in some pvclock
         * related functions. We don't need the vcpu_info placement
         * optimizations because we don't use any pv_mmu or pv_irq op on
         * HVM.
-        * When xen_hvm_set_shared_info is run at boot time only vcpu 0 is
-        * online but xen_hvm_set_shared_info is run at resume time too and
+        * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is
+        * online but xen_hvm_init_shared_info is run at resume time too and
         * in that case multiple vcpus might be online. */
        for_each_online_cpu(cpu) {
                per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
        }
 }
 
-/* Reconnect the shared_info pfn to a mfn */
-void xen_hvm_resume_shared_info(void)
-{
-       xen_hvm_connect_shared_info(__pa(xen_hvm_shared_info) >> PAGE_SHIFT);
-}
-
-#ifdef CONFIG_KEXEC
-static struct shared_info *xen_hvm_shared_info_kexec;
-static unsigned long xen_hvm_shared_info_pfn_kexec;
-
-/* Remember a pfn in MMIO space for kexec reboot */
-void __devinit xen_hvm_prepare_kexec(struct shared_info *sip, unsigned long pfn)
-{
-       xen_hvm_shared_info_kexec = sip;
-       xen_hvm_shared_info_pfn_kexec = pfn;
-}
-
-static void xen_hvm_syscore_shutdown(void)
-{
-       struct xen_memory_reservation reservation = {
-               .domid = DOMID_SELF,
-               .nr_extents = 1,
-       };
-       unsigned long prev_pfn;
-       int rc;
-
-       if (!xen_hvm_shared_info_kexec)
-               return;
-
-       prev_pfn = __pa(xen_hvm_shared_info) >> PAGE_SHIFT;
-       set_xen_guest_handle(reservation.extent_start, &prev_pfn);
-
-       /* Move pfn to MMIO, disconnects previous pfn from mfn */
-       xen_hvm_connect_shared_info(xen_hvm_shared_info_pfn_kexec);
-
-       /* Update pointers, following hypercall is also a memory barrier */
-       xen_hvm_set_shared_info(xen_hvm_shared_info_kexec);
-
-       /* Allocate new mfn for previous pfn */
-       do {
-               rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
-               if (rc == 0)
-                       msleep(123);
-       } while (rc == 0);
-
-       /* Make sure the previous pfn is really connected to a (new) mfn */
-       BUG_ON(rc != 1);
-}
-
-static struct syscore_ops xen_hvm_syscore_ops = {
-       .shutdown = xen_hvm_syscore_shutdown,
-};
-#endif
-
-/* Use a pfn in RAM, may move to MMIO before kexec. */
-static void __init xen_hvm_init_shared_info(void)
-{
-       /* Remember pointer for resume */
-       xen_hvm_shared_info = extend_brk(PAGE_SIZE, PAGE_SIZE);
-       xen_hvm_connect_shared_info(__pa(xen_hvm_shared_info) >> PAGE_SHIFT);
-       xen_hvm_set_shared_info(xen_hvm_shared_info);
-}
-
+#ifdef CONFIG_XEN_PVHVM
 static void __init init_hvm_pv_info(void)
 {
        int major, minor;
@@ -1644,9 +1551,6 @@ static void __init xen_hvm_guest_init(void)
        init_hvm_pv_info();
 
        xen_hvm_init_shared_info();
-#ifdef CONFIG_KEXEC
-       register_syscore_ops(&xen_hvm_syscore_ops);
-#endif
 
        if (xen_feature(XENFEAT_hvm_callback_vector))
                xen_have_vector_callback = 1;
index 64effdc6da9400c09515af384d3d4b94c8efcb50..d4b255463253c8b3bb824a915f5764cc2992e202 100644 (file)
@@ -194,6 +194,13 @@ RESERVE_BRK(p2m_mid_mfn, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID
  * boundary violation will require three middle nodes. */
 RESERVE_BRK(p2m_mid_identity, PAGE_SIZE * 2 * 3);
 
+/* When we populate back during bootup, the amount of pages can vary. The
+ * max we have is seen is 395979, but that does not mean it can't be more.
+ * Some machines can have 3GB I/O holes even. With early_can_reuse_p2m_middle
+ * it can re-use Xen provided mfn_list array, so we only need to allocate at
+ * most three P2M top nodes. */
+RESERVE_BRK(p2m_populated, PAGE_SIZE * 3);
+
 static inline unsigned p2m_top_index(unsigned long pfn)
 {
        BUG_ON(pfn >= MAX_P2M_PFN);
@@ -570,12 +577,99 @@ static bool __init early_alloc_p2m(unsigned long pfn)
        }
        return true;
 }
+
+/*
+ * Skim over the P2M tree looking at pages that are either filled with
+ * INVALID_P2M_ENTRY or with 1:1 PFNs. If found, re-use that page and
+ * replace the P2M leaf with a p2m_missing or p2m_identity.
+ * Stick the old page in the new P2M tree location.
+ */
+bool __init early_can_reuse_p2m_middle(unsigned long set_pfn, unsigned long set_mfn)
+{
+       unsigned topidx;
+       unsigned mididx;
+       unsigned ident_pfns;
+       unsigned inv_pfns;
+       unsigned long *p2m;
+       unsigned long *mid_mfn_p;
+       unsigned idx;
+       unsigned long pfn;
+
+       /* We only look when this entails a P2M middle layer */
+       if (p2m_index(set_pfn))
+               return false;
+
+       for (pfn = 0; pfn <= MAX_DOMAIN_PAGES; pfn += P2M_PER_PAGE) {
+               topidx = p2m_top_index(pfn);
+
+               if (!p2m_top[topidx])
+                       continue;
+
+               if (p2m_top[topidx] == p2m_mid_missing)
+                       continue;
+
+               mididx = p2m_mid_index(pfn);
+               p2m = p2m_top[topidx][mididx];
+               if (!p2m)
+                       continue;
+
+               if ((p2m == p2m_missing) || (p2m == p2m_identity))
+                       continue;
+
+               if ((unsigned long)p2m == INVALID_P2M_ENTRY)
+                       continue;
+
+               ident_pfns = 0;
+               inv_pfns = 0;
+               for (idx = 0; idx < P2M_PER_PAGE; idx++) {
+                       /* IDENTITY_PFNs are 1:1 */
+                       if (p2m[idx] == IDENTITY_FRAME(pfn + idx))
+                               ident_pfns++;
+                       else if (p2m[idx] == INVALID_P2M_ENTRY)
+                               inv_pfns++;
+                       else
+                               break;
+               }
+               if ((ident_pfns == P2M_PER_PAGE) || (inv_pfns == P2M_PER_PAGE))
+                       goto found;
+       }
+       return false;
+found:
+       /* Found one, replace old with p2m_identity or p2m_missing */
+       p2m_top[topidx][mididx] = (ident_pfns ? p2m_identity : p2m_missing);
+       /* And the other for save/restore.. */
+       mid_mfn_p = p2m_top_mfn_p[topidx];
+       /* NOTE: Even if it is a p2m_identity it should still be point to
+        * a page filled with INVALID_P2M_ENTRY entries. */
+       mid_mfn_p[mididx] = virt_to_mfn(p2m_missing);
+
+       /* Reset where we want to stick the old page in. */
+       topidx = p2m_top_index(set_pfn);
+       mididx = p2m_mid_index(set_pfn);
+
+       /* This shouldn't happen */
+       if (WARN_ON(p2m_top[topidx] == p2m_mid_missing))
+               early_alloc_p2m(set_pfn);
+
+       if (WARN_ON(p2m_top[topidx][mididx] != p2m_missing))
+               return false;
+
+       p2m_init(p2m);
+       p2m_top[topidx][mididx] = p2m;
+       mid_mfn_p = p2m_top_mfn_p[topidx];
+       mid_mfn_p[mididx] = virt_to_mfn(p2m);
+
+       return true;
+}
 bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 {
        if (unlikely(!__set_phys_to_machine(pfn, mfn)))  {
                if (!early_alloc_p2m(pfn))
                        return false;
 
+               if (early_can_reuse_p2m_middle(pfn, mfn))
+                       return __set_phys_to_machine(pfn, mfn);
+
                if (!early_alloc_p2m_middle(pfn, false /* boundary crossover OK!*/))
                        return false;
 
index ead85576d54a6c097f10b9a9d55e2057575e2168..d11ca11d14fc094379e989a6b06fe2e5b2bc72e6 100644 (file)
@@ -78,9 +78,16 @@ static void __init xen_add_extra_mem(u64 start, u64 size)
        memblock_reserve(start, size);
 
        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);
+
+               if (WARN(mfn == pfn, "Trying to over-write 1-1 mapping (pfn: %lx)\n", pfn))
+                       continue;
+               WARN(mfn != INVALID_P2M_ENTRY, "Trying to remove %lx which has %lx mfn!\n",
+                       pfn, mfn);
 
-       for (pfn = PFN_DOWN(start); pfn <= xen_max_p2m_pfn; pfn++)
                __set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
+       }
 }
 
 static unsigned long __init xen_do_chunk(unsigned long start,
index ae8a00c39de4b0d02cfad0722715d0fbd159a1cb..45329c8c226e4c4070f16a791b300265a0bf472b 100644 (file)
@@ -30,7 +30,7 @@ void xen_arch_hvm_post_suspend(int suspend_cancelled)
 {
 #ifdef CONFIG_XEN_PVHVM
        int cpu;
-       xen_hvm_resume_shared_info();
+       xen_hvm_init_shared_info();
        xen_callback_vector();
        xen_unplug_emulated_devices();
        if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
index 1e4329e04e0fbf105467f18b009183c9dcebd2a8..202d4c150154fb31ddb03da8f8144a45f21c02a7 100644 (file)
@@ -41,7 +41,7 @@ void xen_enable_syscall(void);
 void xen_vcpu_restore(void);
 
 void xen_callback_vector(void);
-void xen_hvm_resume_shared_info(void);
+void xen_hvm_init_shared_info(void);
 void xen_unplug_emulated_devices(void);
 
 void __init xen_build_dynamic_phys_to_machine(void);
index 2b461b496a788c11d00616efaf16df121e620160..19cc761cacb2a4b71fe9d4579226025324ffddf5 100644 (file)
@@ -44,6 +44,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        struct request_queue *q = bdev_get_queue(bdev);
        int type = REQ_WRITE | REQ_DISCARD;
        unsigned int max_discard_sectors;
+       unsigned int granularity, alignment, mask;
        struct bio_batch bb;
        struct bio *bio;
        int ret = 0;
@@ -54,18 +55,20 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        if (!blk_queue_discard(q))
                return -EOPNOTSUPP;
 
+       /* Zero-sector (unknown) and one-sector granularities are the same.  */
+       granularity = max(q->limits.discard_granularity >> 9, 1U);
+       mask = granularity - 1;
+       alignment = (bdev_discard_alignment(bdev) >> 9) & mask;
+
        /*
         * Ensure that max_discard_sectors is of the proper
-        * granularity
+        * granularity, so that requests stay aligned after a split.
         */
        max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9);
+       max_discard_sectors = round_down(max_discard_sectors, granularity);
        if (unlikely(!max_discard_sectors)) {
                /* Avoid infinite loop below. Being cautious never hurts. */
                return -EOPNOTSUPP;
-       } else if (q->limits.discard_granularity) {
-               unsigned int disc_sects = q->limits.discard_granularity >> 9;
-
-               max_discard_sectors &= ~(disc_sects - 1);
        }
 
        if (flags & BLKDEV_DISCARD_SECURE) {
@@ -79,25 +82,37 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        bb.wait = &wait;
 
        while (nr_sects) {
+               unsigned int req_sects;
+               sector_t end_sect;
+
                bio = bio_alloc(gfp_mask, 1);
                if (!bio) {
                        ret = -ENOMEM;
                        break;
                }
 
+               req_sects = min_t(sector_t, nr_sects, max_discard_sectors);
+
+               /*
+                * If splitting a request, and the next starting sector would be
+                * misaligned, stop the discard at the previous aligned sector.
+                */
+               end_sect = sector + req_sects;
+               if (req_sects < nr_sects && (end_sect & mask) != alignment) {
+                       end_sect =
+                               round_down(end_sect - alignment, granularity)
+                               + alignment;
+                       req_sects = end_sect - sector;
+               }
+
                bio->bi_sector = sector;
                bio->bi_end_io = bio_batch_end_io;
                bio->bi_bdev = bdev;
                bio->bi_private = &bb;
 
-               if (nr_sects > max_discard_sectors) {
-                       bio->bi_size = max_discard_sectors << 9;
-                       nr_sects -= max_discard_sectors;
-                       sector += max_discard_sectors;
-               } else {
-                       bio->bi_size = nr_sects << 9;
-                       nr_sects = 0;
-               }
+               bio->bi_size = req_sects << 9;
+               nr_sects -= req_sects;
+               sector = end_sect;
 
                atomic_inc(&bb.done);
                submit_bio(type, bio);
index 160035f548823482968bcd58298fcf9c309e7d62..e76279e411622519eebb54d4802eb11b796788db 100644 (file)
@@ -110,6 +110,49 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
        return 0;
 }
 
+static void
+__blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
+                    struct scatterlist *sglist, struct bio_vec **bvprv,
+                    struct scatterlist **sg, int *nsegs, int *cluster)
+{
+
+       int nbytes = bvec->bv_len;
+
+       if (*bvprv && *cluster) {
+               if ((*sg)->length + nbytes > queue_max_segment_size(q))
+                       goto new_segment;
+
+               if (!BIOVEC_PHYS_MERGEABLE(*bvprv, bvec))
+                       goto new_segment;
+               if (!BIOVEC_SEG_BOUNDARY(q, *bvprv, bvec))
+                       goto new_segment;
+
+               (*sg)->length += nbytes;
+       } else {
+new_segment:
+               if (!*sg)
+                       *sg = sglist;
+               else {
+                       /*
+                        * If the driver previously mapped a shorter
+                        * list, we could see a termination bit
+                        * prematurely unless it fully inits the sg
+                        * table on each mapping. We KNOW that there
+                        * must be more entries here or the driver
+                        * would be buggy, so force clear the
+                        * termination bit to avoid doing a full
+                        * sg_init_table() in drivers for each command.
+                        */
+                       (*sg)->page_link &= ~0x02;
+                       *sg = sg_next(*sg);
+               }
+
+               sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
+               (*nsegs)++;
+       }
+       *bvprv = bvec;
+}
+
 /*
  * map a request to scatterlist, return number of sg entries setup. Caller
  * must make sure sg can hold rq->nr_phys_segments entries
@@ -131,41 +174,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
        bvprv = NULL;
        sg = NULL;
        rq_for_each_segment(bvec, rq, iter) {
-               int nbytes = bvec->bv_len;
-
-               if (bvprv && cluster) {
-                       if (sg->length + nbytes > queue_max_segment_size(q))
-                               goto new_segment;
-
-                       if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
-                               goto new_segment;
-                       if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
-                               goto new_segment;
-
-                       sg->length += nbytes;
-               } else {
-new_segment:
-                       if (!sg)
-                               sg = sglist;
-                       else {
-                               /*
-                                * If the driver previously mapped a shorter
-                                * list, we could see a termination bit
-                                * prematurely unless it fully inits the sg
-                                * table on each mapping. We KNOW that there
-                                * must be more entries here or the driver
-                                * would be buggy, so force clear the
-                                * termination bit to avoid doing a full
-                                * sg_init_table() in drivers for each command.
-                                */
-                               sg->page_link &= ~0x02;
-                               sg = sg_next(sg);
-                       }
-
-                       sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset);
-                       nsegs++;
-               }
-               bvprv = bvec;
+               __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+                                    &nsegs, &cluster);
        } /* segments in rq */
 
 
@@ -199,6 +209,43 @@ new_segment:
 }
 EXPORT_SYMBOL(blk_rq_map_sg);
 
+/**
+ * blk_bio_map_sg - map a bio to a scatterlist
+ * @q: request_queue in question
+ * @bio: bio being mapped
+ * @sglist: scatterlist being mapped
+ *
+ * Note:
+ *    Caller must make sure sg can hold bio->bi_phys_segments entries
+ *
+ * Will return the number of sg entries setup
+ */
+int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
+                  struct scatterlist *sglist)
+{
+       struct bio_vec *bvec, *bvprv;
+       struct scatterlist *sg;
+       int nsegs, cluster;
+       unsigned long i;
+
+       nsegs = 0;
+       cluster = blk_queue_cluster(q);
+
+       bvprv = NULL;
+       sg = NULL;
+       bio_for_each_segment(bvec, bio, i) {
+               __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+                                    &nsegs, &cluster);
+       } /* segments in bio */
+
+       if (sg)
+               sg_mark_end(sg);
+
+       BUG_ON(bio->bi_phys_segments && nsegs > bio->bi_phys_segments);
+       return nsegs;
+}
+EXPORT_SYMBOL(blk_bio_map_sg);
+
 static inline int ll_new_hw_segment(struct request_queue *q,
                                    struct request *req,
                                    struct bio *bio)
index cac7366957c376cedb2341753520e6f32516572c..d839723303c856ae221bdf54ec1de93544698d95 100644 (file)
@@ -835,7 +835,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v)
 
 static void *show_partition_start(struct seq_file *seqf, loff_t *pos)
 {
-       static void *p;
+       void *p;
 
        p = disk_seqf_start(seqf, pos);
        if (!IS_ERR_OR_NULL(p) && !*pos)
index ac7034129f3f9e656d6cbf537dc063a2e49ba614..d5fdd36190cce3f385011b30a1f5c729a5b6a4dd 100644 (file)
@@ -69,7 +69,9 @@ static const struct acpi_device_id ac_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, ac_device_ids);
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_ac_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
 
 static struct acpi_driver acpi_ac_driver = {
@@ -313,6 +315,7 @@ static int acpi_ac_add(struct acpi_device *device)
        return result;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_ac_resume(struct device *dev)
 {
        struct acpi_ac *ac;
@@ -332,6 +335,7 @@ static int acpi_ac_resume(struct device *dev)
                kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
        return 0;
 }
+#endif
 
 static int acpi_ac_remove(struct acpi_device *device, int type)
 {
index 5ccb99ae3a6fae1872a13ab40755aa4ecd693106..5de4ec72766d653924068cb6887d07573ef93539 100644 (file)
@@ -83,22 +83,22 @@ acpi_status acpi_hw_clear_acpi_status(void);
 /*
  * hwsleep - sleep/wake support (Legacy sleep registers)
  */
-acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags);
+acpi_status acpi_hw_legacy_sleep(u8 sleep_state);
 
-acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags);
+acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state);
 
-acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags);
+acpi_status acpi_hw_legacy_wake(u8 sleep_state);
 
 /*
  * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers)
  */
 void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument);
 
-acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags);
+acpi_status acpi_hw_extended_sleep(u8 sleep_state);
 
-acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags);
+acpi_status acpi_hw_extended_wake_prep(u8 sleep_state);
 
-acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags);
+acpi_status acpi_hw_extended_wake(u8 sleep_state);
 
 /*
  * hwvalid - Port I/O with validation
index 48518dac534230a8f59ee7bbfe1e36475396bb19..94996f9ae3ad164636364af38d6ce0b2524cdd72 100644 (file)
@@ -90,7 +90,6 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument)
  * FUNCTION:    acpi_hw_extended_sleep
  *
  * PARAMETERS:  sleep_state         - Which sleep state to enter
- *              flags               - ACPI_EXECUTE_GTS to run optional method
  *
  * RETURN:      Status
  *
@@ -100,7 +99,7 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument)
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags)
+acpi_status acpi_hw_extended_sleep(u8 sleep_state)
 {
        acpi_status status;
        u8 sleep_type_value;
@@ -125,12 +124,6 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags)
 
        acpi_gbl_system_awake_and_running = FALSE;
 
-       /* Optionally execute _GTS (Going To Sleep) */
-
-       if (flags & ACPI_EXECUTE_GTS) {
-               acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state);
-       }
-
        /* Flush caches, as per ACPI specification */
 
        ACPI_FLUSH_CPU_CACHE();
@@ -172,7 +165,6 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags)
  * FUNCTION:    acpi_hw_extended_wake_prep
  *
  * PARAMETERS:  sleep_state         - Which sleep state we just exited
- *              flags               - ACPI_EXECUTE_BFS to run optional method
  *
  * RETURN:      Status
  *
@@ -181,7 +173,7 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags)
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags)
+acpi_status acpi_hw_extended_wake_prep(u8 sleep_state)
 {
        acpi_status status;
        u8 sleep_type_value;
@@ -200,11 +192,6 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags)
                                 &acpi_gbl_FADT.sleep_control);
        }
 
-       /* Optionally execute _BFS (Back From Sleep) */
-
-       if (flags & ACPI_EXECUTE_BFS) {
-               acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state);
-       }
        return_ACPI_STATUS(AE_OK);
 }
 
@@ -222,7 +209,7 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags)
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags)
+acpi_status acpi_hw_extended_wake(u8 sleep_state)
 {
        ACPI_FUNCTION_TRACE(hw_extended_wake);
 
index 9960fe9ef5334f719ed4e5cbd8cb2cbef530a2aa..3fddde056a5e1774e2e208f2478ce07d53fa5bf5 100644 (file)
@@ -56,7 +56,6 @@ ACPI_MODULE_NAME("hwsleep")
  * FUNCTION:    acpi_hw_legacy_sleep
  *
  * PARAMETERS:  sleep_state         - Which sleep state to enter
- *              flags               - ACPI_EXECUTE_GTS to run optional method
  *
  * RETURN:      Status
  *
@@ -64,7 +63,7 @@ ACPI_MODULE_NAME("hwsleep")
  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
-acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags)
+acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
 {
        struct acpi_bit_register_info *sleep_type_reg_info;
        struct acpi_bit_register_info *sleep_enable_reg_info;
@@ -110,12 +109,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags)
                return_ACPI_STATUS(status);
        }
 
-       /* Optionally execute _GTS (Going To Sleep) */
-
-       if (flags & ACPI_EXECUTE_GTS) {
-               acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state);
-       }
-
        /* Get current value of PM1A control */
 
        status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
@@ -214,7 +207,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags)
  * FUNCTION:    acpi_hw_legacy_wake_prep
  *
  * PARAMETERS:  sleep_state         - Which sleep state we just exited
- *              flags               - ACPI_EXECUTE_BFS to run optional method
  *
  * RETURN:      Status
  *
@@ -224,7 +216,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags)
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags)
+acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
 {
        acpi_status status;
        struct acpi_bit_register_info *sleep_type_reg_info;
@@ -275,11 +267,6 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags)
                }
        }
 
-       /* Optionally execute _BFS (Back From Sleep) */
-
-       if (flags & ACPI_EXECUTE_BFS) {
-               acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state);
-       }
        return_ACPI_STATUS(status);
 }
 
@@ -288,7 +275,6 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags)
  * FUNCTION:    acpi_hw_legacy_wake
  *
  * PARAMETERS:  sleep_state         - Which sleep state we just exited
- *              flags               - Reserved, set to zero
  *
  * RETURN:      Status
  *
@@ -297,7 +283,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags)
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags)
+acpi_status acpi_hw_legacy_wake(u8 sleep_state)
 {
        acpi_status status;
 
index f8684bfe79079ba170c727b96d7ea404a91ee604..1f165a750ae28736ca5066c908d5ade37ba4740e 100644 (file)
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("hwxfsleep")
 
 /* Local prototypes */
 static acpi_status
-acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id);
+acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id);
 
 /*
  * Dispatch table used to efficiently branch to the various sleep
@@ -235,7 +235,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
  *
  ******************************************************************************/
 static acpi_status
-acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id)
+acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id)
 {
        acpi_status status;
        struct acpi_sleep_functions *sleep_functions =
@@ -248,11 +248,11 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id)
         * use the extended sleep registers
         */
        if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) {
-               status = sleep_functions->extended_function(sleep_state, flags);
+               status = sleep_functions->extended_function(sleep_state);
        } else {
                /* Legacy sleep */
 
-               status = sleep_functions->legacy_function(sleep_state, flags);
+               status = sleep_functions->legacy_function(sleep_state);
        }
 
        return (status);
@@ -262,7 +262,7 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id)
         * For the case where reduced-hardware-only code is being generated,
         * we know that only the extended sleep registers are available
         */
-       status = sleep_functions->extended_function(sleep_state, flags);
+       status = sleep_functions->extended_function(sleep_state);
        return (status);
 
 #endif                         /* !ACPI_REDUCED_HARDWARE */
@@ -349,7 +349,6 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
  * FUNCTION:    acpi_enter_sleep_state
  *
  * PARAMETERS:  sleep_state         - Which sleep state to enter
- *              flags               - ACPI_EXECUTE_GTS to run optional method
  *
  * RETURN:      Status
  *
@@ -357,7 +356,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
-acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags)
+acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 {
        acpi_status status;
 
@@ -371,7 +370,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags)
        }
 
        status =
-           acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_SLEEP_FUNCTION_ID);
+           acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID);
        return_ACPI_STATUS(status);
 }
 
@@ -391,14 +390,14 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
  *              Called with interrupts DISABLED.
  *
  ******************************************************************************/
-acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags)
+acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
 {
        acpi_status status;
 
        ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
 
        status =
-           acpi_hw_sleep_dispatch(sleep_state, flags,
+           acpi_hw_sleep_dispatch(sleep_state,
                                   ACPI_WAKE_PREP_FUNCTION_ID);
        return_ACPI_STATUS(status);
 }
@@ -423,8 +422,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
 
        ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
 
-
-       status = acpi_hw_sleep_dispatch(sleep_state, 0, ACPI_WAKE_FUNCTION_ID);
+       status = acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_FUNCTION_ID);
        return_ACPI_STATUS(status);
 }
 
index ea4c6d52605a2af79f141efab1f2615c87b0cab1..29e51bc013838c5d33cf1df0089331ae3380951b 100644 (file)
@@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature,
 
        return (AE_NOT_FOUND);
 }
+ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
 
 acpi_status
 acpi_get_table(char *signature,
index ff2c876ec412980a8f9a73188f925c964ecae0ad..45e3e1759fb88c09ddd401921d2a4ea035431bff 100644 (file)
@@ -1052,6 +1052,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 /* this is needed to learn about changes made in suspended state */
 static int acpi_battery_resume(struct device *dev)
 {
@@ -1068,6 +1069,7 @@ static int acpi_battery_resume(struct device *dev)
        acpi_battery_update(battery);
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
 
index 79d4c22f7a6d82c21e786b591f02f8bfe28b0f43..314a3b84bbc7e2626a227a4ef2a620204dbf2434 100644 (file)
@@ -78,7 +78,9 @@ static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
 static void acpi_button_notify(struct acpi_device *device, u32 event);
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_button_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume);
 
 static struct acpi_driver acpi_button_driver = {
@@ -310,6 +312,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
        }
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_button_resume(struct device *dev)
 {
        struct acpi_device *device = to_acpi_device(dev);
@@ -319,6 +322,7 @@ static int acpi_button_resume(struct device *dev)
                return acpi_lid_send_state(device);
        return 0;
 }
+#endif
 
 static int acpi_button_add(struct acpi_device *device)
 {
index 669d9ee80d1678b7665a3b4b8b2ad709743a44aa..bc36a476f1abf139586391c4e490cad56aff4368 100644 (file)
@@ -53,8 +53,10 @@ static const struct acpi_device_id fan_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, fan_device_ids);
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_fan_suspend(struct device *dev);
 static int acpi_fan_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume);
 
 static struct acpi_driver acpi_fan_driver = {
@@ -184,6 +186,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_fan_suspend(struct device *dev)
 {
        if (!dev)
@@ -207,6 +210,7 @@ static int acpi_fan_resume(struct device *dev)
 
        return result;
 }
+#endif
 
 static int __init acpi_fan_init(void)
 {
index e56f3be7b07d36fceb32dce25ede0fa35308f0e7..cb31298ca684f5d99578ada635eb2b011bd07b67 100644 (file)
@@ -237,6 +237,8 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header,
        return 0;
 }
 
+static int __initdata parsed_numa_memblks;
+
 static int __init
 acpi_parse_memory_affinity(struct acpi_subtable_header * header,
                           const unsigned long end)
@@ -250,8 +252,8 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header,
        acpi_table_print_srat_entry(header);
 
        /* let architecture-dependent part to do it */
-       acpi_numa_memory_affinity_init(memory_affinity);
-
+       if (!acpi_numa_memory_affinity_init(memory_affinity))
+               parsed_numa_memblks++;
        return 0;
 }
 
@@ -304,8 +306,10 @@ int __init acpi_numa_init(void)
 
        acpi_numa_arch_fixup();
 
-       if (cnt <= 0)
-               return cnt ?: -ENOENT;
+       if (cnt < 0)
+               return cnt;
+       else if (!parsed_numa_memblks)
+               return -ENOENT;
        return 0;
 }
 
index ec54014c321c5ffd72cf46cc14d877ecbdec1925..72a2c98bc4298e8518e7d2b388f0e2d5d3abdc5f 100644 (file)
@@ -573,8 +573,15 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
                        OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
        if (pci_msi_enabled())
                flags |= OSC_MSI_SUPPORT;
-       if (flags != base_flags)
-               acpi_pci_osc_support(root, flags);
+       if (flags != base_flags) {
+               status = acpi_pci_osc_support(root, flags);
+               if (ACPI_FAILURE(status)) {
+                       dev_info(root->bus->bridge, "ACPI _OSC support "
+                               "notification failed, disabling PCIe ASPM\n");
+                       pcie_no_aspm();
+                       flags = base_flags;
+               }
+       }
 
        if (!pcie_ports_disabled
            && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
index 215ecd09740888be80ce50bbd4ffb74f292c9753..fc1803414629d8233b0d6f11819efd166838952e 100644 (file)
@@ -67,7 +67,9 @@ static const struct acpi_device_id power_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, power_device_ids);
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_power_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume);
 
 static struct acpi_driver acpi_power_driver = {
@@ -775,6 +777,7 @@ static int acpi_power_remove(struct acpi_device *device, int type)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_power_resume(struct device *dev)
 {
        int result = 0, state;
@@ -803,6 +806,7 @@ static int acpi_power_resume(struct device *dev)
 
        return result;
 }
+#endif
 
 int __init acpi_power_init(void)
 {
index ff8e04f2fab40eb7ea14693a2ba70babe1ec8797..bfc31cb0dd3eac96292af65535c2ee4554cdbf10 100644 (file)
@@ -437,7 +437,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
                /* Normal CPU soft online event */
                } else {
                        acpi_processor_ppc_has_changed(pr, 0);
-                       acpi_processor_cst_has_changed(pr);
+                       acpi_processor_hotplug(pr);
                        acpi_processor_reevaluate_tstate(pr, action);
                        acpi_processor_tstate_has_changed(pr);
                }
index c0b9aa5faf4cdfd8d354fa89e8204704714cccf1..ff0740e0a9c248fc932992e56d23540a59489a55 100644 (file)
@@ -988,6 +988,7 @@ static void acpi_sbs_rmdirs(void)
 #endif
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_sbs_resume(struct device *dev)
 {
        struct acpi_sbs *sbs;
@@ -997,6 +998,7 @@ static int acpi_sbs_resume(struct device *dev)
        acpi_sbs_callback(sbs);
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume);
 
index 7a7a9c929247e6faaecbeca3c9863f02abc1c283..fdcdbb652915a32340d91a7d6e6fcce15c3ee602 100644 (file)
 #include "internal.h"
 #include "sleep.h"
 
-u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS;
-static unsigned int gts, bfs;
-static int set_param_wake_flag(const char *val, struct kernel_param *kp)
-{
-       int ret = param_set_int(val, kp);
-
-       if (ret)
-               return ret;
-
-       if (kp->arg == (const char *)&gts) {
-               if (gts)
-                       wake_sleep_flags |= ACPI_EXECUTE_GTS;
-               else
-                       wake_sleep_flags &= ~ACPI_EXECUTE_GTS;
-       }
-       if (kp->arg == (const char *)&bfs) {
-               if (bfs)
-                       wake_sleep_flags |= ACPI_EXECUTE_BFS;
-               else
-                       wake_sleep_flags &= ~ACPI_EXECUTE_BFS;
-       }
-       return ret;
-}
-module_param_call(gts, set_param_wake_flag, param_get_int, &gts, 0644);
-module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644);
-MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
-MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
-
 static u8 sleep_states[ACPI_S_STATE_COUNT];
-static bool pwr_btn_event_pending;
 
 static void acpi_sleep_tts_switch(u32 acpi_state)
 {
@@ -110,6 +81,7 @@ static int acpi_sleep_prepare(u32 acpi_state)
 
 #ifdef CONFIG_ACPI_SLEEP
 static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+static bool pwr_btn_event_pending;
 
 /*
  * The ACPI specification wants us to save NVS memory regions during hibernation
@@ -305,7 +277,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
        switch (acpi_state) {
        case ACPI_STATE_S1:
                barrier();
-               status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags);
+               status = acpi_enter_sleep_state(acpi_state);
                break;
 
        case ACPI_STATE_S3:
@@ -319,8 +291,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
        /* This violates the spec but is required for bug compatibility. */
        acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
 
-       /* Reprogram control registers and execute _BFS */
-       acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags);
+       /* Reprogram control registers */
+       acpi_leave_sleep_state_prep(acpi_state);
 
        /* ACPI 3.0 specs (P62) says that it's the responsibility
         * of the OSPM to clear the status bit [ implying that the
@@ -603,9 +575,9 @@ static int acpi_hibernation_enter(void)
        ACPI_FLUSH_CPU_CACHE();
 
        /* This shouldn't return.  If it returns, we have a problem */
-       status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags);
-       /* Reprogram control registers and execute _BFS */
-       acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);
+       status = acpi_enter_sleep_state(ACPI_STATE_S4);
+       /* Reprogram control registers */
+       acpi_leave_sleep_state_prep(ACPI_STATE_S4);
 
        return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
@@ -617,8 +589,8 @@ static void acpi_hibernation_leave(void)
         * enable it here.
         */
        acpi_enable();
-       /* Reprogram control registers and execute _BFS */
-       acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);
+       /* Reprogram control registers */
+       acpi_leave_sleep_state_prep(ACPI_STATE_S4);
        /* Check the hardware signature */
        if (facs && s4_hardware_signature != facs->hardware_signature) {
                printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
@@ -892,33 +864,7 @@ static void acpi_power_off(void)
        /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
        printk(KERN_DEBUG "%s called\n", __func__);
        local_irq_disable();
-       acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags);
-}
-
-/*
- * ACPI 2.0 created the optional _GTS and _BFS,
- * but industry adoption has been neither rapid nor broad.
- *
- * Linux gets into trouble when it executes poorly validated
- * paths through the BIOS, so disable _GTS and _BFS by default,
- * but do speak up and offer the option to enable them.
- */
-static void __init acpi_gts_bfs_check(void)
-{
-       acpi_handle dummy;
-
-       if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy)))
-       {
-               printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n");
-               printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, "
-                       "please notify linux-acpi@vger.kernel.org\n");
-       }
-       if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy)))
-       {
-               printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n");
-               printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, "
-                       "please notify linux-acpi@vger.kernel.org\n");
-       }
+       acpi_enter_sleep_state(ACPI_STATE_S5);
 }
 
 int __init acpi_sleep_init(void)
@@ -979,6 +925,5 @@ int __init acpi_sleep_init(void)
         * object can also be evaluated when the system enters S5.
         */
        register_reboot_notifier(&tts_notifier);
-       acpi_gts_bfs_check();
        return 0;
 }
index 240a24400976929c663b9b3f8ce8bafa36435d5f..7c3f98ba4afefd00686fffc36283ad783a3e4798 100644 (file)
@@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp)
 {
        int result = 0;
 
-       if (!strncmp(val, "enable", strlen("enable"))) {
+       if (!strncmp(val, "enable", sizeof("enable") - 1)) {
                result = acpi_debug_trace(trace_method_name, trace_debug_level,
                                          trace_debug_layer, 0);
                if (result)
@@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp)
                goto exit;
        }
 
-       if (!strncmp(val, "disable", strlen("disable"))) {
+       if (!strncmp(val, "disable", sizeof("disable") - 1)) {
                int name = 0;
                result = acpi_debug_trace((char *)&name, trace_debug_level,
                                          trace_debug_layer, 0);
index 9fe90e9fecb56ada8629a55c472c67653bbd02f5..edda74a43406b5232c01a65ac030303abab830f4 100644 (file)
@@ -106,7 +106,9 @@ static const struct acpi_device_id  thermal_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_thermal_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume);
 
 static struct acpi_driver acpi_thermal_driver = {
@@ -1041,6 +1043,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_thermal_resume(struct device *dev)
 {
        struct acpi_thermal *tz;
@@ -1075,6 +1078,7 @@ static int acpi_thermal_resume(struct device *dev)
 
        return AE_OK;
 }
+#endif
 
 static int thermal_act(const struct dmi_system_id *d) {
 
index 2be8ef1d30935af81a9b7ac3b721750fdda6b3cd..27cecd313e7588386960244548b391bfddac2a55 100644 (file)
@@ -115,7 +115,7 @@ config SATA_SIL24
          If unsure, say N.
 
 config ATA_SFF
-       bool "ATA SFF support"
+       bool "ATA SFF support (for legacy IDE and PATA)"
        default y
        help
          This option adds support for ATA controllers with SFF
index 062e6a1a248fe97b69cd2047017a88ded3f2164d..50d5dea0ff599feb19626ff80b8143dff1ae4f6e 100644 (file)
@@ -256,6 +256,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
        { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
        { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
+       { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
+       { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
+       { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
+       { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */
+       { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */
+       { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
+       { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
+       { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
index c2594ddf25b00f54d22b51c66f23db5d54d47222..57eb1c212a4ce8ee267d36b3f920d3011f96b832 100644 (file)
@@ -320,6 +320,7 @@ extern struct device_attribute *ahci_sdev_attrs[];
 extern struct ata_port_operations ahci_ops;
 extern struct ata_port_operations ahci_pmp_retry_srst_ops;
 
+unsigned int ahci_dev_classify(struct ata_port *ap);
 void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
                        u32 opts);
 void ahci_save_initial_config(struct device *dev,
index 3c809bfbccf58a2af573be99719a4fda77bd3815..ef773e12af79d2c931e37852e7c31b716a00e51e 100644 (file)
@@ -329,6 +329,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (Lynx Point) */
        { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (Lynx Point-LP) */
+       { 0x8086, 0x9c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
+       /* SATA Controller IDE (Lynx Point-LP) */
+       { 0x8086, 0x9c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
+       /* SATA Controller IDE (Lynx Point-LP) */
+       { 0x8086, 0x9c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (Lynx Point-LP) */
+       { 0x8086, 0x9c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (DH89xxCC) */
        { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        { }     /* terminate list */
index f9eaa82311a9a191dd56fe06881dd318d5c518eb..555c07afa05bc6f82d6cc0357684f1f8e8b9f8da 100644 (file)
@@ -1139,7 +1139,7 @@ static void ahci_dev_config(struct ata_device *dev)
        }
 }
 
-static unsigned int ahci_dev_classify(struct ata_port *ap)
+unsigned int ahci_dev_classify(struct ata_port *ap)
 {
        void __iomem *port_mmio = ahci_port_base(ap);
        struct ata_taskfile tf;
@@ -1153,6 +1153,7 @@ static unsigned int ahci_dev_classify(struct ata_port *ap)
 
        return ata_dev_classify(&tf);
 }
+EXPORT_SYMBOL_GPL(ahci_dev_classify);
 
 void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
                        u32 opts)
index 902b5a457170958f4d805ae30185cee170e6b6e9..fd9ecf74e631afc800e56927069d97bd61774862 100644 (file)
@@ -60,17 +60,7 @@ acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
        if (ap->flags & ATA_FLAG_ACPI_SATA)
                return NULL;
 
-       /*
-        * If acpi bind operation has already happened, we can get the handle
-        * for the port by checking the corresponding scsi_host device's
-        * firmware node, otherwise we will need to find out the handle from
-        * its parent's acpi node.
-        */
-       if (ap->scsi_host)
-               return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev);
-       else
-               return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev),
-                               ap->port_no);
+       return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no);
 }
 EXPORT_SYMBOL(ata_ap_acpi_handle);
 
@@ -1101,6 +1091,9 @@ static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
        if (!*handle)
                return -ENODEV;
 
+       if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
+               ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
+
        return 0;
 }
 
index fadd5866d40fd29b2eb70df29e3d026e2e3722db..8e1039c8e15975aced4e6a359dc4a0451a58bc4b 100644 (file)
@@ -4062,7 +4062,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "_NEC DV5800A",       NULL,           ATA_HORKAGE_NODMA },
        { "SAMSUNG CD-ROM SN-124", "N001",      ATA_HORKAGE_NODMA },
        { "Seagate STT20000A", NULL,            ATA_HORKAGE_NODMA },
-       { "2GB ATA Flash Disk", "ADMA428M",     ATA_HORKAGE_NODMA },
+       { " 2GB ATA Flash Disk", "ADMA428M",    ATA_HORKAGE_NODMA },
        /* Odd clown on sil3726/4726 PMPs */
        { "Config  Disk",       NULL,           ATA_HORKAGE_DISABLE },
 
@@ -4128,6 +4128,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 
        /* Devices that do not need bridging limits applied */
        { "MTRON MSP-SATA*",            NULL,   ATA_HORKAGE_BRIDGE_OK, },
+       { "BUFFALO HD-QSU2/R5",         NULL,   ATA_HORKAGE_BRIDGE_OK, },
 
        /* Devices which aren't very happy with higher link speeds */
        { "WD My Book",                 NULL,   ATA_HORKAGE_1_5_GBPS, },
index 361c75cea57b9d1836ca6be599343f019759833b..24e51056ac26a857c1db028b9eb71450a0608d45 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
+#include <linux/dmi.h>
 
 #define DRV_NAME "pata_atiixp"
 #define DRV_VERSION "0.4.6"
@@ -33,11 +34,26 @@ enum {
        ATIIXP_IDE_UDMA_MODE    = 0x56
 };
 
+static const struct dmi_system_id attixp_cable_override_dmi_table[] = {
+       {
+               /* Board has onboard PATA<->SATA converters */
+               .ident = "MSI E350DM-E33",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
+                       DMI_MATCH(DMI_BOARD_NAME, "E350DM-E33(MS-7720)"),
+               },
+       },
+       { }
+};
+
 static int atiixp_cable_detect(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 udma;
 
+       if (dmi_check_system(attixp_cable_override_dmi_table))
+               return ATA_CBL_PATA40_SHORT;
+
        /* Hack from drivers/ide/pci. Really we want to know how to do the
           raw detection not play follow the bios mode guess */
        pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
index d4386019af5d59657812021e608a506adde44fe3..96cce6d5319592b20fbc8536c350d3cffdd841e8 100644 (file)
@@ -2362,7 +2362,7 @@ static int __devinit ia_init(struct atm_dev *dev)
        {  
                printk(DEV_LABEL " (itf %d): can't set up page mapping\n",  
                            dev->number);  
-               return error;  
+               return -ENOMEM;
        }  
        IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n",  
                        dev->number, iadev->pci->revision, base, iadev->irq);)
index f338037a4f3d9109e4d69da7a22a4e41070615b4..5e6e00bc1652a064530818e5f87416604eba7e25 100644 (file)
@@ -1865,6 +1865,7 @@ int __dev_printk(const char *level, const struct device *dev,
                 struct va_format *vaf)
 {
        char dict[128];
+       const char *level_extra = "";
        size_t dictlen = 0;
        const char *subsys;
 
@@ -1911,10 +1912,14 @@ int __dev_printk(const char *level, const struct device *dev,
                                    "DEVICE=+%s:%s", subsys, dev_name(dev));
        }
 skip:
+       if (level[2])
+               level_extra = &level[2]; /* skip past KERN_SOH "L" */
+
        return printk_emit(0, level[1] - '0',
                           dictlen ? dict : NULL, dictlen,
-                          "%s %s: %pV",
-                          dev_driver_string(dev), dev_name(dev), vaf);
+                          "%s %s: %s%pV",
+                          dev_driver_string(dev), dev_name(dev),
+                          level_extra, vaf);
 }
 EXPORT_SYMBOL(__dev_printk);
 
index 869d7ff2227f8aa87ba5a390644558e7e0585099..eb78e9640c4a86c0df9c0464e7dbd0b37f4ab75d 100644 (file)
@@ -169,8 +169,7 @@ void pm_clk_init(struct device *dev)
  */
 int pm_clk_create(struct device *dev)
 {
-       int ret = dev_pm_get_subsys_data(dev);
-       return ret < 0 ? ret : 0;
+       return dev_pm_get_subsys_data(dev);
 }
 
 /**
index a14085cc613fdfd2116afeb9da0f620b96c492f7..39c32529b83374c36eda18188c393930732ad99f 100644 (file)
@@ -24,7 +24,6 @@
 int dev_pm_get_subsys_data(struct device *dev)
 {
        struct pm_subsys_data *psd;
-       int ret = 0;
 
        psd = kzalloc(sizeof(*psd), GFP_KERNEL);
        if (!psd)
@@ -40,7 +39,6 @@ int dev_pm_get_subsys_data(struct device *dev)
                dev->power.subsys_data = psd;
                pm_clk_init(dev);
                psd = NULL;
-               ret = 1;
        }
 
        spin_unlock_irq(&dev->power.lock);
@@ -48,7 +46,7 @@ int dev_pm_get_subsys_data(struct device *dev)
        /* kfree() verifies that its argument is nonzero. */
        kfree(psd);
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data);
 
index 59894873a3b37de88a50d3b5e1f22ce67e454858..7d9c1cb1c39a7760081bae4d518efd8acf835902 100644 (file)
@@ -147,6 +147,8 @@ static int rpm_check_suspend_allowed(struct device *dev)
            || (dev->power.request_pending
                        && dev->power.request == RPM_REQ_RESUME))
                retval = -EAGAIN;
+       else if (__dev_pm_qos_read_value(dev) < 0)
+               retval = -EPERM;
        else if (dev->power.runtime_status == RPM_SUSPENDED)
                retval = 1;
 
@@ -388,7 +390,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
                goto repeat;
        }
 
-       dev->power.deferred_resume = false;
        if (dev->power.no_callbacks)
                goto no_callback;       /* Assume success. */
 
@@ -403,12 +404,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
                goto out;
        }
 
-       if (__dev_pm_qos_read_value(dev) < 0) {
-               /* Negative PM QoS constraint means "never suspend". */
-               retval = -EPERM;
-               goto out;
-       }
-
        __update_runtime_status(dev, RPM_SUSPENDING);
 
        if (dev->pm_domain)
@@ -440,6 +435,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
        wake_up_all(&dev->power.wait_queue);
 
        if (dev->power.deferred_resume) {
+               dev->power.deferred_resume = false;
                rpm_resume(dev, 0);
                retval = -EAGAIN;
                goto out;
@@ -584,6 +580,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
                    || dev->parent->power.runtime_status == RPM_ACTIVE) {
                        atomic_inc(&dev->parent->power.child_count);
                        spin_unlock(&dev->parent->power.lock);
+                       retval = 1;
                        goto no_callback;       /* Assume success. */
                }
                spin_unlock(&dev->parent->power.lock);
@@ -664,7 +661,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
        }
        wake_up_all(&dev->power.wait_queue);
 
-       if (!retval)
+       if (retval >= 0)
                rpm_idle(dev, RPM_ASYNC);
 
  out:
index 11b32d2642dfc25dd4b1d22b30c9e3bf0cf65555..a6e5672c67e77f473a8685884ff4626791e99ab2 100644 (file)
@@ -272,6 +272,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
        { 0, },
 };
index 26823d97fd9f60925967b51a4fdfc158454bbe1b..9ea4627dc0c233a808f322816c2560fd9c145d3d 100644 (file)
@@ -507,7 +507,9 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
                /* for these chips OTP is always available */
                present = true;
                break;
-
+       case BCMA_CHIP_ID_BCM43228:
+               present = chip_status & BCMA_CC_CHIPST_43228_OTP_PRESENT;
+               break;
        default:
                present = false;
                break;
index acda773b3720878495d14f5ebfbe1a82f50c0f74..38aa6dda6b81d0deeb355956ead087324f41f3d1 100644 (file)
@@ -763,16 +763,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout,
                {
                        case CMD_TARGET_STATUS:
                                /* Pass it up to the upper layers... */
-                               if( ei->ScsiStatus)
-                               {
-#if 0
-                                       printk(KERN_WARNING "cciss: cmd %p "
-                                               "has SCSI Status = %x\n",
-                                               c, ei->ScsiStatus);
-#endif
-                                       cmd->result |= (ei->ScsiStatus << 1);
-                               }
-                               else {  /* scsi status is zero??? How??? */
+                               if (!ei->ScsiStatus) {
                                        
        /* Ordinarily, this case should never happen, but there is a bug
           in some released firmware revisions that allows it to happen
index ba91b408abad75ce7da0ff173595ce23ee51f635..d84566496746aef57baf19dae86528bc202038cb 100644 (file)
@@ -889,6 +889,7 @@ struct bm_aio_ctx {
        unsigned int done;
        unsigned flags;
 #define BM_AIO_COPY_PAGES      1
+#define BM_WRITE_ALL_PAGES     2
        int error;
        struct kref kref;
 };
@@ -1059,7 +1060,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
                if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)
                        break;
                if (rw & WRITE) {
-                       if (bm_test_page_unchanged(b->bm_pages[i])) {
+                       if (!(flags & BM_WRITE_ALL_PAGES) &&
+                           bm_test_page_unchanged(b->bm_pages[i])) {
                                dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i);
                                continue;
                        }
@@ -1140,6 +1142,17 @@ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local)
        return bm_rw(mdev, WRITE, 0, 0);
 }
 
+/**
+ * drbd_bm_write_all() - Write the whole bitmap to its on disk location.
+ * @mdev:      DRBD device.
+ *
+ * Will write all pages.
+ */
+int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local)
+{
+       return bm_rw(mdev, WRITE, BM_WRITE_ALL_PAGES, 0);
+}
+
 /**
  * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed.
  * @mdev:      DRBD device.
index b2ca143d0053d75487e3a083a4271b9e5d0d285e..b953cc7c9c00ce4fb13885f2631211c6046ed58d 100644 (file)
@@ -1469,6 +1469,7 @@ extern int  drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr);
 extern int  drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local);
 extern int  drbd_bm_read(struct drbd_conf *mdev) __must_hold(local);
 extern int  drbd_bm_write(struct drbd_conf *mdev) __must_hold(local);
+extern int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local);
 extern int  drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local);
 extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev,
                unsigned long al_enr);
index 2e0e7fc1dbbaf50e24d8a446a4e20aeb2239f5bb..f93a0320e952dd6b07fb8c73739ee73d3c1af0a0 100644 (file)
@@ -79,6 +79,7 @@ static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused);
 static void md_sync_timer_fn(unsigned long data);
 static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused);
 static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+static void _tl_clear(struct drbd_conf *mdev);
 
 MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, "
              "Lars Ellenberg <lars@linbit.com>");
@@ -432,19 +433,10 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 
        /* Actions operating on the disk state, also want to work on
           requests that got barrier acked. */
-       switch (what) {
-       case fail_frozen_disk_io:
-       case restart_frozen_disk_io:
-               list_for_each_safe(le, tle, &mdev->barrier_acked_requests) {
-                       req = list_entry(le, struct drbd_request, tl_requests);
-                       _req_mod(req, what);
-               }
 
-       case connection_lost_while_pending:
-       case resend:
-               break;
-       default:
-               dev_err(DEV, "what = %d in _tl_restart()\n", what);
+       list_for_each_safe(le, tle, &mdev->barrier_acked_requests) {
+               req = list_entry(le, struct drbd_request, tl_requests);
+               _req_mod(req, what);
        }
 }
 
@@ -458,12 +450,17 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
  * receiver thread and the worker thread.
  */
 void tl_clear(struct drbd_conf *mdev)
+{
+       spin_lock_irq(&mdev->req_lock);
+       _tl_clear(mdev);
+       spin_unlock_irq(&mdev->req_lock);
+}
+
+static void _tl_clear(struct drbd_conf *mdev)
 {
        struct list_head *le, *tle;
        struct drbd_request *r;
 
-       spin_lock_irq(&mdev->req_lock);
-
        _tl_restart(mdev, connection_lost_while_pending);
 
        /* we expect this list to be empty. */
@@ -482,7 +479,6 @@ void tl_clear(struct drbd_conf *mdev)
 
        memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *));
 
-       spin_unlock_irq(&mdev->req_lock);
 }
 
 void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
@@ -1476,12 +1472,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
        if (ns.susp_fen) {
                /* case1: The outdate peer handler is successful: */
                if (os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) {
-                       tl_clear(mdev);
                        if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
                                drbd_uuid_new_current(mdev);
                                clear_bit(NEW_CUR_UUID, &mdev->flags);
                        }
                        spin_lock_irq(&mdev->req_lock);
+                       _tl_clear(mdev);
                        _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);
                        spin_unlock_irq(&mdev->req_lock);
                }
@@ -3537,9 +3533,9 @@ static void drbd_cleanup(void)
 }
 
 /**
- * drbd_congested() - Callback for pdflush
+ * drbd_congested() - Callback for the flusher thread
  * @congested_data:    User data
- * @bdi_bits:          Bits pdflush is currently interested in
+ * @bdi_bits:          Bits the BDI flusher thread is currently interested in
  *
  * Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested.
  */
index fb9dce8daa2468c76992f4ab609adb471bc42af3..edb490aad8b44fa507da3d72724b5df925a020e4 100644 (file)
@@ -674,8 +674,8 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds
                         la_size_changed && md_moved ? "size changed and md moved" :
                         la_size_changed ? "size changed" : "md moved");
                /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */
-               err = drbd_bitmap_io(mdev, &drbd_bm_write,
-                               "size changed", BM_LOCKED_MASK);
+               err = drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write,
+                                    "size changed", BM_LOCKED_MASK);
                if (err) {
                        rv = dev_size_error;
                        goto out;
index 910335c30927f0429a4c4b0fddcfe74033c45e8d..01b2ac641c7babe119f98dac7596ff8a690402a8 100644 (file)
@@ -695,6 +695,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
                break;
 
        case resend:
+               /* Simply complete (local only) READs. */
+               if (!(req->rq_state & RQ_WRITE) && !req->w.cb) {
+                       _req_may_be_done(req, m);
+                       break;
+               }
+
                /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK
                   before the connection loss (B&C only); only P_BARRIER_ACK was missing.
                   Trowing them out of the TL here by pretending we got a BARRIER_ACK
@@ -834,7 +840,15 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
                req->private_bio = NULL;
        }
        if (rw == WRITE) {
-               remote = 1;
+               /* Need to replicate writes.  Unless it is an empty flush,
+                * which is better mapped to a DRBD P_BARRIER packet,
+                * also for drbd wire protocol compatibility reasons. */
+               if (unlikely(size == 0)) {
+                       /* The only size==0 bios we expect are empty flushes. */
+                       D_ASSERT(bio->bi_rw & REQ_FLUSH);
+                       remote = 0;
+               } else
+                       remote = 1;
        } else {
                /* READ || READA */
                if (local) {
@@ -870,8 +884,11 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
         * extent.  This waits for any resync activity in the corresponding
         * resync extent to finish, and, if necessary, pulls in the target
         * extent into the activity log, which involves further disk io because
-        * of transactional on-disk meta data updates. */
-       if (rw == WRITE && local && !test_bit(AL_SUSPENDED, &mdev->flags)) {
+        * of transactional on-disk meta data updates.
+        * Empty flushes don't need to go into the activity log, they can only
+        * flush data for pending writes which are already in there. */
+       if (rw == WRITE && local && size
+       && !test_bit(AL_SUSPENDED, &mdev->flags)) {
                req->rq_state |= RQ_IN_ACT_LOG;
                drbd_al_begin_io(mdev, sector);
        }
@@ -994,7 +1011,10 @@ allocate_barrier:
        if (rw == WRITE && _req_conflicts(req))
                goto fail_conflicting;
 
-       list_add_tail(&req->tl_requests, &mdev->newest_tle->requests);
+       /* no point in adding empty flushes to the transfer log,
+        * they are mapped to drbd barriers already. */
+       if (likely(size!=0))
+               list_add_tail(&req->tl_requests, &mdev->newest_tle->requests);
 
        /* NOTE remote first: to get the concurrent write detection right,
         * we must register the request before start of local IO.  */
@@ -1014,6 +1034,14 @@ allocate_barrier:
            mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96)
                maybe_pull_ahead(mdev);
 
+       /* If this was a flush, queue a drbd barrier/start a new epoch.
+        * Unless the current epoch was empty anyways, or we are not currently
+        * replicating, in which case there is no point. */
+       if (unlikely(bio->bi_rw & REQ_FLUSH)
+               && mdev->newest_tle->n_writes
+               && drbd_should_do_remote(mdev->state))
+               queue_barrier(mdev);
+
        spin_unlock_irq(&mdev->req_lock);
        kfree(b); /* if someone else has beaten us to it... */
 
index 10308cd8a7ed2276f146c86c752383de5517464a..11f36e5021367d7dd7c2b0794241154a0544ad0a 100644 (file)
@@ -79,6 +79,7 @@ static struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x13d3, 0x3362) },
        { USB_DEVICE(0x0CF3, 0xE004) },
        { USB_DEVICE(0x0930, 0x0219) },
+       { USB_DEVICE(0x0489, 0xe057) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -104,6 +105,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
index e272214110365510fcfcbb6f6f3f75778f65ed46..cef3bac1a543d83113b54939585f807748accaf7 100644 (file)
@@ -98,6 +98,7 @@ static struct usb_device_id btusb_table[] = {
        { USB_DEVICE(0x0a5c, 0x21e6) },
        { USB_DEVICE(0x0a5c, 0x21e8) },
        { USB_DEVICE(0x0a5c, 0x21f3) },
+       { USB_DEVICE(0x0a5c, 0x21f4) },
        { USB_DEVICE(0x413c, 0x8197) },
 
        /* Foxconn - Hon Hai */
@@ -133,6 +134,7 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
index 57226424690cb1f05ebfa560f776aa8adf967c55..6ec0fff79bc2f6dfce8eb2be78019dca56bb18e6 100644 (file)
@@ -64,6 +64,7 @@
 #define I830_PTE_SYSTEM_CACHED  0x00000006
 /* GT PTE cache control fields */
 #define GEN6_PTE_UNCACHED      0x00000002
+#define HSW_PTE_UNCACHED       0x00000000
 #define GEN6_PTE_LLC           0x00000004
 #define GEN6_PTE_LLC_MLC       0x00000006
 #define GEN6_PTE_GFDT          0x00000008
 #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG         0x016A
 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_HB              0x0F00 /* VLV1 */
 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG              0x0F30
-#define PCI_DEVICE_ID_INTEL_HASWELL_HB                         0x0400 /* Desktop */
+#define PCI_DEVICE_ID_INTEL_HASWELL_HB                 0x0400 /* Desktop */
 #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG           0x0402
 #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG           0x0412
-#define PCI_DEVICE_ID_INTEL_HASWELL_M_HB                       0x0404 /* Mobile */
+#define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG      0x0422
+#define PCI_DEVICE_ID_INTEL_HASWELL_M_HB               0x0404 /* Mobile */
 #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG           0x0406
 #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG           0x0416
-#define PCI_DEVICE_ID_INTEL_HASWELL_S_HB                       0x0408 /* Server */
+#define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG      0x0426
+#define PCI_DEVICE_ID_INTEL_HASWELL_S_HB               0x0408 /* Server */
 #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG           0x040a
 #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG           0x041a
-#define PCI_DEVICE_ID_INTEL_HASWELL_SDV                0x0c16 /* SDV */
-#define PCI_DEVICE_ID_INTEL_HASWELL_E_HB                       0x0c04
+#define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG      0x042a
+#define PCI_DEVICE_ID_INTEL_HASWELL_E_HB               0x0c04
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG       0x0C02
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG       0x0C12
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG  0x0C22
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG       0x0C06
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG       0x0C16
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG  0x0C26
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG       0x0C0A
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG       0x0C1A
+#define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG  0x0C2A
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG       0x0A02
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG       0x0A12
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG  0x0A22
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG       0x0A06
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG       0x0A16
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG  0x0A26
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG       0x0A0A
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG       0x0A1A
+#define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG  0x0A2A
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG       0x0D12
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG       0x0D22
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG  0x0D32
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG       0x0D16
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG       0x0D26
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG  0x0D36
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG       0x0D1A
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG       0x0D2A
+#define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG  0x0D3A
 
 #endif
index 9ed92ef5829b8f54bb318e0b6510e59c2b40e939..58e32f7c322956209bd3a63ce16f5ce16135c59b 100644 (file)
@@ -1156,6 +1156,30 @@ static bool gen6_check_flags(unsigned int flags)
        return true;
 }
 
+static void haswell_write_entry(dma_addr_t addr, unsigned int entry,
+                               unsigned int flags)
+{
+       unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT;
+       unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT;
+       u32 pte_flags;
+
+       if (type_mask == AGP_USER_MEMORY)
+               pte_flags = HSW_PTE_UNCACHED | I810_PTE_VALID;
+       else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) {
+               pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID;
+               if (gfdt)
+                       pte_flags |= GEN6_PTE_GFDT;
+       } else { /* set 'normal'/'cached' to LLC by default */
+               pte_flags = GEN6_PTE_LLC | I810_PTE_VALID;
+               if (gfdt)
+                       pte_flags |= GEN6_PTE_GFDT;
+       }
+
+       /* gen6 has bit11-4 for physical addr bit39-32 */
+       addr |= (addr >> 28) & 0xff0;
+       writel(addr | pte_flags, intel_private.gtt + entry);
+}
+
 static void gen6_write_entry(dma_addr_t addr, unsigned int entry,
                             unsigned int flags)
 {
@@ -1382,6 +1406,15 @@ static const struct intel_gtt_driver sandybridge_gtt_driver = {
        .check_flags = gen6_check_flags,
        .chipset_flush = i9xx_chipset_flush,
 };
+static const struct intel_gtt_driver haswell_gtt_driver = {
+       .gen = 6,
+       .setup = i9xx_setup,
+       .cleanup = gen6_cleanup,
+       .write_entry = haswell_write_entry,
+       .dma_mask_size = 40,
+       .check_flags = gen6_check_flags,
+       .chipset_flush = i9xx_chipset_flush,
+};
 static const struct intel_gtt_driver valleyview_gtt_driver = {
        .gen = 7,
        .setup = i9xx_setup,
@@ -1499,19 +1532,77 @@ static const struct intel_gtt_driver_description {
        { PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG,
            "ValleyView", &valleyview_gtt_driver },
        { PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG,
-           "Haswell", &sandybridge_gtt_driver },
+           "Haswell", &haswell_gtt_driver },
        { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG,
-           "Haswell", &sandybridge_gtt_driver },
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
        { PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG,
-           "Haswell", &sandybridge_gtt_driver },
+           "Haswell", &haswell_gtt_driver },
        { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG,
-           "Haswell", &sandybridge_gtt_driver },
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
        { PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG,
-           "Haswell", &sandybridge_gtt_driver },
+           "Haswell", &haswell_gtt_driver },
        { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG,
-           "Haswell", &sandybridge_gtt_driver },
-       { PCI_DEVICE_ID_INTEL_HASWELL_SDV,
-           "Haswell", &sandybridge_gtt_driver },
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG,
+           "Haswell", &haswell_gtt_driver },
+       { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG,
+           "Haswell", &haswell_gtt_driver },
        { 0, NULL, NULL }
 };
 
index d706bd0e9e800fd791e198b4b573b64296f3f40e..4fbdceb6f773d7e45189a22347668c34a0b52c63 100644 (file)
@@ -160,7 +160,7 @@ static int __exit omap_rng_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 
 static int omap_rng_suspend(struct device *dev)
 {
index 89682fa8801ea0fafb1f8e9556ca148ab0b4f6f9..c4be3519a587c4fe33c3a14be17ba72e6067d9a0 100644 (file)
@@ -807,6 +807,7 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 #endif
 
+#ifdef CONFIG_PM_SLEEP
 static int tpm_tis_resume(struct device *dev)
 {
        struct tpm_chip *chip = dev_get_drvdata(dev);
@@ -816,6 +817,7 @@ static int tpm_tis_resume(struct device *dev)
 
        return tpm_pm_resume(dev);
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
 
index 540795cd0760b434e53c0b10afd41d295892c836..d9279385304d8b86fff47d58f3b623b0c804a046 100644 (file)
@@ -53,7 +53,7 @@ static struct cs5535_mfgpt_timer *cs5535_event_clock;
 #define MFGPT_PERIODIC (MFGPT_HZ / HZ)
 
 /*
- * The MFPGT timers on the CS5536 provide us with suitable timers to use
+ * The MFGPT timers on the CS5536 provide us with suitable timers to use
  * as clock event sources - not as good as a HPET or APIC, but certainly
  * better than the PIT.  This isn't a general purpose MFGPT driver, but
  * a simplified one designed specifically to act as a clock event source.
@@ -144,7 +144,7 @@ static int __init cs5535_mfgpt_init(void)
 
        timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
        if (!timer) {
-               printk(KERN_ERR DRV_NAME ": Could not allocate MFPGT timer\n");
+               printk(KERN_ERR DRV_NAME ": Could not allocate MFGPT timer\n");
                return -ENODEV;
        }
        cs5535_event_clock = timer;
index 17fa04d08be9cc0af181e5f20398128d8b4d5234..b47034e650a579b9d0263f8d0a03af2ecc8b3aa7 100644 (file)
@@ -218,7 +218,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
 
        policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
 
-       if (atomic_inc_return(&freq_table_users) == 1)
+       if (!freq_table)
                result = opp_init_cpufreq_table(mpu_dev, &freq_table);
 
        if (result) {
@@ -227,6 +227,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
                goto fail_ck;
        }
 
+       atomic_inc_return(&freq_table_users);
+
        result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
        if (result)
                goto fail_table;
index cdc02ac8f41a7ff5d3f121e2b0927fd8bf99ae7a..503996a94a6af3d4f41292794c14f261ada96ae1 100644 (file)
@@ -454,6 +454,7 @@ static int __init pcc_cpufreq_probe(void)
                                        mem_resource->address_length);
        if (pcch_virt_addr == NULL) {
                pr_debug("probe: could not map shared mem region\n");
+               ret = -ENOMEM;
                goto out_free;
        }
        pcch_hdr = pcch_virt_addr;
index 2c9bf2692232e51a66e5455368d9881383ccfc2f..3265844839bfe9c79ef8849705262a52d16cc4e1 100644 (file)
@@ -678,10 +678,22 @@ static int cpuidle_coupled_cpu_notify(struct notifier_block *nb,
        int cpu = (unsigned long)hcpu;
        struct cpuidle_device *dev;
 
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_UP_PREPARE:
+       case CPU_DOWN_PREPARE:
+       case CPU_ONLINE:
+       case CPU_DEAD:
+       case CPU_UP_CANCELED:
+       case CPU_DOWN_FAILED:
+               break;
+       default:
+               return NOTIFY_OK;
+       }
+
        mutex_lock(&cpuidle_lock);
 
        dev = per_cpu(cpuidle_devices, cpu);
-       if (!dev->coupled)
+       if (!dev || !dev->coupled)
                goto out;
 
        switch (action & ~CPU_TASKS_FROZEN) {
index 53c8c51d58817cb62b4641d5e923bb4f72b39f2f..93d14070141ae64fe4e96dd838fc28c36061b3cf 100644 (file)
@@ -63,7 +63,7 @@ static void caam_jr_dequeue(unsigned long devarg)
 
                head = ACCESS_ONCE(jrp->head);
 
-               spin_lock_bh(&jrp->outlock);
+               spin_lock(&jrp->outlock);
 
                sw_idx = tail = jrp->tail;
                hw_idx = jrp->out_ring_read_index;
@@ -115,7 +115,7 @@ static void caam_jr_dequeue(unsigned long devarg)
                        jrp->tail = tail;
                }
 
-               spin_unlock_bh(&jrp->outlock);
+               spin_unlock(&jrp->outlock);
 
                /* Finally, execute user's callback */
                usercall(dev, userdesc, userstatus, userarg);
@@ -236,14 +236,14 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
                return -EIO;
        }
 
-       spin_lock(&jrp->inplock);
+       spin_lock_bh(&jrp->inplock);
 
        head = jrp->head;
        tail = ACCESS_ONCE(jrp->tail);
 
        if (!rd_reg32(&jrp->rregs->inpring_avail) ||
            CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) {
-               spin_unlock(&jrp->inplock);
+               spin_unlock_bh(&jrp->inplock);
                dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE);
                return -EBUSY;
        }
@@ -265,7 +265,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
 
        wr_reg32(&jrp->rregs->inpring_jobadd, 1);
 
-       spin_unlock(&jrp->inplock);
+       spin_unlock_bh(&jrp->inplock);
 
        return 0;
 }
index c9c4befb5a8d261701698c570c668d5009113a64..df14358d7fa1658c48e10d8b7a768f32eec6b9ac 100644 (file)
@@ -821,8 +821,8 @@ static int hifn_register_rng(struct hifn_device *dev)
        /*
         * We must wait at least 256 Pk_clk cycles between two reads of the rng.
         */
-       dev->rng_wait_time      = DIV_ROUND_UP(NSEC_PER_SEC, dev->pk_clk_freq) *
-                                 256;
+       dev->rng_wait_time      = DIV_ROUND_UP_ULL(NSEC_PER_SEC,
+                                                  dev->pk_clk_freq) * 256;
 
        dev->rng.name           = dev->name;
        dev->rng.data_present   = hifn_rng_data_present,
index fcfeb3cd8d3170aff7c30d6d151a0e7e15ecd968..5084975d793cd25949e62ae68f5932bd3c456763 100644 (file)
@@ -172,7 +172,8 @@ struct imxdma_engine {
        struct device_dma_parameters    dma_parms;
        struct dma_device               dma_device;
        void __iomem                    *base;
-       struct clk                      *dma_clk;
+       struct clk                      *dma_ahb;
+       struct clk                      *dma_ipg;
        spinlock_t                      lock;
        struct imx_dma_2d_config        slots_2d[IMX_DMA_2D_SLOTS];
        struct imxdma_channel           channel[IMX_DMA_CHANNELS];
@@ -976,10 +977,20 @@ static int __init imxdma_probe(struct platform_device *pdev)
                return 0;
        }
 
-       imxdma->dma_clk = clk_get(NULL, "dma");
-       if (IS_ERR(imxdma->dma_clk))
-               return PTR_ERR(imxdma->dma_clk);
-       clk_enable(imxdma->dma_clk);
+       imxdma->dma_ipg = devm_clk_get(&pdev->dev, "ipg");
+       if (IS_ERR(imxdma->dma_ipg)) {
+               ret = PTR_ERR(imxdma->dma_ipg);
+               goto err_clk;
+       }
+
+       imxdma->dma_ahb = devm_clk_get(&pdev->dev, "ahb");
+       if (IS_ERR(imxdma->dma_ahb)) {
+               ret = PTR_ERR(imxdma->dma_ahb);
+               goto err_clk;
+       }
+
+       clk_prepare_enable(imxdma->dma_ipg);
+       clk_prepare_enable(imxdma->dma_ahb);
 
        /* reset DMA module */
        imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR);
@@ -988,16 +999,14 @@ static int __init imxdma_probe(struct platform_device *pdev)
                ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma);
                if (ret) {
                        dev_warn(imxdma->dev, "Can't register IRQ for DMA\n");
-                       kfree(imxdma);
-                       return ret;
+                       goto err_enable;
                }
 
                ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma);
                if (ret) {
                        dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n");
                        free_irq(MX1_DMA_INT, NULL);
-                       kfree(imxdma);
-                       return ret;
+                       goto err_enable;
                }
        }
 
@@ -1094,7 +1103,10 @@ err_init:
                free_irq(MX1_DMA_INT, NULL);
                free_irq(MX1_DMA_ERR, NULL);
        }
-
+err_enable:
+       clk_disable_unprepare(imxdma->dma_ipg);
+       clk_disable_unprepare(imxdma->dma_ahb);
+err_clk:
        kfree(imxdma);
        return ret;
 }
@@ -1114,7 +1126,9 @@ static int __exit imxdma_remove(struct platform_device *pdev)
                free_irq(MX1_DMA_ERR, NULL);
        }
 
-        kfree(imxdma);
+       clk_disable_unprepare(imxdma->dma_ipg);
+       clk_disable_unprepare(imxdma->dma_ahb);
+       kfree(imxdma);
 
         return 0;
 }
index d52dbc6c54abdb346278b65bfbd8715f317d3e58..24acd711e0326852e2bf97bce308fb1fe272cea6 100644 (file)
@@ -1119,15 +1119,21 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
 static int tegra_dma_alloc_chan_resources(struct dma_chan *dc)
 {
        struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
+       struct tegra_dma *tdma = tdc->tdma;
+       int ret;
 
        dma_cookie_init(&tdc->dma_chan);
        tdc->config_init = false;
-       return 0;
+       ret = clk_prepare_enable(tdma->dma_clk);
+       if (ret < 0)
+               dev_err(tdc2dev(tdc), "clk_prepare_enable failed: %d\n", ret);
+       return ret;
 }
 
 static void tegra_dma_free_chan_resources(struct dma_chan *dc)
 {
        struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
+       struct tegra_dma *tdma = tdc->tdma;
 
        struct tegra_dma_desc *dma_desc;
        struct tegra_dma_sg_req *sg_req;
@@ -1163,6 +1169,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
                list_del(&sg_req->node);
                kfree(sg_req);
        }
+       clk_disable_unprepare(tdma->dma_clk);
 }
 
 /* Tegra20 specific DMA controller information */
@@ -1255,6 +1262,13 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev)
                }
        }
 
+       /* Enable clock before accessing registers */
+       ret = clk_prepare_enable(tdma->dma_clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
+               goto err_pm_disable;
+       }
+
        /* Reset DMA controller */
        tegra_periph_reset_assert(tdma->dma_clk);
        udelay(2);
@@ -1265,6 +1279,8 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev)
        tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0);
        tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul);
 
+       clk_disable_unprepare(tdma->dma_clk);
+
        INIT_LIST_HEAD(&tdma->dma_dev.channels);
        for (i = 0; i < cdata->nr_channels; i++) {
                struct tegra_dma_channel *tdc = &tdma->channels[i];
index fe3db45fa83c13604db19590cb29546dc38efae1..3cc152e690b06087c8374bf35cb72106f9bfde32 100644 (file)
@@ -107,7 +107,8 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
-       ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name);
+       ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN,
+                                   pdev->name);
        if (ret < 0)
                goto err;
 
index 150d9768811d4a09d30cef2ca9b69bdaf3c57275..ae37181798b3c979d9ce423a437f7ba09511166a 100644 (file)
@@ -266,7 +266,7 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p)
        return 0;
 }
 
-static void __devexit em_gio_irq_domain_cleanup(struct em_gio_priv *p)
+static void em_gio_irq_domain_cleanup(struct em_gio_priv *p)
 {
        struct gpio_em_config *pdata = p->pdev->dev.platform_data;
 
index a1c8754f52cf1b523c3da1bb9e572dc084ddde0b..202a99207b7d40c1a0e98dbe728cb7f782704a0d 100644 (file)
@@ -339,7 +339,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
        resource_size_t start, len;
        struct lnw_gpio *lnw;
        u32 gpio_base;
-       int retval = 0;
+       int retval;
        int ngpio = id->driver_data;
 
        retval = pci_enable_device(pdev);
@@ -357,6 +357,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
        base = ioremap_nocache(start, len);
        if (!base) {
                dev_err(&pdev->dev, "error mapping bar1\n");
+               retval = -EFAULT;
                goto err3;
        }
        gpio_base = *((u32 *)base + 1);
@@ -381,8 +382,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
 
        lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio,
                                            &lnw_gpio_irq_ops, lnw);
-       if (!lnw->domain)
+       if (!lnw->domain) {
+               retval = -ENOMEM;
                goto err3;
+       }
 
        lnw->reg_base = base;
        lnw->chip.label = dev_name(&pdev->dev);
index 71a838f44501065b76e6253a3780959f15c85e0b..b38986285868ab96151c2c522463ccfb377aeae1 100644 (file)
@@ -99,7 +99,7 @@ static int msic_gpio_to_oreg(unsigned offset)
        if (offset < 20)
                return INTEL_MSIC_GPIO0HV0CTLO - offset + 16;
 
-       return INTEL_MSIC_GPIO1HV0CTLO + offset + 20;
+       return INTEL_MSIC_GPIO1HV0CTLO - offset + 20;
 }
 
 static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
index 4db460b6ecf7dbf1ffe7bfd14a1361d271609667..80f44bb64a871835b9cdf59561d8bff90d03126d 100644 (file)
@@ -465,9 +465,8 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
                goto out_iounmap;
 
        port->bgc.gc.to_irq = mxc_gpio_to_irq;
-       port->bgc.gc.base = pdev->id * 32;
-       port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir);
-       port->bgc.data = port->bgc.read_reg(port->bgc.reg_set);
+       port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
+                                            pdev->id * 32;
 
        err = gpiochip_add(&port->bgc.gc);
        if (err)
index 58a6a63a6ece65ed9de822449ee0d53cd41e66eb..9cac88a65f78402e2a45b919799576810d9ab9fd 100644 (file)
@@ -62,6 +62,7 @@ int pxa_last_gpio;
 
 #ifdef CONFIG_OF
 static struct irq_domain *domain;
+static struct device_node *pxa_gpio_of_node;
 #endif
 
 struct pxa_gpio_chip {
@@ -277,6 +278,24 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
                                (value ? GPSR_OFFSET : GPCR_OFFSET));
 }
 
+#ifdef CONFIG_OF_GPIO
+static int pxa_gpio_of_xlate(struct gpio_chip *gc,
+                            const struct of_phandle_args *gpiospec,
+                            u32 *flags)
+{
+       if (gpiospec->args[0] > pxa_last_gpio)
+               return -EINVAL;
+
+       if (gc != &pxa_gpio_chips[gpiospec->args[0] / 32].chip)
+               return -EINVAL;
+
+       if (flags)
+               *flags = gpiospec->args[1];
+
+       return gpiospec->args[0] % 32;
+}
+#endif
+
 static int __devinit pxa_init_gpio_chip(int gpio_end,
                                        int (*set_wake)(unsigned int, unsigned int))
 {
@@ -304,6 +323,11 @@ static int __devinit pxa_init_gpio_chip(int gpio_end,
                c->get = pxa_gpio_get;
                c->set = pxa_gpio_set;
                c->to_irq = pxa_gpio_to_irq;
+#ifdef CONFIG_OF_GPIO
+               c->of_node = pxa_gpio_of_node;
+               c->of_xlate = pxa_gpio_of_xlate;
+               c->of_gpio_n_cells = 2;
+#endif
 
                /* number of GPIOs on last bank may be less than 32 */
                c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
@@ -488,6 +512,7 @@ static int pxa_gpio_nums(void)
        return count;
 }
 
+#ifdef CONFIG_OF
 static struct of_device_id pxa_gpio_dt_ids[] = {
        { .compatible = "mrvl,pxa-gpio" },
        { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
@@ -505,9 +530,9 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
 
 const struct irq_domain_ops pxa_irq_domain_ops = {
        .map    = pxa_irq_domain_map,
+       .xlate  = irq_domain_xlate_twocell,
 };
 
-#ifdef CONFIG_OF
 static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev)
 {
        int ret, nr_banks, nr_gpios, irq_base;
@@ -545,6 +570,7 @@ static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev)
        }
        domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
                                       &pxa_irq_domain_ops, NULL);
+       pxa_gpio_of_node = np;
        return 0;
 err:
        iounmap(gpio_reg_base);
@@ -653,7 +679,7 @@ static struct platform_driver pxa_gpio_driver = {
        .probe          = pxa_gpio_probe,
        .driver         = {
                .name   = "pxa-gpio",
-               .of_match_table = pxa_gpio_dt_ids,
+               .of_match_table = of_match_ptr(pxa_gpio_dt_ids),
        },
 };
 
index 92f7b2bb79d40ccf277d19a4d234a53fd8c98d83..ba126cc04073e04c0d304bd8b6cbbd455d3d1d67 100644 (file)
@@ -2452,12 +2452,6 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = {
                        .ngpio  = EXYNOS5_GPIO_C3_NR,
                        .label  = "GPC3",
                },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS5_GPC4(0),
-                       .ngpio  = EXYNOS5_GPIO_C4_NR,
-                       .label  = "GPC4",
-               },
        }, {
                .chip   = {
                        .base   = EXYNOS5_GPD0(0),
@@ -2512,6 +2506,12 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = {
                        .ngpio  = EXYNOS5_GPIO_Y6_NR,
                        .label  = "GPY6",
                },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPC4(0),
+                       .ngpio  = EXYNOS5_GPIO_C4_NR,
+                       .label  = "GPC4",
+               },
        }, {
                .config = &samsung_gpio_cfgs[9],
                .irq_base = IRQ_EINT(0),
@@ -2836,7 +2836,7 @@ static __init void exynos5_gpiolib_init(void)
        }
 
        /* need to set base address for gpc4 */
-       exynos5_gpios_1[11].base = gpio_base1 + 0x2E0;
+       exynos5_gpios_1[20].base = gpio_base1 + 0x2E0;
 
        /* need to set base address for gpx */
        chip = &exynos5_gpios_1[21];
index 424dce8e3f30107ce2e9b5eb9b5d2bb394164cf9..8707d4572a06bfee4713fab5b521cd58f220aefa 100644 (file)
@@ -241,7 +241,8 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev)
                        break;
 
                default:
-                       return -ENODEV;
+                       err = -ENODEV;
+                       goto err_sch_gpio_core;
        }
 
        sch_gpio_core.dev = &pdev->dev;
index 23120c00a88175db9c74d4c33bff8a4d9e324fdc..90e28081712dbd7c68343f88bd10b468c10f604a 100644 (file)
@@ -22,6 +22,7 @@ menuconfig DRM
 config DRM_USB
        tristate
        depends on DRM
+       depends on USB_ARCH_HAS_HCD
        select USB
 
 config DRM_KMS_HELPER
index 08a7aa722d6b8f0d798b7a59ccd5b8146183f497..6fbfc244748fd9f5e23e05c90d57bcfbdead4b6b 100644 (file)
@@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                return -EINVAL;
 
-       if (!req->flags)
+       if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
                return -EINVAL;
 
        mutex_lock(&dev->mode_config.mutex);
index a8743c399e83234c976ebdb4b471542a0645c42d..b7ee230572b7c053a20c6bf115d4fd98a836f820 100644 (file)
@@ -87,6 +87,9 @@ static struct edid_quirk {
        int product_id;
        u32 quirks;
 } edid_quirk_list[] = {
+       /* ASUS VW222S */
+       { "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING },
+
        /* Acer AL1706 */
        { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
        /* Acer F51 */
index 66d4a28ad5a23fc2cf4b7b745091296444e287b1..0303935d10e2ca45165509a7e9e8165962c99774 100644 (file)
@@ -119,7 +119,7 @@ static int edid_load(struct drm_connector *connector, char *name,
 {
        const struct firmware *fw;
        struct platform_device *pdev;
-       u8 *fwdata = NULL, *edid;
+       u8 *fwdata = NULL, *edid, *new_edid;
        int fwsize, expected;
        int builtin = 0, err = 0;
        int i, valid_extensions = 0;
@@ -195,12 +195,14 @@ static int edid_load(struct drm_connector *connector, char *name,
                    "\"%s\" for connector \"%s\"\n", valid_extensions,
                    edid[0x7e], name, connector_name);
                edid[0x7e] = valid_extensions;
-               edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
+               new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
                    GFP_KERNEL);
-               if (edid == NULL) {
+               if (new_edid == NULL) {
                        err = -ENOMEM;
+                       kfree(edid);
                        goto relfw_out;
                }
+               edid = new_edid;
        }
 
        connector->display_info.raw_edid = edid;
index b7adb4a967fd02b80eee0f0bd6e78b2d76c7e9b1..28637c181b15045fb0d2e9235a5d653ee0204f92 100644 (file)
@@ -706,9 +706,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
        p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal);
        p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay);
        p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal);
-
-       p->crtc_hadjusted = false;
-       p->crtc_vadjusted = false;
 }
 EXPORT_SYMBOL(drm_mode_set_crtcinfo);
 
index 371c695322d9f8f1736510eeaeeab7ea153cbe9e..da457b18eaaf601c7f4aa7ebec6b294355bbcc41 100644 (file)
@@ -89,7 +89,7 @@ static const struct file_operations drm_proc_fops = {
  * Create a given set of proc files represented by an array of
  * gdm_proc_lists in the given root directory.
  */
-int drm_proc_create_files(struct drm_info_list *files, int count,
+static int drm_proc_create_files(struct drm_info_list *files, int count,
                          struct proc_dir_entry *root, struct drm_minor *minor)
 {
        struct drm_device *dev = minor->dev;
@@ -172,7 +172,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
        return 0;
 }
 
-int drm_proc_remove_files(struct drm_info_list *files, int count,
+static int drm_proc_remove_files(struct drm_info_list *files, int count,
                          struct drm_minor *minor)
 {
        struct list_head *pos, *q;
index 30dc22a7156ce88446d1a11ff2d484c2581c82e6..8033526bb53b98fd84e197f8b57a5b340cc45bd6 100644 (file)
@@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
            (struct drm_connector **) (psb_intel_crtc + 1);
        psb_intel_crtc->mode_set.num_connectors = 0;
        psb_intel_cursor_init(dev, psb_intel_crtc);
+
+       /* Set to true so that the pipe is forced off on initial config. */
+       psb_intel_crtc->active = true;
 }
 
 int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
index ed22612bc8477a3aa6dc95cfc2e058f7071c4878..a24ffbe97c01cffd8a8fa5093a5ba15ff04db30b 100644 (file)
@@ -346,11 +346,40 @@ static const struct pci_device_id pciidlist[] = {         /* aka */
        INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */
        INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */
        INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */
+       INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */
        INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */
        INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */
+       INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */
        INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */
        INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */
-       INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */
+       INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */
+       INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */
+       INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */
+       INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */
+       INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */
+       INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */
+       INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */
+       INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */
+       INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */
+       INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */
+       INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */
+       INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */
+       INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */
+       INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */
+       INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */
+       INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */
+       INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
+       INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
+       INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
+       INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */
+       INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
+       INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */
+       INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */
+       INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
+       INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */
+       INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */
+       INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
+       INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */
        INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
index 5c4657a54f977689c1668a9a70b8a8f6e39743c9..489e2b162b2736b4fc3d43e171ebddb25c66b12e 100644 (file)
@@ -2365,6 +2365,10 @@ int i915_gpu_idle(struct drm_device *dev)
 
        /* Flush everything onto the inactive list. */
        for_each_ring(ring, dev_priv, i) {
+               ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID);
+               if (ret)
+                       return ret;
+
                ret = i915_ring_idle(ring);
                if (ret)
                        return ret;
@@ -2372,10 +2376,6 @@ int i915_gpu_idle(struct drm_device *dev)
                /* Is the device fubar? */
                if (WARN_ON(!list_empty(&ring->gpu_write_list)))
                        return -EBUSY;
-
-               ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID);
-               if (ret)
-                       return ret;
        }
 
        return 0;
index da8b01fb1bf8dbbc1cbe34457bb67f4ff3fe28eb..a9d58d72bb4da2215592bb8ba6554e9835fb48cf 100644 (file)
@@ -451,7 +451,6 @@ int i915_switch_context(struct intel_ring_buffer *ring,
        struct drm_i915_file_private *file_priv = NULL;
        struct i915_hw_context *to;
        struct drm_i915_gem_object *from_obj = ring->last_context_obj;
-       int ret;
 
        if (dev_priv->hw_contexts_disabled)
                return 0;
index 5af631e788c8e6d39118eac4483ff9e2a40f329d..ff2819ea08130fb98da5f67550a18d9ca3c5974d 100644 (file)
@@ -291,6 +291,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
        target_i915_obj = to_intel_bo(target_obj);
        target_offset = target_i915_obj->gtt_offset;
 
+       /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
+        * pipe_control writes because the gpu doesn't properly redirect them
+        * through the ppgtt for non_secure batchbuffers. */
+       if (unlikely(IS_GEN6(dev) &&
+           reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
+           !target_i915_obj->has_global_gtt_mapping)) {
+               i915_gem_gtt_bind_object(target_i915_obj,
+                                        target_i915_obj->cache_level);
+       }
+
        /* The target buffer should have appeared before us in the
         * exec_object list, so it should have a GTT space bound by now.
         */
@@ -399,16 +409,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
                io_mapping_unmap_atomic(reloc_page);
        }
 
-       /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
-        * pipe_control writes because the gpu doesn't properly redirect them
-        * through the ppgtt for non_secure batchbuffers. */
-       if (unlikely(IS_GEN6(dev) &&
-           reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
-           !target_i915_obj->has_global_gtt_mapping)) {
-               i915_gem_gtt_bind_object(target_i915_obj,
-                                        target_i915_obj->cache_level);
-       }
-
        /* and update the user's relocation entry */
        reloc->presumed_offset = target_offset;
 
index 9fd25a435536121a33651c66ac00f5999c81f6f4..60815b861ec2143dc1fdad526232d03bea1158fd 100644 (file)
@@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
        /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024
         * entries. For aliasing ppgtt support we just steal them at the end for
         * now. */
-       first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES;
+       first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES;
 
        ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
        if (!ppgtt)
@@ -261,7 +261,10 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
                pte_flags |= GEN6_PTE_CACHE_LLC;
                break;
        case I915_CACHE_NONE:
-               pte_flags |= GEN6_PTE_UNCACHED;
+               if (IS_HASWELL(dev))
+                       pte_flags |= HSW_PTE_UNCACHED;
+               else
+                       pte_flags |= GEN6_PTE_UNCACHED;
                break;
        default:
                BUG();
@@ -361,7 +364,8 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj)
        struct drm_device *dev = obj->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (dev_priv->mm.gtt->needs_dmar)
+       /* don't map imported dma buf objects */
+       if (dev_priv->mm.gtt->needs_dmar && !obj->sg_table)
                return intel_gtt_map_memory(obj->pages,
                                            obj->base.size >> PAGE_SHIFT,
                                            &obj->sg_list,
index acc99b21e0b66d4fd215c16fb6f1e81b49b5fe8b..28725ce5b82cc052a4469828166a7f9c8d987236 100644 (file)
 
 #define GEN6_PTE_VALID                 (1 << 0)
 #define GEN6_PTE_UNCACHED              (1 << 1)
+#define HSW_PTE_UNCACHED               (0)
 #define GEN6_PTE_CACHE_LLC             (2 << 1)
 #define GEN6_PTE_CACHE_LLC_MLC         (3 << 1)
 #define GEN6_PTE_CACHE_BITS            (3 << 1)
index 2f5388af8df9cdf775d66d4d4f72f50f29bdecc0..7631807a27886e2483d77de1046461350f9c7d15 100644 (file)
@@ -32,6 +32,7 @@
 #include "intel_drv.h"
 #include "i915_drv.h"
 
+#ifdef CONFIG_PM
 static u32 calc_residency(struct drm_device *dev, const u32 reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -224,3 +225,14 @@ void i915_teardown_sysfs(struct drm_device *dev)
        device_remove_bin_file(&dev->primary->kdev,  &dpf_attrs);
        sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
 }
+#else
+void i915_setup_sysfs(struct drm_device *dev)
+{
+       return;
+}
+
+void i915_teardown_sysfs(struct drm_device *dev)
+{
+       return;
+}
+#endif /* CONFIG_PM */
index 7ed4a41c396590f77b477d36f4400fb687e86990..23bdc8cd145864f8346ce8d8ce4a255e436b0b6f 100644 (file)
@@ -326,6 +326,36 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
        return ret;
 }
 
+static struct edid *intel_crt_get_edid(struct drm_connector *connector,
+                               struct i2c_adapter *i2c)
+{
+       struct edid *edid;
+
+       edid = drm_get_edid(connector, i2c);
+
+       if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
+               DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n");
+               intel_gmbus_force_bit(i2c, true);
+               edid = drm_get_edid(connector, i2c);
+               intel_gmbus_force_bit(i2c, false);
+       }
+
+       return edid;
+}
+
+/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */
+static int intel_crt_ddc_get_modes(struct drm_connector *connector,
+                               struct i2c_adapter *adapter)
+{
+       struct edid *edid;
+
+       edid = intel_crt_get_edid(connector, adapter);
+       if (!edid)
+               return 0;
+
+       return intel_connector_update_modes(connector, edid);
+}
+
 static bool intel_crt_detect_ddc(struct drm_connector *connector)
 {
        struct intel_crt *crt = intel_attached_crt(connector);
@@ -336,7 +366,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
        BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
 
        i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
-       edid = drm_get_edid(connector, i2c);
+       edid = intel_crt_get_edid(connector, i2c);
 
        if (edid) {
                bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
@@ -544,13 +574,13 @@ static int intel_crt_get_modes(struct drm_connector *connector)
        struct i2c_adapter *i2c;
 
        i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
-       ret = intel_ddc_get_modes(connector, i2c);
+       ret = intel_crt_ddc_get_modes(connector, i2c);
        if (ret || !IS_G4X(dev))
                return ret;
 
        /* Try to probe digital port for output in DVI-I -> VGA mode. */
        i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
-       return intel_ddc_get_modes(connector, i2c);
+       return intel_crt_ddc_get_modes(connector, i2c);
 }
 
 static int intel_crt_set_property(struct drm_connector *connector,
index f6159765f1ebe8cf8f6844c092deddd37bd44040..2dfa6cf4886b6a2a3b31b90d1df489634a30df3f 100644 (file)
@@ -869,6 +869,7 @@ intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
        unsigned long bestppm, ppm, absppm;
        int dotclk, flag;
 
+       flag = 0;
        dotclk = target * 1000;
        bestppm = 1000000;
        ppm = absppm = 0;
@@ -1383,7 +1384,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
                                     enum pipe pipe, int reg)
 {
        u32 val = I915_READ(reg);
-       WARN(hdmi_pipe_enabled(dev_priv, val, pipe),
+       WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
             "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
             reg, pipe_name(pipe));
 
@@ -1403,13 +1404,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
 
        reg = PCH_ADPA;
        val = I915_READ(reg);
-       WARN(adpa_pipe_enabled(dev_priv, val, pipe),
+       WARN(adpa_pipe_enabled(dev_priv, pipe, val),
             "PCH VGA enabled on transcoder %c, should be disabled\n",
             pipe_name(pipe));
 
        reg = PCH_LVDS;
        val = I915_READ(reg);
-       WARN(lvds_pipe_enabled(dev_priv, val, pipe),
+       WARN(lvds_pipe_enabled(dev_priv, pipe, val),
             "PCH LVDS enabled on transcoder %c, should be disabled\n",
             pipe_name(pipe));
 
@@ -1871,7 +1872,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
                             enum pipe pipe, int reg)
 {
        u32 val = I915_READ(reg);
-       if (hdmi_pipe_enabled(dev_priv, val, pipe)) {
+       if (hdmi_pipe_enabled(dev_priv, pipe, val)) {
                DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",
                              reg, pipe);
                I915_WRITE(reg, val & ~PORT_ENABLE);
@@ -1893,12 +1894,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
 
        reg = PCH_ADPA;
        val = I915_READ(reg);
-       if (adpa_pipe_enabled(dev_priv, val, pipe))
+       if (adpa_pipe_enabled(dev_priv, pipe, val))
                I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
 
        reg = PCH_LVDS;
        val = I915_READ(reg);
-       if (lvds_pipe_enabled(dev_priv, val, pipe)) {
+       if (lvds_pipe_enabled(dev_priv, pipe, val)) {
                DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);
                I915_WRITE(reg, val & ~LVDS_PORT_EN);
                POSTING_READ(reg);
@@ -3753,17 +3754,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        continue;
                }
 
-               if (intel_encoder->type == INTEL_OUTPUT_EDP) {
-                       /* Use VBT settings if we have an eDP panel */
-                       unsigned int edp_bpc = dev_priv->edp.bpp / 3;
-
-                       if (edp_bpc < display_bpc) {
-                               DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
-                               display_bpc = edp_bpc;
-                       }
-                       continue;
-               }
-
                /* Not one of the known troublemakers, check the EDID */
                list_for_each_entry(connector, &dev->mode_config.connector_list,
                                    head) {
index 0a56b9ab0f5893d49b60499ae75db9f387b6fa2e..a6c426afaa7aca46144f5a3710c0ea6f10a46b83 100644 (file)
@@ -1174,10 +1174,14 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
        WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
 
        pp = ironlake_get_pp_control(dev_priv);
-       pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+       /* We need to switch off panel power _and_ force vdd, for otherwise some
+        * panels get very unhappy and cease to work. */
+       pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
 
+       intel_dp->want_panel_vdd = false;
+
        ironlake_wait_panel_off(intel_dp);
 }
 
@@ -1287,11 +1291,9 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
         * ensure that we have vdd while we switch off the panel. */
        ironlake_edp_panel_vdd_on(intel_dp);
        ironlake_edp_backlight_off(intel_dp);
-       ironlake_edp_panel_off(intel_dp);
-
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+       ironlake_edp_panel_off(intel_dp);
        intel_dp_link_down(intel_dp);
-       ironlake_edp_panel_vdd_off(intel_dp, false);
 }
 
 static void intel_dp_commit(struct drm_encoder *encoder)
@@ -1326,11 +1328,9 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
                /* Switching the panel off requires vdd. */
                ironlake_edp_panel_vdd_on(intel_dp);
                ironlake_edp_backlight_off(intel_dp);
-               ironlake_edp_panel_off(intel_dp);
-
                intel_dp_sink_dpms(intel_dp, mode);
+               ironlake_edp_panel_off(intel_dp);
                intel_dp_link_down(intel_dp);
-               ironlake_edp_panel_vdd_off(intel_dp, false);
 
                if (is_cpu_edp(intel_dp))
                        ironlake_edp_pll_off(encoder);
index 84353559441cc2169dde4bef5042949de62ef251..cd54cf88a28fe408519a6bd14e8f0b71659fd498 100644 (file)
 })
 
 #define wait_for_atomic_us(COND, US) ({ \
-       int i, ret__ = -ETIMEDOUT;      \
-       for (i = 0; i < (US); i++) {    \
-               if ((COND)) {           \
-                       ret__ = 0;      \
-                       break;          \
-               }                       \
-               udelay(1);              \
-       }                               \
-       ret__;                          \
+       unsigned long timeout__ = jiffies + usecs_to_jiffies(US);       \
+       int ret__ = 0;                                                  \
+       while (!(COND)) {                                               \
+               if (time_after(jiffies, timeout__)) {                   \
+                       ret__ = -ETIMEDOUT;                             \
+                       break;                                          \
+               }                                                       \
+               cpu_relax();                                            \
+       }                                                               \
+       ret__;                                                          \
 })
 
 #define wait_for(COND, MS) _wait_for(COND, MS, 1)
@@ -341,6 +342,8 @@ struct intel_fbc_work {
        int interval;
 };
 
+int intel_connector_update_modes(struct drm_connector *connector,
+                               struct edid *edid);
 int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
 
 extern void intel_attach_force_audio_property(struct drm_connector *connector);
@@ -380,7 +383,6 @@ extern void intel_pch_panel_fitting(struct drm_device *dev,
                                    const struct drm_display_mode *mode,
                                    struct drm_display_mode *adjusted_mode);
 extern u32 intel_panel_get_max_backlight(struct drm_device *dev);
-extern u32 intel_panel_get_backlight(struct drm_device *dev);
 extern void intel_panel_set_backlight(struct drm_device *dev, u32 level);
 extern int intel_panel_setup_backlight(struct drm_device *dev);
 extern void intel_panel_enable_backlight(struct drm_device *dev,
index 1991a4408cf9e10896bd5295ba4b3b4b1d74856b..b9755f6378d8d5a6b4ad9a979ce54b49b84a9814 100644 (file)
@@ -486,9 +486,6 @@ int intel_setup_gmbus(struct drm_device *dev)
                bus->dev_priv = dev_priv;
 
                bus->adapter.algo = &gmbus_algorithm;
-               ret = i2c_add_adapter(&bus->adapter);
-               if (ret)
-                       goto err;
 
                /* By default use a conservative clock rate */
                bus->reg0 = port | GMBUS_RATE_100KHZ;
@@ -498,6 +495,10 @@ int intel_setup_gmbus(struct drm_device *dev)
                        bus->force_bit = true;
 
                intel_gpio_setup(bus, port);
+
+               ret = i2c_add_adapter(&bus->adapter);
+               if (ret)
+                       goto err;
        }
 
        intel_i2c_reset(dev_priv->dev);
@@ -540,9 +541,6 @@ void intel_teardown_gmbus(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
 
-       if (dev_priv->gmbus == NULL)
-               return;
-
        for (i = 0; i < GMBUS_NUM_PORTS; i++) {
                struct intel_gmbus *bus = &dev_priv->gmbus[i];
                i2c_del_adapter(&bus->adapter);
index e05c0d3e3440f1398f85806f00203998bbfc24ce..e9a6f6aaed855dfa5acad6026c0f95e79a33955e 100644 (file)
@@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+               .ident = "Gigabyte GA-D525TUD",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
+                       DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
+               },
+       },
 
        { }     /* terminating entry */
 };
index 45848b9b670b0538625a18fca7427fd98a3155ae..29b72593fbb276fbce8b2ae00828cc7c48a06bf3 100644 (file)
 #include "intel_drv.h"
 #include "i915_drv.h"
 
+/**
+ * intel_connector_update_modes - update connector from edid
+ * @connector: DRM connector device to use
+ * @edid: previously read EDID information
+ */
+int intel_connector_update_modes(struct drm_connector *connector,
+                               struct edid *edid)
+{
+       int ret;
+
+       drm_mode_connector_update_edid_property(connector, edid);
+       ret = drm_add_edid_modes(connector, edid);
+       drm_edid_to_eld(connector, edid);
+       connector->display_info.raw_edid = NULL;
+       kfree(edid);
+
+       return ret;
+}
+
 /**
  * intel_ddc_get_modes - get modelist from monitor
  * @connector: DRM connector device to use
@@ -43,18 +62,12 @@ int intel_ddc_get_modes(struct drm_connector *connector,
                        struct i2c_adapter *adapter)
 {
        struct edid *edid;
-       int ret = 0;
 
        edid = drm_get_edid(connector, adapter);
-       if (edid) {
-               drm_mode_connector_update_edid_property(connector, edid);
-               ret = drm_add_edid_modes(connector, edid);
-               drm_edid_to_eld(connector, edid);
-               connector->display_info.raw_edid = NULL;
-               kfree(edid);
-       }
+       if (!edid)
+               return 0;
 
-       return ret;
+       return intel_connector_update_modes(connector, edid);
 }
 
 static const struct drm_prop_enum_list force_audio_names[] = {
index 10c7d39034e1c8c0a3e17491e17ffa3286b5f97a..3df4f5fa892ad847b394c2050e8956779473afd8 100644 (file)
@@ -213,7 +213,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
        return val;
 }
 
-u32 intel_panel_get_backlight(struct drm_device *dev)
+static u32 intel_panel_get_backlight(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 val;
@@ -311,9 +311,6 @@ void intel_panel_enable_backlight(struct drm_device *dev,
        if (dev_priv->backlight_level == 0)
                dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
 
-       dev_priv->backlight_enabled = true;
-       intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
-
        if (INTEL_INFO(dev)->gen >= 4) {
                uint32_t reg, tmp;
 
@@ -326,7 +323,7 @@ void intel_panel_enable_backlight(struct drm_device *dev,
                 * we don't track the backlight dpms state, hence check whether
                 * we have to do anything first. */
                if (tmp & BLM_PWM_ENABLE)
-                       return;
+                       goto set_level;
 
                if (dev_priv->num_pipe == 3)
                        tmp &= ~BLM_PIPE_SELECT_IVB;
@@ -347,6 +344,14 @@ void intel_panel_enable_backlight(struct drm_device *dev,
                        I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
                }
        }
+
+set_level:
+       /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
+        * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
+        * registers are set.
+        */
+       dev_priv->backlight_enabled = true;
+       intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
 }
 
 static void intel_panel_init_backlight(struct drm_device *dev)
index 94aabcaa3a673a46aa0e9361133aa3331ed8e453..1881c8c83f0e0c44ab009dfed7049235c4074d97 100644 (file)
@@ -2441,17 +2441,10 @@ static void gen6_enable_rps(struct drm_device *dev)
                   dev_priv->max_delay << 24 |
                   dev_priv->min_delay << 16);
 
-       if (IS_HASWELL(dev)) {
-               I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
-               I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
-               I915_WRITE(GEN6_RP_UP_EI, 66000);
-               I915_WRITE(GEN6_RP_DOWN_EI, 350000);
-       } else {
-               I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000);
-               I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000);
-               I915_WRITE(GEN6_RP_UP_EI, 100000);
-               I915_WRITE(GEN6_RP_DOWN_EI, 5000000);
-       }
+       I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
+       I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
+       I915_WRITE(GEN6_RP_UP_EI, 66000);
+       I915_WRITE(GEN6_RP_DOWN_EI, 350000);
 
        I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
        I915_WRITE(GEN6_RP_CONTROL,
@@ -3963,6 +3956,7 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
                DRM_ERROR("Force wake wait timed out\n");
 
        I915_WRITE_NOTRACE(FORCEWAKE, 1);
+       POSTING_READ(FORCEWAKE);
 
        if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500))
                DRM_ERROR("Force wake wait timed out\n");
@@ -3983,6 +3977,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
                DRM_ERROR("Force wake wait timed out\n");
 
        I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1));
+       POSTING_READ(FORCEWAKE_MT);
 
        if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500))
                DRM_ERROR("Force wake wait timed out\n");
@@ -4018,14 +4013,14 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
 static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
 {
        I915_WRITE_NOTRACE(FORCEWAKE, 0);
-       /* The below doubles as a POSTING_READ */
+       POSTING_READ(FORCEWAKE);
        gen6_gt_check_fifodbg(dev_priv);
 }
 
 static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
 {
        I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1));
-       /* The below doubles as a POSTING_READ */
+       POSTING_READ(FORCEWAKE_MT);
        gen6_gt_check_fifodbg(dev_priv);
 }
 
index bf0195a96d5308c48d273cb492081a8d415ba188..e2a73b38abe96e7dc49674d39806c5ca3cab6e51 100644 (file)
@@ -227,31 +227,36 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring,
         * number of bits based on the write domains has little performance
         * impact.
         */
-       flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
-       flags |= PIPE_CONTROL_TLB_INVALIDATE;
-       flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
-       flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
-       flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
-       flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
-       flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
-       flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
-       /*
-        * Ensure that any following seqno writes only happen when the render
-        * cache is indeed flushed (but only if the caller actually wants that).
-        */
-       if (flush_domains)
+       if (flush_domains) {
+               flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               /*
+                * Ensure that any following seqno writes only happen
+                * when the render cache is indeed flushed.
+                */
                flags |= PIPE_CONTROL_CS_STALL;
+       }
+       if (invalidate_domains) {
+               flags |= PIPE_CONTROL_TLB_INVALIDATE;
+               flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+               /*
+                * TLB invalidate requires a post-sync write.
+                */
+               flags |= PIPE_CONTROL_QW_WRITE;
+       }
 
-       ret = intel_ring_begin(ring, 6);
+       ret = intel_ring_begin(ring, 4);
        if (ret)
                return ret;
 
-       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5));
+       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4));
        intel_ring_emit(ring, flags);
        intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT);
-       intel_ring_emit(ring, 0); /* lower dword */
-       intel_ring_emit(ring, 0); /* uppwer dword */
-       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_emit(ring, 0);
        intel_ring_advance(ring);
 
        return 0;
@@ -289,8 +294,6 @@ static int init_ring_common(struct intel_ring_buffer *ring)
        I915_WRITE_HEAD(ring, 0);
        ring->write_tail(ring, 0);
 
-       /* Initialize the ring. */
-       I915_WRITE_START(ring, obj->gtt_offset);
        head = I915_READ_HEAD(ring) & HEAD_ADDR;
 
        /* G45 ring initialization fails to reset head to zero */
@@ -316,6 +319,11 @@ static int init_ring_common(struct intel_ring_buffer *ring)
                }
        }
 
+       /* Initialize the ring. This must happen _after_ we've cleared the ring
+        * registers with the above sequence (the readback of the HEAD registers
+        * also enforces ordering), otherwise the hw might lose the new ring
+        * register values. */
+       I915_WRITE_START(ring, obj->gtt_offset);
        I915_WRITE_CTL(ring,
                        ((ring->size - PAGE_SIZE) & RING_NR_PAGES)
                        | RING_VALID);
index 26a6a4d0d0788b536de65f3b4ca6261768115179..d81bb0bf28850f4ea734dedabec44d8478b12d44 100644 (file)
@@ -444,13 +444,16 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
        struct i2c_msg *msgs;
        int i, ret = true;
 
+        /* Would be simpler to allocate both in one go ? */        
        buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL);
        if (!buf)
                return false;
 
        msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL);
-       if (!msgs)
+       if (!msgs) {
+               kfree(buf);
                return false;
+        }
 
        intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
 
@@ -1689,6 +1692,7 @@ static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
        edid = intel_sdvo_get_edid(connector);
        if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)
                has_audio = drm_detect_monitor_audio(edid);
+       kfree(edid);
 
        return has_audio;
 }
index cc8df4de2d921691fdee876b1cdc9b97acb39b8f..7644f31a3778685bb3e21c021e1ad76c5afb2e95 100644 (file)
@@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
 
        switch (fb->pixel_format) {
        case DRM_FORMAT_XBGR8888:
-               sprctl |= SPRITE_FORMAT_RGBX888;
+               sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
                pixel_size = 4;
                break;
        case DRM_FORMAT_XRGB8888:
-               sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
+               sprctl |= SPRITE_FORMAT_RGBX888;
                pixel_size = 4;
                break;
        case DRM_FORMAT_YUYV:
index a4d7c500c97b7f43d049a8ed8cc6bca59b20c100..b69642d5d850581694fe8741056a5d0529f4eeed 100644 (file)
@@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
 {
        unsigned int vcomax, vcomin, pllreffreq;
        unsigned int delta, tmpdelta;
-       unsigned int testr, testn, testm, testo;
+       int testr, testn, testm, testo;
        unsigned int p, m, n;
-       unsigned int computed;
+       unsigned int computed, vco;
        int tmp;
+       const unsigned int m_div_val[] = { 1, 2, 4, 8 };
 
        m = n = p = 0;
        vcomax = 1488000;
@@ -490,12 +491,13 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
                                if (delta == 0)
                                        break;
                                for (testo = 5; testo < 33; testo++) {
-                                       computed = pllreffreq * (testn + 1) /
+                                       vco = pllreffreq * (testn + 1) /
                                                (testr + 1);
-                                       if (computed < vcomin)
+                                       if (vco < vcomin)
                                                continue;
-                                       if (computed > vcomax)
+                                       if (vco > vcomax)
                                                continue;
+                                       computed = vco / (m_div_val[testm] * (testo + 1));
                                        if (computed > clock)
                                                tmpdelta = computed - clock;
                                        else
index fc841e87b343a6aa71cc05bb7f4ae94e7399fafc..26ebffebe7107db7accfecc619b282ba0b271252 100644 (file)
@@ -211,11 +211,6 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
        return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
 }
 
-static int nouveau_dsm_init(void)
-{
-       return 0;
-}
-
 static int nouveau_dsm_get_client_id(struct pci_dev *pdev)
 {
        /* easy option one - intel vendor ID means Integrated */
@@ -232,7 +227,6 @@ static int nouveau_dsm_get_client_id(struct pci_dev *pdev)
 static struct vga_switcheroo_handler nouveau_dsm_handler = {
        .switchto = nouveau_dsm_switchto,
        .power_state = nouveau_dsm_power_state,
-       .init = nouveau_dsm_init,
        .get_client_id = nouveau_dsm_get_client_id,
 };
 
index 77e564667b5c89d6fec1ad5e58f55ce5082f2c42..240cf962c999ee322e4f77fe2e612ffc731e6eb7 100644 (file)
@@ -229,7 +229,7 @@ nouveau_i2c_init(struct drm_device *dev)
                        }
                        break;
                case 6: /* NV50- DP AUX */
-                       port->drive = entry[0];
+                       port->drive = entry[0] & 0x0f;
                        port->sense = port->drive;
                        port->adapter.algo = &nouveau_dp_i2c_algo;
                        break;
index 1cdfd6e757ce7455c03ea35eaef42dbe6253ab7b..c61014442aa931cfe5822069c7ecf6c0d565f4dc 100644 (file)
@@ -731,15 +731,16 @@ nouveau_card_init(struct drm_device *dev)
                        case 0xa3:
                        case 0xa5:
                        case 0xa8:
-                       case 0xaf:
                                nva3_copy_create(dev);
                                break;
                        }
                        break;
                case NV_C0:
-                       nvc0_copy_create(dev, 1);
+                       if (!(nv_rd32(dev, 0x022500) & 0x00000200))
+                               nvc0_copy_create(dev, 1);
                case NV_D0:
-                       nvc0_copy_create(dev, 0);
+                       if (!(nv_rd32(dev, 0x022500) & 0x00000100))
+                               nvc0_copy_create(dev, 0);
                        break;
                default:
                        break;
index cc82d799fc3ba162ae2798d3a5e0df1e6db4abec..c564c5e4c30aa97841f5cf1060d3bbcf8686ebbf 100644 (file)
@@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine)
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        unsigned long flags;
+       u32 save;
 
        /* remove channel from playlist, will context switch if active */
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
        nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000);
        nv50_fifo_playlist_update(dev);
 
+       save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
+
        /* tell any engines on this channel to unload their contexts */
        nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12);
        if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff))
                NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id);
 
+       nv_wr32(dev, 0x002520, save);
+
        nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000);
        spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
@@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nv84_fifo_priv *priv = nv_engine(dev, engine);
        int i;
+       u32 save;
 
        /* set playlist length to zero, fifo will unload context */
        nv_wr32(dev, 0x0032ec, 0);
 
+       save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
+
        /* tell all connected engines to unload their contexts */
        for (i = 0; i < priv->base.channels; i++) {
                struct nouveau_channel *chan = dev_priv->channels.ptr[i];
@@ -199,6 +207,7 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend)
                }
        }
 
+       nv_wr32(dev, 0x002520, save);
        nv_wr32(dev, 0x002140, 0);
        return 0;
 }
index 7c95c44e2887b870096964d600b98c80a0e16505..4e712b10ebdb682c7956c74a5f3e694ff57e61dd 100644 (file)
@@ -557,7 +557,7 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info)
        nouveau_mem_exec(&exec, info->perflvl);
 
        if (dev_priv->chipset < 0xd0)
-               nv_wr32(dev, 0x611200, 0x00003300);
+               nv_wr32(dev, 0x611200, 0x00003330);
        else
                nv_wr32(dev, 0x62c000, 0x03030300);
 }
index d0d60e1e7f95bf74c7209f81f6cd205edd8d71a5..dac525b2994ee4bd28ff862625e7a6fe7649d2cd 100644 (file)
@@ -790,7 +790,7 @@ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        int ch = EVO_CURS(nv_crtc->index);
 
-       evo_piow(crtc->dev, ch, 0x0084, (y << 16) | x);
+       evo_piow(crtc->dev, ch, 0x0084, (y << 16) | (x & 0xffff));
        evo_piow(crtc->dev, ch, 0x0080, 0x00000000);
        return 0;
 }
index 1855ecbd843b81161245cfd15ccb1f4e7f8e2343..e98d144e6eb9df766fc458e03bdd35acef349ce4 100644 (file)
@@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
        printk(" on channel 0x%010llx\n", (u64)inst << 12);
 }
 
+static int
+nve0_fifo_page_flip(struct drm_device *dev, u32 chid)
+{
+       struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_channel *chan = NULL;
+       unsigned long flags;
+       int ret = -EINVAL;
+
+       spin_lock_irqsave(&dev_priv->channels.lock, flags);
+       if (likely(chid >= 0 && chid < priv->base.channels)) {
+               chan = dev_priv->channels.ptr[chid];
+               if (likely(chan))
+                       ret = nouveau_finish_page_flip(chan, NULL);
+       }
+       spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
+       return ret;
+}
+
 static void
 nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 {
@@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
        u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f;
        u32 subc = (addr & 0x00070000);
        u32 mthd = (addr & 0x00003ffc);
+       u32 show = stat;
+
+       if (stat & 0x00200000) {
+               if (mthd == 0x0054) {
+                       if (!nve0_fifo_page_flip(dev, chid))
+                               show &= ~0x00200000;
+               }
+       }
 
-       NV_INFO(dev, "PSUBFIFO %d:", unit);
-       nouveau_bitfield_print(nve0_fifo_subfifo_intr, stat);
-       NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
-               unit, chid, subc, mthd, data);
+       if (show) {
+               NV_INFO(dev, "PFIFO%d:", unit);
+               nouveau_bitfield_print(nve0_fifo_subfifo_intr, show);
+               NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
+                       unit, chid, subc, mthd, data);
+       }
 
        nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008);
        nv_wr32(dev, 0x040108 + (unit * 0x2000), stat);
index 9e6f76fec52789b4931e4e1098b9b52df765c270..2817101fb167eb1f70ac36d88e2f4f1c58dd2427 100644 (file)
@@ -258,8 +258,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
                radeon_crtc->enabled = true;
                /* adjust pm to dpms changes BEFORE enabling crtcs */
                radeon_pm_compute_clocks(rdev);
-               /* disable crtc pair power gating before programming */
-               if (ASIC_IS_DCE6(rdev))
+               if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
                        atombios_powergate_crtc(crtc, ATOM_DISABLE);
                atombios_enable_crtc(crtc, ATOM_ENABLE);
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
@@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
                        atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
                atombios_enable_crtc(crtc, ATOM_DISABLE);
                radeon_crtc->enabled = false;
-               /* power gating is per-pair */
-               if (ASIC_IS_DCE6(rdev)) {
-                       struct drm_crtc *other_crtc;
-                       struct radeon_crtc *other_radeon_crtc;
-                       list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) {
-                               other_radeon_crtc = to_radeon_crtc(other_crtc);
-                               if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) ||
-                                   ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) ||
-                                   ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) ||
-                                   ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) ||
-                                   ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) ||
-                                   ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) {
-                                       /* if both crtcs in the pair are off, enable power gating */
-                                       if (other_radeon_crtc->enabled == false)
-                                               atombios_powergate_crtc(crtc, ATOM_ENABLE);
-                                       break;
-                               }
-                       }
-               }
+               if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+                       atombios_powergate_crtc(crtc, ATOM_ENABLE);
                /* adjust pm to dpms changes AFTER disabling crtcs */
                radeon_pm_compute_clocks(rdev);
                break;
@@ -444,11 +426,28 @@ union atom_enable_ss {
 static void atombios_crtc_program_ss(struct radeon_device *rdev,
                                     int enable,
                                     int pll_id,
+                                    int crtc_id,
                                     struct radeon_atom_ss *ss)
 {
+       unsigned i;
        int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
        union atom_enable_ss args;
 
+       if (!enable) {
+               for (i = 0; i < rdev->num_crtc; i++) {
+                       if (rdev->mode_info.crtcs[i] &&
+                           rdev->mode_info.crtcs[i]->enabled &&
+                           i != crtc_id &&
+                           pll_id == rdev->mode_info.crtcs[i]->pll_id) {
+                               /* one other crtc is using this pll don't turn
+                                * off spread spectrum as it might turn off
+                                * display on active crtc
+                                */
+                               return;
+                       }
+               }
+       }
+
        memset(&args, 0, sizeof(args));
 
        if (ASIC_IS_DCE5(rdev)) {
@@ -1028,7 +1027,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
                radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
                                          &ref_div, &post_div);
 
-       atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
+       atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);
 
        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
                                  encoder_mode, radeon_encoder->encoder_id, mode->clock,
@@ -1051,7 +1050,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
                        ss.step = step_size;
                }
 
-               atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
+               atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);
        }
 }
 
@@ -1531,12 +1530,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
                                 * crtc virtual pixel clock.
                                 */
                                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
-                                       if (ASIC_IS_DCE5(rdev))
-                                               return ATOM_DCPLL;
+                                       if (rdev->clock.dp_extclk)
+                                               return ATOM_PPLL_INVALID;
                                        else if (ASIC_IS_DCE6(rdev))
                                                return ATOM_PPLL0;
-                                       else if (rdev->clock.dp_extclk)
-                                               return ATOM_PPLL_INVALID;
+                                       else if (ASIC_IS_DCE5(rdev))
+                                               return ATOM_DCPLL;
                                }
                        }
                }
@@ -1572,11 +1571,11 @@ void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
                                                                   ASIC_INTERNAL_SS_ON_DCPLL,
                                                                   rdev->clock.default_dispclk);
                if (ss_enabled)
-                       atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
+                       atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss);
                /* XXX: DCE5, make sure voltage, dispclk is high enough */
                atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
                if (ss_enabled)
-                       atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
+                       atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss);
        }
 
 }
@@ -1635,18 +1634,28 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
 static void atombios_crtc_prepare(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
 
+       radeon_crtc->in_mode_set = true;
        /* pick pll */
        radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
 
+       /* disable crtc pair power gating before programming */
+       if (ASIC_IS_DCE6(rdev))
+               atombios_powergate_crtc(crtc, ATOM_DISABLE);
+
        atombios_lock_crtc(crtc, ATOM_ENABLE);
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void atombios_crtc_commit(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
        atombios_lock_crtc(crtc, ATOM_DISABLE);
+       radeon_crtc->in_mode_set = false;
 }
 
 static void atombios_crtc_disable(struct drm_crtc *crtc)
@@ -1655,9 +1664,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_atom_ss ss;
+       int i;
 
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 
+       for (i = 0; i < rdev->num_crtc; i++) {
+               if (rdev->mode_info.crtcs[i] &&
+                   rdev->mode_info.crtcs[i]->enabled &&
+                   i != radeon_crtc->crtc_id &&
+                   radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) {
+                       /* one other crtc is using this pll don't turn
+                        * off the pll
+                        */
+                       goto done;
+               }
+       }
+
        switch (radeon_crtc->pll_id) {
        case ATOM_PPLL1:
        case ATOM_PPLL2:
@@ -1674,6 +1696,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
        default:
                break;
        }
+done:
        radeon_crtc->pll_id = -1;
 }
 
index 7712cf5ab33b9a107ddf6ef61f1122622a358951..3623b98ed3fe2ab529617e37ceb41dfcf4fd5882 100644 (file)
@@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+       u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector);
+       u8 tmp;
 
        if (!ASIC_IS_DCE4(rdev))
                return panel_mode;
 
-       if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
-           ENCODER_OBJECT_ID_NUTMEG)
-               panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
-       else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
-                ENCODER_OBJECT_ID_TRAVIS) {
-               u8 id[6];
-               int i;
-               for (i = 0; i < 6; i++)
-                       id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i);
-               if (id[0] == 0x73 &&
-                   id[1] == 0x69 &&
-                   id[2] == 0x76 &&
-                   id[3] == 0x61 &&
-                   id[4] == 0x72 &&
-                   id[5] == 0x54)
+       if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
+               /* DP bridge chips */
+               tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
+               if (tmp & 1)
+                       panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+               else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
+                        (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
                        panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
                else
-                       panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+                       panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
        } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
-               u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
+               /* eDP */
+               tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
                if (tmp & 1)
                        panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
        }
index f9bc27fe269a125b54803350b838a9062f0e6337..6e8803a1170c24b052a0193ce58294605fed01fd 100644 (file)
@@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
        struct radeon_connector *radeon_connector = NULL;
        struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
@@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
 
        switch (mode) {
        case DRM_MODE_DPMS_ON:
-               /* some early dce3.2 boards have a bug in their transmitter control table */
-               if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) ||
-                   ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
-                       if (ASIC_IS_DCE6(rdev)) {
-                               /* It seems we need to call ATOM_ENCODER_CMD_SETUP again
-                                * before reenabling encoder on DPMS ON, otherwise we never
-                                * get picture
-                                */
-                               atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
+               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+                       if (!connector)
+                               dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+                       else
+                               dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
+
+                       /* setup and enable the encoder */
+                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
+                       atombios_dig_encoder_setup(encoder,
+                                                  ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
+                                                  dig->panel_mode);
+                       if (ext_encoder) {
+                               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+                                       atombios_external_encoder_setup(encoder, ext_encoder,
+                                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
                        }
                        atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
-               } else {
+               } else if (ASIC_IS_DCE4(rdev)) {
+                       /* setup and enable the encoder */
+                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
+                       /* enable the transmitter */
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
                        atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+               } else {
+                       /* setup and enable the encoder and transmitter */
+                       atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+                       /* some early dce3.2 boards have a bug in their transmitter control table */
+                       if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730))
+                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
                }
                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
                        if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
@@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
+               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+                       /* disable the transmitter */
                        atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-               else
+               } else if (ASIC_IS_DCE4(rdev)) {
+                       /* disable the transmitter */
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+               } else {
+                       /* disable the encoder and transmitter */
                        atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+                       atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
+               }
                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
                        if (ASIC_IS_DCE4(rdev))
                                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
@@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_encoder *test_encoder;
-       struct radeon_encoder_atom_dig *dig;
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        uint32_t dig_enc_in_use = 0;
 
-       /* DCE4/5 */
-       if (ASIC_IS_DCE4(rdev)) {
-               dig = radeon_encoder->enc_priv;
-               if (ASIC_IS_DCE41(rdev)) {
+       if (ASIC_IS_DCE6(rdev)) {
+               /* DCE6 */
+               switch (radeon_encoder->encoder_id) {
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+                       if (dig->linkb)
+                               return 1;
+                       else
+                               return 0;
+                       break;
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+                       if (dig->linkb)
+                               return 3;
+                       else
+                               return 2;
+                       break;
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                       if (dig->linkb)
+                               return 5;
+                       else
+                               return 4;
+                       break;
+               }
+       } else if (ASIC_IS_DCE4(rdev)) {
+               /* DCE4/5 */
+               if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) {
                        /* ontario follows DCE4 */
                        if (rdev->family == CHIP_PALM) {
                                if (dig->linkb)
@@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
 
        radeon_encoder->pixel_clock = adjusted_mode->clock;
 
+       /* need to call this here rather than in prepare() since we need some crtc info */
+       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
        if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
                if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
                        atombios_yuv_setup(encoder, true);
@@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
-                       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-                       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-
-                       if (!connector)
-                               dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
-                       else
-                               dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
-
-                       /* setup and enable the encoder */
-                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
-                       atombios_dig_encoder_setup(encoder,
-                                                  ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
-                                                  dig->panel_mode);
-               } else if (ASIC_IS_DCE4(rdev)) {
-                       /* disable the transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-                       /* setup and enable the encoder */
-                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
-
-                       /* enable the transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
-               } else {
-                       /* disable the encoder and transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-                       atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
-
-                       /* setup and enable the encoder and transmitter */
-                       atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
-               }
+               /* handled in dpms */
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
@@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
                break;
        }
 
-       if (ext_encoder) {
-               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
-                       atombios_external_encoder_setup(encoder, ext_encoder,
-                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
-               else
-                       atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
-       }
-
        atombios_apply_encoder_quirks(encoder, adjusted_mode);
 
        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
@@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
        }
 
        radeon_atom_output_lock(encoder, true);
-       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 
        if (connector) {
                struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 
 static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
 {
+       /* need to call this here as we need the crtc set up */
        radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
        radeon_atom_output_lock(encoder, false);
 }
@@ -2177,14 +2190,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               if (ASIC_IS_DCE4(rdev))
-                       /* disable the transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-               else {
-                       /* disable the encoder and transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-                       atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
-               }
+               /* handled in dpms */
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
index e585a3b947eb7c169fe9869aa18880744ab92ef2..e93b80a6d4e969a30cdbbc934d2e8ddd8b8e8a1a 100644 (file)
@@ -1229,24 +1229,8 @@ void evergreen_agp_enable(struct radeon_device *rdev)
 
 void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
 {
-       save->vga_control[0] = RREG32(D1VGA_CONTROL);
-       save->vga_control[1] = RREG32(D2VGA_CONTROL);
        save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
        save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
-       save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
-       save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
-       if (rdev->num_crtc >= 4) {
-               save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
-               save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
-               save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
-               save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
-       }
-       if (rdev->num_crtc >= 6) {
-               save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
-               save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
-               save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
-               save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
-       }
 
        /* Stop all video */
        WREG32(VGA_RENDER_CONTROL, 0);
@@ -1357,47 +1341,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
        /* Unlock host access */
        WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
        mdelay(1);
-       /* Restore video state */
-       WREG32(D1VGA_CONTROL, save->vga_control[0]);
-       WREG32(D2VGA_CONTROL, save->vga_control[1]);
-       if (rdev->num_crtc >= 4) {
-               WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
-               WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
-       }
-       if (rdev->num_crtc >= 6) {
-               WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
-               WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
-       }
-       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
-       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
-       if (rdev->num_crtc >= 4) {
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
-       }
-       if (rdev->num_crtc >= 6) {
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
-       }
-       WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]);
-       WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]);
-       if (rdev->num_crtc >= 4) {
-               WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
-               WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
-       }
-       if (rdev->num_crtc >= 6) {
-               WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]);
-               WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]);
-       }
-       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
-       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-       if (rdev->num_crtc >= 4) {
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
-       }
-       if (rdev->num_crtc >= 6) {
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
-               WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
-       }
        WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
 }
 
@@ -1986,10 +1929,18 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
        if (rdev->flags & RADEON_IS_IGP)
                rdev->config.evergreen.tile_config |= 1 << 4;
        else {
-               if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT)
-                       rdev->config.evergreen.tile_config |= 1 << 4;
-               else
+               switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
+               case 0: /* four banks */
                        rdev->config.evergreen.tile_config |= 0 << 4;
+                       break;
+               case 1: /* eight banks */
+                       rdev->config.evergreen.tile_config |= 1 << 4;
+                       break;
+               case 2: /* sixteen banks */
+               default:
+                       rdev->config.evergreen.tile_config |= 2 << 4;
+                       break;
+               }
        }
        rdev->config.evergreen.tile_config |= 0 << 8;
        rdev->config.evergreen.tile_config |=
index c16554122ccd0fb482aa2f03bc93e8b47af55430..e44a62a07fe396f36e70dd6dce1b4460c6786b45 100644 (file)
@@ -788,6 +788,13 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
        case V_030000_SQ_TEX_DIM_1D_ARRAY:
        case V_030000_SQ_TEX_DIM_2D_ARRAY:
                depth = 1;
+               break;
+       case V_030000_SQ_TEX_DIM_2D_MSAA:
+       case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA:
+               surf.nsamples = 1 << llevel;
+               llevel = 0;
+               depth = 1;
+               break;
        case V_030000_SQ_TEX_DIM_3D:
                break;
        default:
@@ -961,13 +968,15 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
 
        if (track->db_dirty) {
                /* Check stencil buffer */
-               if (G_028800_STENCIL_ENABLE(track->db_depth_control)) {
+               if (G_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID &&
+                   G_028800_STENCIL_ENABLE(track->db_depth_control)) {
                        r = evergreen_cs_track_validate_stencil(p);
                        if (r)
                                return r;
                }
                /* Check depth buffer */
-               if (G_028800_Z_ENABLE(track->db_depth_control)) {
+               if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID &&
+                   G_028800_Z_ENABLE(track->db_depth_control)) {
                        r = evergreen_cs_track_validate_depth(p);
                        if (r)
                                return r;
index d3bd098e4e19d453aee64b691e6519a0d8c97066..79347855d9bf50cf024a34677ca2a4287f9f3df5 100644 (file)
 #define   S_028044_FORMAT(x)                           (((x) & 0x1) << 0)
 #define   G_028044_FORMAT(x)                           (((x) >> 0) & 0x1)
 #define   C_028044_FORMAT                              0xFFFFFFFE
+#define            V_028044_STENCIL_INVALID                    0
+#define            V_028044_STENCIL_8                          1
 #define   G_028044_TILE_SPLIT(x)                       (((x) >> 8) & 0x7)
 #define DB_Z_READ_BASE                                 0x28048
 #define DB_STENCIL_READ_BASE                           0x2804c
index 9945d86d900153b13210bcc967c594c638213f5c..853800e8582f972233dd20f6f6b4573d24f71f2f 100644 (file)
@@ -574,10 +574,18 @@ static void cayman_gpu_init(struct radeon_device *rdev)
        if (rdev->flags & RADEON_IS_IGP)
                rdev->config.cayman.tile_config |= 1 << 4;
        else {
-               if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT)
-                       rdev->config.cayman.tile_config |= 1 << 4;
-               else
+               switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
+               case 0: /* four banks */
                        rdev->config.cayman.tile_config |= 0 << 4;
+                       break;
+               case 1: /* eight banks */
+                       rdev->config.cayman.tile_config |= 1 << 4;
+                       break;
+               case 2: /* sixteen banks */
+               default:
+                       rdev->config.cayman.tile_config |= 2 << 4;
+                       break;
+               }
        }
        rdev->config.cayman.tile_config |=
                ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
index 637280f541a38492e8a0289e209285e0bb518aaf..d79c639ae739cf68a35039d4ca94357d423c534a 100644 (file)
@@ -3789,3 +3789,23 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev)
                WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
        }
 }
+
+/**
+ * r600_get_gpu_clock - return GPU clock counter snapshot
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Fetches a GPU clock counter snapshot (R6xx-cayman).
+ * Returns the 64 bit clock counter snapshot.
+ */
+uint64_t r600_get_gpu_clock(struct radeon_device *rdev)
+{
+       uint64_t clock;
+
+       mutex_lock(&rdev->gpu_clock_mutex);
+       WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+       clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
+               ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+       mutex_unlock(&rdev->gpu_clock_mutex);
+       return clock;
+}
index ca87f7afaf2374d02117ec91e479c1e5a385b8d2..f37676d7f217c56373ba55e7c883098b5736d1f7 100644 (file)
@@ -47,18 +47,23 @@ struct r600_cs_track {
        u32                     npipes;
        /* value we track */
        u32                     sq_config;
+       u32                     log_nsamples;
        u32                     nsamples;
        u32                     cb_color_base_last[8];
        struct radeon_bo        *cb_color_bo[8];
        u64                     cb_color_bo_mc[8];
-       u32                     cb_color_bo_offset[8];
-       struct radeon_bo        *cb_color_frag_bo[8]; /* unused */
-       struct radeon_bo        *cb_color_tile_bo[8]; /* unused */
+       u64                     cb_color_bo_offset[8];
+       struct radeon_bo        *cb_color_frag_bo[8];
+       u64                     cb_color_frag_offset[8];
+       struct radeon_bo        *cb_color_tile_bo[8];
+       u64                     cb_color_tile_offset[8];
+       u32                     cb_color_mask[8];
        u32                     cb_color_info[8];
        u32                     cb_color_view[8];
        u32                     cb_color_size_idx[8]; /* unused */
        u32                     cb_target_mask;
        u32                     cb_shader_mask;  /* unused */
+       bool                    is_resolve;
        u32                     cb_color_size[8];
        u32                     vgt_strmout_en;
        u32                     vgt_strmout_buffer_en;
@@ -311,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track)
                track->cb_color_bo[i] = NULL;
                track->cb_color_bo_offset[i] = 0xFFFFFFFF;
                track->cb_color_bo_mc[i] = 0xFFFFFFFF;
-       }
+               track->cb_color_frag_bo[i] = NULL;
+               track->cb_color_frag_offset[i] = 0xFFFFFFFF;
+               track->cb_color_tile_bo[i] = NULL;
+               track->cb_color_tile_offset[i] = 0xFFFFFFFF;
+               track->cb_color_mask[i] = 0xFFFFFFFF;
+       }
+       track->is_resolve = false;
+       track->nsamples = 16;
+       track->log_nsamples = 4;
        track->cb_target_mask = 0xFFFFFFFF;
        track->cb_shader_mask = 0xFFFFFFFF;
        track->cb_dirty = true;
@@ -348,11 +361,9 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
        volatile u32 *ib = p->ib.ptr;
        unsigned array_mode;
        u32 format;
+       /* When resolve is used, the second colorbuffer has always 1 sample. */
+       unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples;
 
-       if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
-               dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
-               return -EINVAL;
-       }
        size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
        format = G_0280A0_FORMAT(track->cb_color_info[i]);
        if (!r600_fmt_is_valid_color(format)) {
@@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
        array_check.group_size = track->group_size;
        array_check.nbanks = track->nbanks;
        array_check.npipes = track->npipes;
-       array_check.nsamples = track->nsamples;
+       array_check.nsamples = nsamples;
        array_check.blocksize = r600_fmt_get_blocksize(format);
        if (r600_get_array_mode_alignment(&array_check,
                                          &pitch_align, &height_align, &depth_align, &base_align)) {
@@ -420,7 +431,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
        }
 
        /* check offset */
-       tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format);
+       tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) *
+             r600_fmt_get_blocksize(format) * nsamples;
        switch (array_mode) {
        default:
        case V_0280A0_ARRAY_LINEAR_GENERAL:
@@ -441,7 +453,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                         * broken userspace.
                         */
                } else {
-                       dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n",
+                       dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n",
                                 __func__, i, array_mode,
                                 track->cb_color_bo_offset[i], tmp,
                                 radeon_bo_size(track->cb_color_bo[i]),
@@ -458,6 +470,51 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
        tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
                S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
        ib[track->cb_color_size_idx[i]] = tmp;
+
+       /* FMASK/CMASK */
+       switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
+       case V_0280A0_TILE_DISABLE:
+               break;
+       case V_0280A0_FRAG_ENABLE:
+               if (track->nsamples > 1) {
+                       uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]);
+                       /* the tile size is 8x8, but the size is in units of bits.
+                        * for bytes, do just * 8. */
+                       uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1);
+
+                       if (bytes + track->cb_color_frag_offset[i] >
+                           radeon_bo_size(track->cb_color_frag_bo[i])) {
+                               dev_warn(p->dev, "%s FMASK_TILE_MAX too large "
+                                        "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n",
+                                        __func__, tile_max, bytes,
+                                        track->cb_color_frag_offset[i],
+                                        radeon_bo_size(track->cb_color_frag_bo[i]));
+                               return -EINVAL;
+                       }
+               }
+               /* fall through */
+       case V_0280A0_CLEAR_ENABLE:
+       {
+               uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]);
+               /* One block = 128x128 pixels, one 8x8 tile has 4 bits..
+                * (128*128) / (8*8) / 2 = 128 bytes per block. */
+               uint32_t bytes = (block_max + 1) * 128;
+
+               if (bytes + track->cb_color_tile_offset[i] >
+                   radeon_bo_size(track->cb_color_tile_bo[i])) {
+                       dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large "
+                                "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n",
+                                __func__, block_max, bytes,
+                                track->cb_color_tile_offset[i],
+                                radeon_bo_size(track->cb_color_tile_bo[i]));
+                       return -EINVAL;
+               }
+               break;
+       }
+       default:
+               dev_warn(p->dev, "%s invalid tile mode\n", __func__);
+               return -EINVAL;
+       }
        return 0;
 }
 
@@ -566,7 +623,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p)
 
                ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
                nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
-               tmp = ntiles * bpe * 64 * nviews;
+               tmp = ntiles * bpe * 64 * nviews * track->nsamples;
                if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
                        dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
                                        array_mode,
@@ -746,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
         */
        if (track->cb_dirty) {
                tmp = track->cb_target_mask;
+
+               /* We must check both colorbuffers for RESOLVE. */
+               if (track->is_resolve) {
+                       tmp |= 0xff;
+               }
+
                for (i = 0; i < 8; i++) {
                        if ((tmp >> (i * 4)) & 0xF) {
                                /* at least one component is enabled */
@@ -764,8 +827,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
        }
 
        /* Check depth buffer */
-       if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
-               G_028800_Z_ENABLE(track->db_depth_control))) {
+       if (track->db_dirty &&
+           G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID &&
+           (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
+            G_028800_Z_ENABLE(track->db_depth_control))) {
                r = r600_cs_track_validate_db(p);
                if (r)
                        return r;
@@ -1229,9 +1294,15 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                break;
        case R_028C04_PA_SC_AA_CONFIG:
                tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx));
+               track->log_nsamples = tmp;
                track->nsamples = 1 << tmp;
                track->cb_dirty = true;
                break;
+       case R_028808_CB_COLOR_CONTROL:
+               tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx));
+               track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX;
+               track->cb_dirty = true;
+               break;
        case R_0280A0_CB_COLOR0_INFO:
        case R_0280A4_CB_COLOR1_INFO:
        case R_0280A8_CB_COLOR2_INFO:
@@ -1310,16 +1381,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                                dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
                                return -EINVAL;
                        }
-                       ib[idx] = track->cb_color_base_last[tmp];
                        track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
+                       track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp];
+                       ib[idx] = track->cb_color_base_last[tmp];
                } else {
                        r = r600_cs_packet_next_reloc(p, &reloc);
                        if (r) {
                                dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
                                return -EINVAL;
                        }
-                       ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                        track->cb_color_frag_bo[tmp] = reloc->robj;
+                       track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8;
+                       ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               }
+               if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
+                       track->cb_dirty = true;
                }
                break;
        case R_0280C0_CB_COLOR0_TILE:
@@ -1336,16 +1412,35 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                                dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
                                return -EINVAL;
                        }
-                       ib[idx] = track->cb_color_base_last[tmp];
                        track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
+                       track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp];
+                       ib[idx] = track->cb_color_base_last[tmp];
                } else {
                        r = r600_cs_packet_next_reloc(p, &reloc);
                        if (r) {
                                dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
                                return -EINVAL;
                        }
-                       ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                        track->cb_color_tile_bo[tmp] = reloc->robj;
+                       track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8;
+                       ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               }
+               if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
+                       track->cb_dirty = true;
+               }
+               break;
+       case R_028100_CB_COLOR0_MASK:
+       case R_028104_CB_COLOR1_MASK:
+       case R_028108_CB_COLOR2_MASK:
+       case R_02810C_CB_COLOR3_MASK:
+       case R_028110_CB_COLOR4_MASK:
+       case R_028114_CB_COLOR5_MASK:
+       case R_028118_CB_COLOR6_MASK:
+       case R_02811C_CB_COLOR7_MASK:
+               tmp = (reg - R_028100_CB_COLOR0_MASK) / 4;
+               track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx);
+               if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
+                       track->cb_dirty = true;
                }
                break;
        case CB_COLOR0_BASE:
@@ -1490,7 +1585,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level)
 }
 
 static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,
-                             unsigned w0, unsigned h0, unsigned d0, unsigned format,
+                             unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format,
                              unsigned block_align, unsigned height_align, unsigned base_align,
                              unsigned *l0_size, unsigned *mipmap_size)
 {
@@ -1518,7 +1613,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,
 
                depth = r600_mip_minify(d0, i);
 
-               size = nbx * nby * blocksize;
+               size = nbx * nby * blocksize * nsamples;
                if (nfaces)
                        size *= nfaces;
                else
@@ -1557,13 +1652,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
                                              u32 tiling_flags)
 {
        struct r600_cs_track *track = p->track;
-       u32 nfaces, llevel, blevel, w0, h0, d0;
-       u32 word0, word1, l0_size, mipmap_size, word2, word3;
+       u32 dim, nfaces, llevel, blevel, w0, h0, d0;
+       u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5;
        u32 height_align, pitch, pitch_align, depth_align;
-       u32 array, barray, larray;
+       u32 barray, larray;
        u64 base_align;
        struct array_mode_checker array_check;
        u32 format;
+       bool is_array;
 
        /* on legacy kernel we don't perform advanced check */
        if (p->rdev == NULL)
@@ -1581,12 +1677,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
                        word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
        }
        word1 = radeon_get_ib_value(p, idx + 1);
+       word2 = radeon_get_ib_value(p, idx + 2) << 8;
+       word3 = radeon_get_ib_value(p, idx + 3) << 8;
+       word4 = radeon_get_ib_value(p, idx + 4);
+       word5 = radeon_get_ib_value(p, idx + 5);
+       dim = G_038000_DIM(word0);
        w0 = G_038000_TEX_WIDTH(word0) + 1;
+       pitch = (G_038000_PITCH(word0) + 1) * 8;
        h0 = G_038004_TEX_HEIGHT(word1) + 1;
        d0 = G_038004_TEX_DEPTH(word1);
+       format = G_038004_DATA_FORMAT(word1);
+       blevel = G_038010_BASE_LEVEL(word4);
+       llevel = G_038014_LAST_LEVEL(word5);
+       /* pitch in texels */
+       array_check.array_mode = G_038000_TILE_MODE(word0);
+       array_check.group_size = track->group_size;
+       array_check.nbanks = track->nbanks;
+       array_check.npipes = track->npipes;
+       array_check.nsamples = 1;
+       array_check.blocksize = r600_fmt_get_blocksize(format);
        nfaces = 1;
-       array = 0;
-       switch (G_038000_DIM(word0)) {
+       is_array = false;
+       switch (dim) {
        case V_038000_SQ_TEX_DIM_1D:
        case V_038000_SQ_TEX_DIM_2D:
        case V_038000_SQ_TEX_DIM_3D:
@@ -1599,29 +1711,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
                break;
        case V_038000_SQ_TEX_DIM_1D_ARRAY:
        case V_038000_SQ_TEX_DIM_2D_ARRAY:
-               array = 1;
+               is_array = true;
                break;
-       case V_038000_SQ_TEX_DIM_2D_MSAA:
        case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA:
+               is_array = true;
+               /* fall through */
+       case V_038000_SQ_TEX_DIM_2D_MSAA:
+               array_check.nsamples = 1 << llevel;
+               llevel = 0;
+               break;
        default:
                dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0));
                return -EINVAL;
        }
-       format = G_038004_DATA_FORMAT(word1);
        if (!r600_fmt_is_valid_texture(format, p->family)) {
                dev_warn(p->dev, "%s:%d texture invalid format %d\n",
                         __func__, __LINE__, format);
                return -EINVAL;
        }
 
-       /* pitch in texels */
-       pitch = (G_038000_PITCH(word0) + 1) * 8;
-       array_check.array_mode = G_038000_TILE_MODE(word0);
-       array_check.group_size = track->group_size;
-       array_check.nbanks = track->nbanks;
-       array_check.npipes = track->npipes;
-       array_check.nsamples = 1;
-       array_check.blocksize = r600_fmt_get_blocksize(format);
        if (r600_get_array_mode_alignment(&array_check,
                                          &pitch_align, &height_align, &depth_align, &base_align)) {
                dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
@@ -1647,24 +1755,17 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
                return -EINVAL;
        }
 
-       word2 = radeon_get_ib_value(p, idx + 2) << 8;
-       word3 = radeon_get_ib_value(p, idx + 3) << 8;
-
-       word0 = radeon_get_ib_value(p, idx + 4);
-       word1 = radeon_get_ib_value(p, idx + 5);
-       blevel = G_038010_BASE_LEVEL(word0);
-       llevel = G_038014_LAST_LEVEL(word1);
        if (blevel > llevel) {
                dev_warn(p->dev, "texture blevel %d > llevel %d\n",
                         blevel, llevel);
        }
-       if (array == 1) {
-               barray = G_038014_BASE_ARRAY(word1);
-               larray = G_038014_LAST_ARRAY(word1);
+       if (is_array) {
+               barray = G_038014_BASE_ARRAY(word5);
+               larray = G_038014_LAST_ARRAY(word5);
 
                nfaces = larray - barray + 1;
        }
-       r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format,
+       r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format,
                          pitch_align, height_align, base_align,
                          &l0_size, &mipmap_size);
        /* using get ib will give us the offset into the texture bo */
@@ -1677,7 +1778,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
                return -EINVAL;
        }
        /* using get ib will give us the offset into the mipmap bo */
-       word3 = radeon_get_ib_value(p, idx + 3) << 8;
        if ((mipmap_size + word3) > radeon_bo_size(mipmap)) {
                /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
                  w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/
index 4b116ae75fc2cedd41b2e446f1a421b7a085d81b..fa6f37099ba90a6968744f15e4531e7ce3de9d17 100644 (file)
 #define        CC_RB_BACKEND_DISABLE                           0x98F4
 #define                BACKEND_DISABLE(x)                              ((x) << 16)
 
+#define R_028808_CB_COLOR_CONTROL                      0x28808
+#define   S_028808_SPECIAL_OP(x)                       (((x) & 0x7) << 4)
+#define   G_028808_SPECIAL_OP(x)                       (((x) >> 4) & 0x7)
+#define   C_028808_SPECIAL_OP                          0xFFFFFF8F
+#define     V_028808_SPECIAL_NORMAL                     0x00
+#define     V_028808_SPECIAL_DISABLE                    0x01
+#define     V_028808_SPECIAL_RESOLVE_BOX                0x07
+
 #define        CB_COLOR0_BASE                                  0x28040
 #define        CB_COLOR1_BASE                                  0x28044
 #define        CB_COLOR2_BASE                                  0x28048
 #define R_028094_CB_COLOR5_VIEW                      0x028094
 #define R_028098_CB_COLOR6_VIEW                      0x028098
 #define R_02809C_CB_COLOR7_VIEW                      0x02809C
+#define R_028100_CB_COLOR0_MASK                      0x028100
+#define   S_028100_CMASK_BLOCK_MAX(x)                  (((x) & 0xFFF) << 0)
+#define   G_028100_CMASK_BLOCK_MAX(x)                  (((x) >> 0) & 0xFFF)
+#define   C_028100_CMASK_BLOCK_MAX                     0xFFFFF000
+#define   S_028100_FMASK_TILE_MAX(x)                   (((x) & 0xFFFFF) << 12)
+#define   G_028100_FMASK_TILE_MAX(x)                   (((x) >> 12) & 0xFFFFF)
+#define   C_028100_FMASK_TILE_MAX                      0x00000FFF
+#define R_028104_CB_COLOR1_MASK                      0x028104
+#define R_028108_CB_COLOR2_MASK                      0x028108
+#define R_02810C_CB_COLOR3_MASK                      0x02810C
+#define R_028110_CB_COLOR4_MASK                      0x028110
+#define R_028114_CB_COLOR5_MASK                      0x028114
+#define R_028118_CB_COLOR6_MASK                      0x028118
+#define R_02811C_CB_COLOR7_MASK                      0x02811C
 #define CB_COLOR0_INFO                                  0x280a0
 #      define CB_FORMAT(x)                             ((x) << 2)
 #       define CB_ARRAY_MODE(x)                         ((x) << 8)
 #define RLC_HB_WPTR                                       0x3f1c
 #define RLC_HB_WPTR_LSB_ADDR                              0x3f14
 #define RLC_HB_WPTR_MSB_ADDR                              0x3f18
+#define RLC_GPU_CLOCK_COUNT_LSB                                  0x3f38
+#define RLC_GPU_CLOCK_COUNT_MSB                                  0x3f3c
+#define RLC_CAPTURE_GPU_CLOCK_COUNT                      0x3f40
 #define RLC_MC_CNTL                                       0x3f44
 #define RLC_UCODE_CNTL                                    0x3f48
 #define RLC_UCODE_ADDR                                    0x3f2c
 #define   S_0280A0_TILE_MODE(x)                        (((x) & 0x3) << 18)
 #define   G_0280A0_TILE_MODE(x)                        (((x) >> 18) & 0x3)
 #define   C_0280A0_TILE_MODE                           0xFFF3FFFF
+#define     V_0280A0_TILE_DISABLE                      0
+#define     V_0280A0_CLEAR_ENABLE                      1
+#define     V_0280A0_FRAG_ENABLE                       2
 #define   S_0280A0_BLEND_CLAMP(x)                      (((x) & 0x1) << 20)
 #define   G_0280A0_BLEND_CLAMP(x)                      (((x) >> 20) & 0x1)
 #define   C_0280A0_BLEND_CLAMP                         0xFFEFFFFF
index 5431af2924083676e7f017d13d2f32a4b9cc1aca..59a15315ae9fd2551e8745736cb15ff0f5e53280 100644 (file)
@@ -142,21 +142,6 @@ struct radeon_device;
 /*
  * BIOS.
  */
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
-       return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
-       return -EINVAL;
-}
-#endif
 bool radeon_get_bios(struct radeon_device *rdev);
 
 /*
@@ -300,6 +285,7 @@ struct radeon_bo_va {
        uint64_t                        soffset;
        uint64_t                        eoffset;
        uint32_t                        flags;
+       struct radeon_fence             *fence;
        bool                            valid;
 };
 
@@ -1533,6 +1519,7 @@ struct radeon_device {
        unsigned                debugfs_count;
        /* virtual memory */
        struct radeon_vm_manager        vm_manager;
+       struct mutex                    gpu_clock_mutex;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -1733,11 +1720,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev))
 #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev))
 #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev))
-#define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc))
-#define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base))
-#define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc))
-#define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc))
-#define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev))
+#define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc))
+#define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base))
+#define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc))
+#define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc))
+#define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
 
 /* Common functions */
 /* AGP */
index f4af243104387b752638b62809c876970b16ce76..18c38d14c8cd88c70499f2eb03d8a282ca3d68b9 100644 (file)
@@ -255,13 +255,10 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev);
  * rv515
  */
 struct rv515_mc_save {
-       u32 d1vga_control;
-       u32 d2vga_control;
        u32 vga_render_control;
        u32 vga_hdp_control;
-       u32 d1crtc_control;
-       u32 d2crtc_control;
 };
+
 int rv515_init(struct radeon_device *rdev);
 void rv515_fini(struct radeon_device *rdev);
 uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg);
@@ -371,6 +368,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
                        unsigned num_gpu_pages,
                        struct radeon_sa_bo *vb);
 int r600_mc_wait_for_idle(struct radeon_device *rdev);
+uint64_t r600_get_gpu_clock(struct radeon_device *rdev);
 
 /*
  * rv770,rv730,rv710,rv740
@@ -389,11 +387,10 @@ void r700_cp_fini(struct radeon_device *rdev);
  * evergreen
  */
 struct evergreen_mc_save {
-       u32 vga_control[6];
        u32 vga_render_control;
        u32 vga_hdp_control;
-       u32 crtc_control[6];
 };
+
 void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev);
 int evergreen_init(struct radeon_device *rdev);
 void evergreen_fini(struct radeon_device *rdev);
@@ -472,5 +469,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id);
 void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
 void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm);
 int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
+uint64_t si_get_gpu_clock(struct radeon_device *rdev);
 
 #endif
index b1e3820df36397e9c2ad7a7798be5412c0853df2..d67d4f3eb6f424d5400a7f01c2d1e3068785f02b 100644 (file)
@@ -452,7 +452,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
        }
 
        /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */
-       if ((dev->pdev->device == 0x9802) &&
+       if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) &&
            (dev->pdev->subsystem_vendor == 0x1734) &&
            (dev->pdev->subsystem_device == 0x11bd)) {
                if (*connector_type == DRM_MODE_CONNECTOR_VGA) {
@@ -1263,6 +1263,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
 union igp_info {
        struct _ATOM_INTEGRATED_SYSTEM_INFO info;
        struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+       struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
+       struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
 };
 
 bool radeon_atombios_sideport_present(struct radeon_device *rdev)
@@ -1390,27 +1392,50 @@ static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev,
        struct radeon_mode_info *mode_info = &rdev->mode_info;
        int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
        u16 data_offset, size;
-       struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info;
+       union igp_info *igp_info;
        u8 frev, crev;
        u16 percentage = 0, rate = 0;
 
        /* get any igp specific overrides */
        if (atom_parse_data_header(mode_info->atom_context, index, &size,
                                   &frev, &crev, &data_offset)) {
-               igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *)
+               igp_info = (union igp_info *)
                        (mode_info->atom_context->bios + data_offset);
-               switch (id) {
-               case ASIC_INTERNAL_SS_ON_TMDS:
-                       percentage = le16_to_cpu(igp_info->usDVISSPercentage);
-                       rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz);
+               switch (crev) {
+               case 6:
+                       switch (id) {
+                       case ASIC_INTERNAL_SS_ON_TMDS:
+                               percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage);
+                               rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz);
+                               break;
+                       case ASIC_INTERNAL_SS_ON_HDMI:
+                               percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage);
+                               rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz);
+                               break;
+                       case ASIC_INTERNAL_SS_ON_LVDS:
+                               percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage);
+                               rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz);
+                               break;
+                       }
                        break;
-               case ASIC_INTERNAL_SS_ON_HDMI:
-                       percentage = le16_to_cpu(igp_info->usHDMISSPercentage);
-                       rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz);
+               case 7:
+                       switch (id) {
+                       case ASIC_INTERNAL_SS_ON_TMDS:
+                               percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage);
+                               rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz);
+                               break;
+                       case ASIC_INTERNAL_SS_ON_HDMI:
+                               percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage);
+                               rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz);
+                               break;
+                       case ASIC_INTERNAL_SS_ON_LVDS:
+                               percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage);
+                               rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz);
+                               break;
+                       }
                        break;
-               case ASIC_INTERNAL_SS_ON_LVDS:
-                       percentage = le16_to_cpu(igp_info->usLvdsSSPercentage);
-                       rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz);
+               default:
+                       DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
                        break;
                }
                if (percentage)
index 98724fcb00885e8a6ba3e8e88937b209e545a8e8..2a2cf0b88a28b1e7f1c71c4bccbc029adacf63eb 100644 (file)
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
        /* handle for device - and atpx */
        acpi_handle dhandle;
        acpi_handle atpx_handle;
-       acpi_handle atrm_handle;
 } radeon_atpx_priv;
 
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
-                           int offset, int len)
-{
-       acpi_status status;
-       union acpi_object atrm_arg_elements[2], *obj;
-       struct acpi_object_list atrm_arg;
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
-       atrm_arg.count = 2;
-       atrm_arg.pointer = &atrm_arg_elements[0];
-
-       atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
-       atrm_arg_elements[0].integer.value = offset;
-
-       atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
-       atrm_arg_elements[1].integer.value = len;
-
-       status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
-       if (ACPI_FAILURE(status)) {
-               printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
-               return -ENODEV;
-       }
-
-       obj = (union acpi_object *)buffer.pointer;
-       memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
-       len = obj->buffer.length;
-       kfree(buffer.pointer);
-       return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
-       /* get the discrete ROM only via ATRM */
-       if (!radeon_atpx_priv.atpx_detected)
-               return false;
-
-       if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
-               return false;
-       return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
-       return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
-}
-
 static int radeon_atpx_get_version(acpi_handle handle)
 {
        acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
 
 static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
 {
-       acpi_handle dhandle, atpx_handle, atrm_handle;
+       acpi_handle dhandle, atpx_handle;
        acpi_status status;
 
        dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
        if (ACPI_FAILURE(status))
                return false;
 
-       status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
-       if (ACPI_FAILURE(status))
-               return false;
-
        radeon_atpx_priv.dhandle = dhandle;
        radeon_atpx_priv.atpx_handle = atpx_handle;
-       radeon_atpx_priv.atrm_handle = atrm_handle;
        return true;
 }
 
index 501f4881e5aab4d1f1dcb9b57b4ba1a61743d9a7..d306cc8fdeaa918294cf9576e0ab834d05882e87 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
+#include <linux/acpi.h>
 /*
  * BIOS.
  */
@@ -98,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
        return true;
 }
 
+#ifdef CONFIG_ACPI
 /* ATRM is used to get the BIOS on the discrete cards in
  * dual-gpu systems.
  */
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+                           int offset, int len)
+{
+       acpi_status status;
+       union acpi_object atrm_arg_elements[2], *obj;
+       struct acpi_object_list atrm_arg;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+       atrm_arg.count = 2;
+       atrm_arg.pointer = &atrm_arg_elements[0];
+
+       atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
+       atrm_arg_elements[0].integer.value = offset;
+
+       atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
+       atrm_arg_elements[1].integer.value = len;
+
+       status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
+       if (ACPI_FAILURE(status)) {
+               printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
+               return -ENODEV;
+       }
+
+       obj = (union acpi_object *)buffer.pointer;
+       memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+       len = obj->buffer.length;
+       kfree(buffer.pointer);
+       return len;
+}
+
 static bool radeon_atrm_get_bios(struct radeon_device *rdev)
 {
        int ret;
        int size = 256 * 1024;
        int i;
+       struct pci_dev *pdev = NULL;
+       acpi_handle dhandle, atrm_handle;
+       acpi_status status;
+       bool found = false;
+
+       /* ATRM is for the discrete card only */
+       if (rdev->flags & RADEON_IS_IGP)
+               return false;
+
+       while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+               dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+               if (!dhandle)
+                       continue;
+
+               status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
+               if (!ACPI_FAILURE(status)) {
+                       found = true;
+                       break;
+               }
+       }
 
-       if (!radeon_atrm_supported(rdev->pdev))
+       if (!found)
                return false;
 
        rdev->bios = kmalloc(size, GFP_KERNEL);
@@ -117,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
        }
 
        for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
-               ret = radeon_atrm_get_bios_chunk(rdev->bios,
-                                                (i * ATRM_BIOS_PAGE),
-                                                ATRM_BIOS_PAGE);
+               ret = radeon_atrm_call(atrm_handle,
+                                      rdev->bios,
+                                      (i * ATRM_BIOS_PAGE),
+                                      ATRM_BIOS_PAGE);
                if (ret < ATRM_BIOS_PAGE)
                        break;
        }
@@ -130,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
        }
        return true;
 }
+#else
+static inline bool radeon_atrm_get_bios(struct radeon_device *rdev)
+{
+       return false;
+}
+#endif
 
 static bool ni_read_disabled_bios(struct radeon_device *rdev)
 {
@@ -476,6 +549,61 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
                return legacy_read_disabled_bios(rdev);
 }
 
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+       bool ret = false;
+       struct acpi_table_header *hdr;
+       acpi_size tbl_size;
+       UEFI_ACPI_VFCT *vfct;
+       GOP_VBIOS_CONTENT *vbios;
+       VFCT_IMAGE_HEADER *vhdr;
+
+       if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
+               return false;
+       if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+               DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+               goto out_unmap;
+       }
+
+       vfct = (UEFI_ACPI_VFCT *)hdr;
+       if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+               DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+               goto out_unmap;
+       }
+
+       vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+       vhdr = &vbios->VbiosHeader;
+       DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
+                       vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+                       vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+       if (vhdr->PCIBus != rdev->pdev->bus->number ||
+           vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+           vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+           vhdr->VendorID != rdev->pdev->vendor ||
+           vhdr->DeviceID != rdev->pdev->device) {
+               DRM_INFO("ACPI VFCT table is not for this card\n");
+               goto out_unmap;
+       };
+
+       if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
+               DRM_ERROR("ACPI VFCT image truncated\n");
+               goto out_unmap;
+       }
+
+       rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
+       ret = !!rdev->bios;
+
+out_unmap:
+       return ret;
+}
+#else
+static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+       return false;
+}
+#endif
 
 bool radeon_get_bios(struct radeon_device *rdev)
 {
@@ -483,6 +611,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
        uint16_t tmp;
 
        r = radeon_atrm_get_bios(rdev);
+       if (r == false)
+               r = radeon_acpi_vfct_bios(rdev);
        if (r == false)
                r = igp_read_bios_from_vram(rdev);
        if (r == false)
index 576f4f6919f28d075ba0e77365d0a0cc52814f25..f75247d42ffdca3bd62e778f51bba1c6b6d6ab78 100644 (file)
@@ -719,6 +719,34 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
        return i2c;
 }
 
+static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
+{
+       struct drm_device *dev = rdev->ddev;
+       struct radeon_i2c_bus_rec i2c;
+       u16 offset;
+       u8 id, blocks, clk, data;
+       int i;
+
+       i2c.valid = false;
+
+       offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
+       if (offset) {
+               blocks = RBIOS8(offset + 2);
+               for (i = 0; i < blocks; i++) {
+                       id = RBIOS8(offset + 3 + (i * 5) + 0);
+                       if (id == 136) {
+                               clk = RBIOS8(offset + 3 + (i * 5) + 3);
+                               data = RBIOS8(offset + 3 + (i * 5) + 4);
+                               /* gpiopad */
+                               i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
+                                                           (1 << clk), (1 << data));
+                               break;
+                       }
+               }
+       }
+       return i2c;
+}
+
 void radeon_combios_i2c_init(struct radeon_device *rdev)
 {
        struct drm_device *dev = rdev->ddev;
@@ -755,30 +783,14 @@ void radeon_combios_i2c_init(struct radeon_device *rdev)
        } else if (rdev->family == CHIP_RS300 ||
                   rdev->family == CHIP_RS400 ||
                   rdev->family == CHIP_RS480) {
-               u16 offset;
-               u8 id, blocks, clk, data;
-               int i;
-
                /* 0x68 */
                i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
                rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
 
-               offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
-               if (offset) {
-                       blocks = RBIOS8(offset + 2);
-                       for (i = 0; i < blocks; i++) {
-                               id = RBIOS8(offset + 3 + (i * 5) + 0);
-                               if (id == 136) {
-                                       clk = RBIOS8(offset + 3 + (i * 5) + 3);
-                                       data = RBIOS8(offset + 3 + (i * 5) + 4);
-                                       /* gpiopad */
-                                       i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
-                                                                   (1 << clk), (1 << data));
-                                       rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
-                                       break;
-                               }
-                       }
-               }
+               /* gpiopad */
+               i2c = radeon_combios_get_i2c_info_from_table(rdev);
+               if (i2c.valid)
+                       rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
        } else if ((rdev->family == CHIP_R200) ||
                   (rdev->family >= CHIP_R300)) {
                /* 0x68 */
@@ -2321,7 +2333,10 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
                        connector = (tmp >> 12) & 0xf;
 
                        ddc_type = (tmp >> 8) & 0xf;
-                       ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
+                       if (ddc_type == 5)
+                               ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev);
+                       else
+                               ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
 
                        switch (connector) {
                        case CONNECTOR_PROPRIETARY_LEGACY:
index 8a4c49ef0cc4e40170b3300aa7ad9cffeea2bc72..b4a0db24f4ddc4611028b671499d5062bd713649 100644 (file)
@@ -278,6 +278,30 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
        return 0;
 }
 
+static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser,
+                                 struct radeon_fence *fence)
+{
+       struct radeon_fpriv *fpriv = parser->filp->driver_priv;
+       struct radeon_vm *vm = &fpriv->vm;
+       struct radeon_bo_list *lobj;
+
+       if (parser->chunk_ib_idx == -1) {
+               return;
+       }
+       if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) {
+               return;
+       }
+
+       list_for_each_entry(lobj, &parser->validated, tv.head) {
+               struct radeon_bo_va *bo_va;
+               struct radeon_bo *rbo = lobj->bo;
+
+               bo_va = radeon_bo_va(rbo, vm);
+               radeon_fence_unref(&bo_va->fence);
+               bo_va->fence = radeon_fence_ref(fence);
+       }
+}
+
 /**
  * cs_parser_fini() - clean parser states
  * @parser:    parser structure holding parsing context.
@@ -290,11 +314,14 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
 {
        unsigned i;
 
-       if (!error)
+       if (!error) {
+               /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */
+               radeon_bo_vm_fence_va(parser, parser->ib.fence);
                ttm_eu_fence_buffer_objects(&parser->validated,
                                            parser->ib.fence);
-       else
+       } else {
                ttm_eu_backoff_reservation(&parser->validated);
+       }
 
        if (parser->relocs != NULL) {
                for (i = 0; i < parser->nrelocs; i++) {
@@ -388,7 +415,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
 
        if (parser->chunk_ib_idx == -1)
                return 0;
-
        if ((parser->cs_flags & RADEON_CS_USE_VM) == 0)
                return 0;
 
index 711e95ad39bfd600de1be7f94373dc57512ef820..8794744cdf1a58c1c14cb5c0d59dc595f80d05be 100644 (file)
@@ -67,7 +67,8 @@ static void radeon_hide_cursor(struct drm_crtc *crtc)
 
        if (ASIC_IS_DCE4(rdev)) {
                WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
-               WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
+               WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) |
+                      EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2));
        } else if (ASIC_IS_AVIVO(rdev)) {
                WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
                WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
@@ -94,7 +95,8 @@ static void radeon_show_cursor(struct drm_crtc *crtc)
        if (ASIC_IS_DCE4(rdev)) {
                WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
                WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
-                      EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
+                      EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) |
+                      EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2));
        } else if (ASIC_IS_AVIVO(rdev)) {
                WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
                WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
index 742af8244e898e565aed6bb9fa6dcffe1521dd98..7a3daebd732d67d85d40dc04d6aa851af42aae26 100644 (file)
@@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev,
        atomic_set(&rdev->ih.lock, 0);
        mutex_init(&rdev->gem.mutex);
        mutex_init(&rdev->pm.mutex);
+       mutex_init(&rdev->gpu_clock_mutex);
        init_rwsem(&rdev->pm.mclk_lock);
        init_rwsem(&rdev->exclusive_lock);
        init_waitqueue_head(&rdev->irq.vblank_queue);
@@ -1050,7 +1051,7 @@ int radeon_device_init(struct radeon_device *rdev,
        if (rdev->flags & RADEON_IS_AGP)
                rdev->need_dma32 = true;
        if ((rdev->flags & RADEON_IS_PCI) &&
-           (rdev->family < CHIP_RS400))
+           (rdev->family <= CHIP_RS740))
                rdev->need_dma32 = true;
 
        dma_bits = rdev->need_dma32 ? 32 : 40;
@@ -1345,12 +1346,15 @@ retry:
                for (i = 0; i < RADEON_NUM_RINGS; ++i) {
                        radeon_ring_restore(rdev, &rdev->ring[i],
                                            ring_sizes[i], ring_data[i]);
+                       ring_sizes[i] = 0;
+                       ring_data[i] = NULL;
                }
 
                r = radeon_ib_ring_tests(rdev);
                if (r) {
                        dev_err(rdev->dev, "ib ring test failed (%d).\n", r);
                        if (saved) {
+                               saved = false;
                                radeon_suspend(rdev);
                                goto retry;
                        }
index dcea6f01ae4e2ec3fe60def4a345c2528d3fedc9..8c593ea82c412b2098d1c3dac3e1f6167356e6fa 100644 (file)
  *   2.15.0 - add max_pipes query
  *   2.16.0 - fix evergreen 2D tiled surface calculation
  *   2.17.0 - add STRMOUT_BASE_UPDATE for r7xx
+ *   2.18.0 - r600-eg: allow "invalid" DB formats
+ *   2.19.0 - r600-eg: MSAA textures
+ *   2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query
+ *   2.21.0 - r600-r700: FMASK and CMASK
+ *   2.22.0 - r600 only: RESOLVE_BOX allowed
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       17
+#define KMS_DRIVER_MINOR       22
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
index b3720054614db5199684ad1d86924a1fd5c8f34d..bb3b7fe05ccdfe2905b9dc6650e854e6361dec8c 100644 (file)
@@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
                return -EINVAL;
        }
 
-       if (bo_va->valid)
+       if (bo_va->valid && mem)
                return 0;
 
        ngpu_pages = radeon_bo_ngpu_pages(bo);
@@ -859,11 +859,27 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
                     struct radeon_bo *bo)
 {
        struct radeon_bo_va *bo_va;
+       int r;
 
        bo_va = radeon_bo_va(bo, vm);
        if (bo_va == NULL)
                return 0;
 
+       /* wait for va use to end */
+       while (bo_va->fence) {
+               r = radeon_fence_wait(bo_va->fence, false);
+               if (r) {
+                       DRM_ERROR("error while waiting for fence: %d\n", r);
+               }
+               if (r == -EDEADLK) {
+                       r = radeon_gpu_reset(rdev);
+                       if (!r)
+                               continue;
+               }
+               break;
+       }
+       radeon_fence_unref(&bo_va->fence);
+
        mutex_lock(&rdev->vm_manager.lock);
        mutex_lock(&vm->mutex);
        radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
@@ -934,7 +950,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
 }
 
 /**
- * radeon_vm_init - tear down a vm instance
+ * radeon_vm_fini - tear down a vm instance
  *
  * @rdev: radeon_device pointer
  * @vm: requested vm
@@ -952,12 +968,15 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
        radeon_vm_unbind_locked(rdev, vm);
        mutex_unlock(&rdev->vm_manager.lock);
 
-       /* remove all bo */
+       /* remove all bo at this point non are busy any more because unbind
+        * waited for the last vm fence to signal
+        */
        r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
        if (!r) {
                bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm);
                list_del_init(&bo_va->bo_list);
                list_del_init(&bo_va->vm_list);
+               radeon_fence_unref(&bo_va->fence);
                radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
                kfree(bo_va);
        }
@@ -969,6 +988,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
                r = radeon_bo_reserve(bo_va->bo, false);
                if (!r) {
                        list_del_init(&bo_va->bo_list);
+                       radeon_fence_unref(&bo_va->fence);
                        radeon_bo_unreserve(bo_va->bo);
                        kfree(bo_va);
                }
index 84d045245739eb3b049e78f88693d6dc1dd229da..1b57b0058ad642e6d0d610dadbf7af235f517c71 100644 (file)
@@ -134,25 +134,16 @@ void radeon_gem_object_close(struct drm_gem_object *obj,
        struct radeon_device *rdev = rbo->rdev;
        struct radeon_fpriv *fpriv = file_priv->driver_priv;
        struct radeon_vm *vm = &fpriv->vm;
-       struct radeon_bo_va *bo_va, *tmp;
 
        if (rdev->family < CHIP_CAYMAN) {
                return;
        }
 
        if (radeon_bo_reserve(rbo, false)) {
+               dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n");
                return;
        }
-       list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) {
-               if (bo_va->vm == vm) {
-                       /* remove from this vm address space */
-                       mutex_lock(&vm->mutex);
-                       list_del(&bo_va->vm_list);
-                       mutex_unlock(&vm->mutex);
-                       list_del(&bo_va->bo_list);
-                       kfree(bo_va);
-               }
-       }
+       radeon_vm_bo_rmv(rdev, vm, rbo);
        radeon_bo_unreserve(rbo);
 }
 
index 1d73f16b5d97d4b480d18cf3831e134f66fa5e29..414b4acf69479abdfdcda63f226d112c0e3387da 100644 (file)
@@ -29,6 +29,7 @@
 #include "drm_sarea.h"
 #include "radeon.h"
 #include "radeon_drm.h"
+#include "radeon_asic.h"
 
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
@@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev,
 int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
        struct radeon_device *rdev = dev->dev_private;
-       struct drm_radeon_info *info;
+       struct drm_radeon_info *info = data;
        struct radeon_mode_info *minfo = &rdev->mode_info;
-       uint32_t *value_ptr;
-       uint32_t value;
+       uint32_t value, *value_ptr;
+       uint64_t value64, *value_ptr64;
        struct drm_crtc *crtc;
        int i, found;
 
-       info = data;
+       /* TIMESTAMP is a 64-bit value, needs special handling. */
+       if (info->request == RADEON_INFO_TIMESTAMP) {
+               if (rdev->family >= CHIP_R600) {
+                       value_ptr64 = (uint64_t*)((unsigned long)info->value);
+                       if (rdev->family >= CHIP_TAHITI) {
+                               value64 = si_get_gpu_clock(rdev);
+                       } else {
+                               value64 = r600_get_gpu_clock(rdev);
+                       }
+
+                       if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) {
+                               DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
+                               return -EFAULT;
+                       }
+                       return 0;
+               } else {
+                       DRM_DEBUG_KMS("timestamp is r6xx+ only!\n");
+                       return -EINVAL;
+               }
+       }
+
        value_ptr = (uint32_t *)((unsigned long)info->value);
-       if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value)))
+       if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) {
+               DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
                return -EFAULT;
+       }
 
        switch (info->request) {
        case RADEON_INFO_DEVICE_ID:
@@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                return -EINVAL;
        }
        if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) {
-               DRM_ERROR("copy_to_user\n");
+               DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
                return -EFAULT;
        }
        return 0;
index d5fd615897ec75ad13d8b1b1e7ddd1e85a1a859b..94b4a1c12893baab8ce72854661ed443fea1cfe0 100644 (file)
@@ -1025,9 +1025,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
 
 static void radeon_crtc_prepare(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct drm_crtc *crtci;
 
+       radeon_crtc->in_mode_set = true;
        /*
        * The hardware wedges sometimes if you reconfigure one CRTC
        * whilst another is running (see fdo bug #24611).
@@ -1038,6 +1040,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc)
 
 static void radeon_crtc_commit(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct drm_crtc *crtci;
 
@@ -1048,6 +1051,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc)
                if (crtci->enabled)
                        radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
        }
+       radeon_crtc->in_mode_set = false;
 }
 
 static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
index f380d59c5763425f0fc0bd79a8733d15bcfdca33..d56978949f34927169cf3db6a832361f2139cb4b 100644 (file)
@@ -275,6 +275,7 @@ struct radeon_crtc {
        u16 lut_r[256], lut_g[256], lut_b[256];
        bool enabled;
        bool can_tile;
+       bool in_mode_set;
        uint32_t crtc_offset;
        struct drm_gem_object *cursor_bo;
        uint64_t cursor_addr;
index 1f1a4c803c1dd267158dece882e8fdf5b2d6b871..9024e72228396068208d51e8dbf13fd8a8676307 100644 (file)
@@ -52,11 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo)
 
        list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) {
                /* remove from all vm address space */
-               mutex_lock(&bo_va->vm->mutex);
-               list_del(&bo_va->vm_list);
-               mutex_unlock(&bo_va->vm->mutex);
-               list_del(&bo_va->bo_list);
-               kfree(bo_va);
+               radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo);
        }
 }
 
@@ -136,6 +132,7 @@ int radeon_bo_create(struct radeon_device *rdev,
        acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size,
                                       sizeof(struct radeon_bo));
 
+retry:
        bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
        if (bo == NULL)
                return -ENOMEM;
@@ -149,8 +146,6 @@ int radeon_bo_create(struct radeon_device *rdev,
        bo->surface_reg = -1;
        INIT_LIST_HEAD(&bo->list);
        INIT_LIST_HEAD(&bo->va);
-
-retry:
        radeon_ttm_placement_from_domain(bo, domain);
        /* Kernel allocation are uninterruptible */
        down_read(&rdev->pm.mclk_lock);
index ec79b37504306f2709036bebe6949f7afc2a90cf..43c431a2686db86428059593dc3f853d87688d9c 100644 (file)
@@ -706,6 +706,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
        if (radeon_debugfs_ring_init(rdev, ring)) {
                DRM_ERROR("Failed to register debugfs file for rings !\n");
        }
+       radeon_ring_lockup_update(ring);
        return 0;
 }
 
index 5e659b034d9a379d362327541480b2eeef70bf61..20bfbda7b3f1bdcf0eff27332bf2b9812af696b4 100644 (file)
@@ -744,15 +744,6 @@ r600 0x9400
 0x00028C38 CB_CLRCMP_DST
 0x00028C3C CB_CLRCMP_MSK
 0x00028C34 CB_CLRCMP_SRC
-0x00028100 CB_COLOR0_MASK
-0x00028104 CB_COLOR1_MASK
-0x00028108 CB_COLOR2_MASK
-0x0002810C CB_COLOR3_MASK
-0x00028110 CB_COLOR4_MASK
-0x00028114 CB_COLOR5_MASK
-0x00028118 CB_COLOR6_MASK
-0x0002811C CB_COLOR7_MASK
-0x00028808 CB_COLOR_CONTROL
 0x0002842C CB_FOG_BLUE
 0x00028428 CB_FOG_GREEN
 0x00028424 CB_FOG_RED
index a12fbcc8ccb6834a9fba7b0d5cb08418538b52e9..aa8ef491ef3c17619ee9f1e64dd8262c5e74e103 100644 (file)
@@ -281,12 +281,8 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev)
 
 void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
 {
-       save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL);
-       save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL);
        save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL);
        save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL);
-       save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL);
-       save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL);
 
        /* Stop all video */
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
@@ -311,15 +307,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
        /* Unlock host access */
        WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
        mdelay(1);
-       /* Restore video state */
-       WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
-       WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
-       WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
-       WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
-       WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control);
-       WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control);
-       WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
-       WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
        WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
 }
 
index c053f8193771a1df17cfa092cabf15caaff880db..0139e227e3c7241712c5ed951f38b52f5120c564 100644 (file)
@@ -1639,11 +1639,19 @@ static void si_gpu_init(struct radeon_device *rdev)
                /* XXX what about 12? */
                rdev->config.si.tile_config |= (3 << 0);
                break;
-       }
-       if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT)
-               rdev->config.si.tile_config |= 1 << 4;
-       else
+       }       
+       switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
+       case 0: /* four banks */
                rdev->config.si.tile_config |= 0 << 4;
+               break;
+       case 1: /* eight banks */
+               rdev->config.si.tile_config |= 1 << 4;
+               break;
+       case 2: /* sixteen banks */
+       default:
+               rdev->config.si.tile_config |= 2 << 4;
+               break;
+       }
        rdev->config.si.tile_config |=
                ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
        rdev->config.si.tile_config |=
@@ -3960,3 +3968,22 @@ void si_fini(struct radeon_device *rdev)
        rdev->bios = NULL;
 }
 
+/**
+ * si_get_gpu_clock - return GPU clock counter snapshot
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Fetches a GPU clock counter snapshot (SI).
+ * Returns the 64 bit clock counter snapshot.
+ */
+uint64_t si_get_gpu_clock(struct radeon_device *rdev)
+{
+       uint64_t clock;
+
+       mutex_lock(&rdev->gpu_clock_mutex);
+       WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+       clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
+               ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+       mutex_unlock(&rdev->gpu_clock_mutex);
+       return clock;
+}
index 7869089e87619562663ca96c1c035c74b7dba710..ef4815c27b1c673e50ab9d675382586686b6495d 100644 (file)
 #define RLC_UCODE_ADDR                                    0xC32C
 #define RLC_UCODE_DATA                                    0xC330
 
+#define RLC_GPU_CLOCK_COUNT_LSB                           0xC338
+#define RLC_GPU_CLOCK_COUNT_MSB                           0xC33C
+#define RLC_CAPTURE_GPU_CLOCK_COUNT                       0xC340
 #define RLC_MC_CNTL                                       0xC344
 #define RLC_UCODE_CNTL                                    0xC348
 
index 0b5e096d39a6a7b590b55acd63ad30a21f241081..56e0bf31d425a6f90f7ad6cc9f2a9c4cbb993739 100644 (file)
@@ -1,6 +1,7 @@
 config DRM_UDL
        tristate "DisplayLink"
        depends on DRM && EXPERIMENTAL
+       depends on USB_ARCH_HAS_HCD
        select DRM_USB
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
index 7bd65bdd15a8092e955d959c08fd6dd04781d490..291ecc1455850400f6e596cde59dfac1acda83d4 100644 (file)
@@ -308,7 +308,7 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev,
        /* need to attach */
        attach = dma_buf_attach(dma_buf, dev->dev);
        if (IS_ERR(attach))
-               return ERR_PTR(PTR_ERR(attach));
+               return ERR_CAST(attach);
 
        sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
        if (IS_ERR(sg)) {
index f5dd89e891de0c165541178c2f0c6a7c74964303..9159d48d1dfd570521c43755596466788411beba 100644 (file)
@@ -354,8 +354,7 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,
 
 static void udl_crtc_disable(struct drm_crtc *crtc)
 {
-
-
+       udl_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void udl_crtc_destroy(struct drm_crtc *crtc)
index 6b0078ffa7638b163abb2a286e6b8d579daae4a5..c50724bd30f6e052e2f80e6f823379241944ff60 100644 (file)
@@ -1688,15 +1688,19 @@ int vmw_du_page_flip(struct drm_crtc *crtc,
        struct vmw_private *dev_priv = vmw_priv(crtc->dev);
        struct drm_framebuffer *old_fb = crtc->fb;
        struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
-       struct drm_file *file_priv = event->base.file_priv;
+       struct drm_file *file_priv ;
        struct vmw_fence_obj *fence = NULL;
        struct drm_clip_rect clips;
        int ret;
 
+       if (event == NULL)
+               return -EINVAL;
+
        /* require ScreenObject support for page flipping */
        if (!dev_priv->sou_priv)
                return -ENOSYS;
 
+       file_priv = event->base.file_priv;
        if (!vmw_kms_screen_object_flippable(dev_priv, crtc))
                return -EINVAL;
 
index 5b3c7d135dc91c407fc9b2bf19b2e3e912ccfed5..e25cf31faab2b10a027d3f3c860887214ba431d1 100644 (file)
@@ -70,27 +70,12 @@ static struct vgasr_priv vgasr_priv = {
        .clients = LIST_HEAD_INIT(vgasr_priv.clients),
 };
 
-int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
-{
-       mutex_lock(&vgasr_mutex);
-       if (vgasr_priv.handler) {
-               mutex_unlock(&vgasr_mutex);
-               return -EINVAL;
-       }
-
-       vgasr_priv.handler = handler;
-       mutex_unlock(&vgasr_mutex);
-       return 0;
-}
-EXPORT_SYMBOL(vga_switcheroo_register_handler);
-
-void vga_switcheroo_unregister_handler(void)
+static bool vga_switcheroo_ready(void)
 {
-       mutex_lock(&vgasr_mutex);
-       vgasr_priv.handler = NULL;
-       mutex_unlock(&vgasr_mutex);
+       /* we're ready if we get two clients + handler */
+       return !vgasr_priv.active &&
+              vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
 }
-EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
 
 static void vga_switcheroo_enable(void)
 {
@@ -98,7 +83,8 @@ static void vga_switcheroo_enable(void)
        struct vga_switcheroo_client *client;
 
        /* call the handler to init */
-       vgasr_priv.handler->init();
+       if (vgasr_priv.handler->init)
+               vgasr_priv.handler->init();
 
        list_for_each_entry(client, &vgasr_priv.clients, list) {
                if (client->id != -1)
@@ -113,6 +99,37 @@ static void vga_switcheroo_enable(void)
        vgasr_priv.active = true;
 }
 
+int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
+{
+       mutex_lock(&vgasr_mutex);
+       if (vgasr_priv.handler) {
+               mutex_unlock(&vgasr_mutex);
+               return -EINVAL;
+       }
+
+       vgasr_priv.handler = handler;
+       if (vga_switcheroo_ready()) {
+               printk(KERN_INFO "vga_switcheroo: enabled\n");
+               vga_switcheroo_enable();
+       }
+       mutex_unlock(&vgasr_mutex);
+       return 0;
+}
+EXPORT_SYMBOL(vga_switcheroo_register_handler);
+
+void vga_switcheroo_unregister_handler(void)
+{
+       mutex_lock(&vgasr_mutex);
+       vgasr_priv.handler = NULL;
+       if (vgasr_priv.active) {
+               pr_info("vga_switcheroo: disabled\n");
+               vga_switcheroo_debugfs_fini(&vgasr_priv);
+               vgasr_priv.active = false;
+       }
+       mutex_unlock(&vgasr_mutex);
+}
+EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
+
 static int register_client(struct pci_dev *pdev,
                           const struct vga_switcheroo_client_ops *ops,
                           int id, bool active)
@@ -134,9 +151,7 @@ static int register_client(struct pci_dev *pdev,
        if (client_is_vga(client))
                vgasr_priv.registered_clients++;
 
-       /* if we get two clients + handler */
-       if (!vgasr_priv.active &&
-           vgasr_priv.registered_clients == 2 && vgasr_priv.handler) {
+       if (vga_switcheroo_ready()) {
                printk(KERN_INFO "vga_switcheroo: enabled\n");
                vga_switcheroo_enable();
        }
index 60ea284407cea4d1f62db43a72b3e6cdbea47e31..8bf8a64e511543989c41624338304d0f11f0c59b 100644 (file)
@@ -1624,7 +1624,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
index 351d1f4593e7a8276da3ff7cdd9b286d4ea2b097..4ee5789487233dbe6bf03920fa29fb820d366b8d 100644 (file)
@@ -34,6 +34,12 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = {
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58")
                }
+       }, {
+               /* Old interface reads the same sensor for fan0 and fan1 */
+               .ident = "Asus M5A78L",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "M5A78L")
+               }
        },
        { }
 };
index faa16f80db9cf652bbc75aaa7e5fd0e73b788ca4..0fa356fe82ccc00fc6a70704627da99bb66fc49a 100644 (file)
@@ -196,7 +196,7 @@ struct tjmax {
        int tjmax;
 };
 
-static struct tjmax __cpuinitconst tjmax_table[] = {
+static const struct tjmax __cpuinitconst tjmax_table[] = {
        { "CPU D410", 100000 },
        { "CPU D425", 100000 },
        { "CPU D510", 100000 },
index ab4825205a9db30436404c64a9ee4d79acc2d535..5b1a6a666441f242ac63f21d9b9359464ced3f97 100644 (file)
@@ -1206,7 +1206,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr,
        int err = -ENODEV;
        u16 val;
 
-       static const __initdata char *names[] = {
+       static __initconst char *const names[] = {
                "W83627HF",
                "W83627THF",
                "W83697HF",
index aedb94f34bf748c1e82846f817264c1f73b2e602..dae3ddfe7619cf69899d974992ea0e7b43264b59 100644 (file)
@@ -405,6 +405,7 @@ static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
                        }
                }
        }
+       ret = num;
 abort:
        sret = diolan_i2c_stop(dev);
        if (sret < 0 && ret >= 0)
index 5e6f1eed4f83f233da76202c70d7564f773d3e1c..61b00edacb08179894c83b91d1f0cbe39a768b37 100644 (file)
@@ -350,10 +350,6 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
 
        i2c_clk = clk_get_rate(dev->clk);
 
-       /* fallback to std. mode if machine has not provided it */
-       if (dev->cfg.clk_freq == 0)
-               dev->cfg.clk_freq = 100000;
-
        /*
         * The spec says, in case of std. mode the divider is
         * 2 whereas it is 3 for fast and fastplus mode of
@@ -911,20 +907,32 @@ static const struct i2c_algorithm nmk_i2c_algo = {
        .functionality  = nmk_i2c_functionality
 };
 
+static struct nmk_i2c_controller u8500_i2c = {
+       /*
+        * Slave data setup time; 250ns, 100ns, and 10ns, which
+        * is 14, 6 and 2 respectively for a 48Mhz i2c clock.
+        */
+       .slsu           = 0xe,
+       .tft            = 1,      /* Tx FIFO threshold */
+       .rft            = 8,      /* Rx FIFO threshold */
+       .clk_freq       = 400000, /* fast mode operation */
+       .timeout        = 200,    /* Slave response timeout(ms) */
+       .sm             = I2C_FREQ_MODE_FAST,
+};
+
 static atomic_t adapter_id = ATOMIC_INIT(0);
 
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 {
        int ret = 0;
-       struct nmk_i2c_controller *pdata =
-                       adev->dev.platform_data;
+       struct nmk_i2c_controller *pdata = adev->dev.platform_data;
        struct nmk_i2c_dev      *dev;
        struct i2c_adapter *adap;
 
-       if (!pdata) {
-               dev_warn(&adev->dev, "no platform data\n");
-               return -ENODEV;
-       }
+       if (!pdata)
+               /* No i2c configuration found, using the default. */
+               pdata = &u8500_i2c;
+
        dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
        if (!dev) {
                dev_err(&adev->dev, "cannot allocate memory\n");
index 6849635b268a81fe8f85d380d2d80d16ba6ab2b1..5d19a49803c152089c85b5b51c4d83cbb7a91cda 100644 (file)
@@ -584,7 +584,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 
        r = pm_runtime_get_sync(dev->dev);
        if (IS_ERR_VALUE(r))
-               return r;
+               goto out;
 
        r = omap_i2c_wait_for_bb(dev);
        if (r < 0)
index 66eb53fac2022363c3cf90fa96d0ad6358234acc..f981ac4e6783104ee8586e2631fc58f788d49be6 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/i2c-tegra.h>
 #include <linux/of_i2c.h>
+#include <linux/of_device.h>
 #include <linux/module.h>
 
 #include <asm/unaligned.h>
@@ -113,12 +114,22 @@ enum msg_end_type {
        MSG_END_CONTINUE,
 };
 
+/**
+ * struct tegra_i2c_hw_feature : Different HW support on Tegra
+ * @has_continue_xfer_support: Continue transfer supports.
+ */
+
+struct tegra_i2c_hw_feature {
+       bool has_continue_xfer_support;
+};
+
 /**
  * struct tegra_i2c_dev        - per device i2c context
  * @dev: device reference for power management
+ * @hw: Tegra i2c hw feature.
  * @adapter: core i2c layer adapter information
- * @clk: clock reference for i2c controller
- * @i2c_clk: clock reference for i2c bus
+ * @div_clk: clock reference for div clock of i2c controller.
+ * @fast_clk: clock reference for fast clock of i2c controller.
  * @base: ioremapped registers cookie
  * @cont_id: i2c controller id, used for for packet header
  * @irq: irq number of transfer complete interrupt
@@ -133,9 +144,10 @@ enum msg_end_type {
  */
 struct tegra_i2c_dev {
        struct device *dev;
+       const struct tegra_i2c_hw_feature *hw;
        struct i2c_adapter adapter;
-       struct clk *clk;
-       struct clk *i2c_clk;
+       struct clk *div_clk;
+       struct clk *fast_clk;
        void __iomem *base;
        int cont_id;
        int irq;
@@ -351,16 +363,40 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
        dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
 }
 
+static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
+{
+       int ret;
+       ret = clk_prepare_enable(i2c_dev->fast_clk);
+       if (ret < 0) {
+               dev_err(i2c_dev->dev,
+                       "Enabling fast clk failed, err %d\n", ret);
+               return ret;
+       }
+       ret = clk_prepare_enable(i2c_dev->div_clk);
+       if (ret < 0) {
+               dev_err(i2c_dev->dev,
+                       "Enabling div clk failed, err %d\n", ret);
+               clk_disable_unprepare(i2c_dev->fast_clk);
+       }
+       return ret;
+}
+
+static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
+{
+       clk_disable_unprepare(i2c_dev->div_clk);
+       clk_disable_unprepare(i2c_dev->fast_clk);
+}
+
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
        u32 val;
        int err = 0;
 
-       clk_prepare_enable(i2c_dev->clk);
+       tegra_i2c_clock_enable(i2c_dev);
 
-       tegra_periph_reset_assert(i2c_dev->clk);
+       tegra_periph_reset_assert(i2c_dev->div_clk);
        udelay(2);
-       tegra_periph_reset_deassert(i2c_dev->clk);
+       tegra_periph_reset_deassert(i2c_dev->div_clk);
 
        if (i2c_dev->is_dvc)
                tegra_dvc_init(i2c_dev);
@@ -369,7 +405,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
                (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
        i2c_writel(i2c_dev, val, I2C_CNFG);
        i2c_writel(i2c_dev, 0, I2C_INT_MASK);
-       clk_set_rate(i2c_dev->clk, i2c_dev->bus_clk_rate * 8);
+       clk_set_rate(i2c_dev->div_clk, i2c_dev->bus_clk_rate * 8);
 
        if (!i2c_dev->is_dvc) {
                u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
@@ -387,7 +423,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
        if (tegra_i2c_flush_fifos(i2c_dev))
                err = -ETIMEDOUT;
 
-       clk_disable_unprepare(i2c_dev->clk);
+       tegra_i2c_clock_disable(i2c_dev);
 
        if (i2c_dev->irq_disabled) {
                i2c_dev->irq_disabled = 0;
@@ -563,7 +599,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
        if (i2c_dev->is_suspended)
                return -EBUSY;
 
-       clk_prepare_enable(i2c_dev->clk);
+       tegra_i2c_clock_enable(i2c_dev);
        for (i = 0; i < num; i++) {
                enum msg_end_type end_type = MSG_END_STOP;
                if (i < (num - 1)) {
@@ -576,14 +612,19 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
                if (ret)
                        break;
        }
-       clk_disable_unprepare(i2c_dev->clk);
+       tegra_i2c_clock_disable(i2c_dev);
        return ret ?: i;
 }
 
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
-       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-               I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
+       struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+       u32 ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+                               I2C_FUNC_PROTOCOL_MANGLING;
+
+       if (i2c_dev->hw->has_continue_xfer_support)
+               ret |= I2C_FUNC_NOSTART;
+       return ret;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
@@ -591,13 +632,32 @@ static const struct i2c_algorithm tegra_i2c_algo = {
        .functionality  = tegra_i2c_func,
 };
 
+static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
+       .has_continue_xfer_support = false,
+};
+
+static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
+       .has_continue_xfer_support = true,
+};
+
+#if defined(CONFIG_OF)
+/* Match table for of_platform binding */
+static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
+       { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
+       { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },
+       { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, },
+       {},
+};
+MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
+#endif
+
 static int __devinit tegra_i2c_probe(struct platform_device *pdev)
 {
        struct tegra_i2c_dev *i2c_dev;
        struct tegra_i2c_platform_data *pdata = pdev->dev.platform_data;
        struct resource *res;
-       struct clk *clk;
-       struct clk *i2c_clk;
+       struct clk *div_clk;
+       struct clk *fast_clk;
        const unsigned int *prop;
        void __iomem *base;
        int irq;
@@ -622,16 +682,16 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
        }
        irq = res->start;
 
-       clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(clk)) {
+       div_clk = devm_clk_get(&pdev->dev, "div-clk");
+       if (IS_ERR(div_clk)) {
                dev_err(&pdev->dev, "missing controller clock");
-               return PTR_ERR(clk);
+               return PTR_ERR(div_clk);
        }
 
-       i2c_clk = devm_clk_get(&pdev->dev, "i2c");
-       if (IS_ERR(i2c_clk)) {
+       fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
+       if (IS_ERR(fast_clk)) {
                dev_err(&pdev->dev, "missing bus clock");
-               return PTR_ERR(i2c_clk);
+               return PTR_ERR(fast_clk);
        }
 
        i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
@@ -641,8 +701,8 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
        }
 
        i2c_dev->base = base;
-       i2c_dev->clk = clk;
-       i2c_dev->i2c_clk = i2c_clk;
+       i2c_dev->div_clk = div_clk;
+       i2c_dev->fast_clk = fast_clk;
        i2c_dev->adapter.algo = &tegra_i2c_algo;
        i2c_dev->irq = irq;
        i2c_dev->cont_id = pdev->id;
@@ -659,11 +719,18 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
                        i2c_dev->bus_clk_rate = be32_to_cpup(prop);
        }
 
-       if (pdev->dev.of_node)
+       i2c_dev->hw = &tegra20_i2c_hw;
+
+       if (pdev->dev.of_node) {
+               const struct of_device_id *match;
+               match = of_match_device(of_match_ptr(tegra_i2c_of_match),
+                                               &pdev->dev);
+               i2c_dev->hw = match->data;
                i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
                                                "nvidia,tegra20-i2c-dvc");
-       else if (pdev->id == 3)
+       } else if (pdev->id == 3) {
                i2c_dev->is_dvc = 1;
+       }
        init_completion(&i2c_dev->msg_complete);
 
        platform_set_drvdata(pdev, i2c_dev);
@@ -681,8 +748,6 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
                return ret;
        }
 
-       clk_prepare_enable(i2c_dev->i2c_clk);
-
        i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
        i2c_dev->adapter.owner = THIS_MODULE;
        i2c_dev->adapter.class = I2C_CLASS_HWMON;
@@ -696,7 +761,6 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
        ret = i2c_add_numbered_adapter(&i2c_dev->adapter);
        if (ret) {
                dev_err(&pdev->dev, "Failed to add I2C adapter\n");
-               clk_disable_unprepare(i2c_dev->i2c_clk);
                return ret;
        }
 
@@ -712,7 +776,7 @@ static int __devexit tegra_i2c_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int tegra_i2c_suspend(struct device *dev)
 {
        struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
@@ -751,16 +815,6 @@ static SIMPLE_DEV_PM_OPS(tegra_i2c_pm, tegra_i2c_suspend, tegra_i2c_resume);
 #define TEGRA_I2C_PM   NULL
 #endif
 
-#if defined(CONFIG_OF)
-/* Match table for of_platform binding */
-static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
-       { .compatible = "nvidia,tegra20-i2c", },
-       { .compatible = "nvidia,tegra20-i2c-dvc", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
-#endif
-
 static struct platform_driver tegra_i2c_driver = {
        .probe   = tegra_i2c_probe,
        .remove  = __devexit_p(tegra_i2c_remove),
index 92406097efebcb5e0052fba38a0f59b5eb8c45eb..8d1e32d7cd9767db4e1c99db627681f03f233139 100644 (file)
@@ -4,7 +4,7 @@
 
 int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 {
-       ide_drive_t *drive = dev_get_drvdata(dev);
+       ide_drive_t *drive = to_ide_device(dev);
        ide_drive_t *pair = ide_get_pair_dev(drive);
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq;
@@ -40,7 +40,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 
 int generic_ide_resume(struct device *dev)
 {
-       ide_drive_t *drive = dev_get_drvdata(dev);
+       ide_drive_t *drive = to_ide_device(dev);
        ide_drive_t *pair = ide_get_pair_dev(drive);
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq;
index f559088869f6451fc349a808778266b4f77557a9..e8726177d103082021a6549d4ce32d161e2bab2a 100644 (file)
@@ -606,8 +606,9 @@ static int __init intel_idle_init(void)
        intel_idle_cpuidle_driver_init();
        retval = cpuidle_register_driver(&intel_idle_driver);
        if (retval) {
+               struct cpuidle_driver *drv = cpuidle_get_driver();
                printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
-                       cpuidle_get_driver()->name);
+                       drv ? drv->name : "none");
                return retval;
        }
 
index 59fbb3ae40e7f4628b3bc9d545a27c86e379bdbc..e35bb8f6fe7597e8823527772b119cd3b579377d 100644 (file)
@@ -129,7 +129,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
 {
        struct adf4350_platform_data *pdata = st->pdata;
        u64 tmp;
-       u32 div_gcd, prescaler;
+       u32 div_gcd, prescaler, chspc;
        u16 mdiv, r_cnt = 0;
        u8 band_sel_div;
 
@@ -158,14 +158,20 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
        if (pdata->ref_div_factor)
                r_cnt = pdata->ref_div_factor - 1;
 
-       do  {
-               r_cnt = adf4350_tune_r_cnt(st, r_cnt);
+       chspc = st->chspc;
 
-               st->r1_mod = st->fpfd / st->chspc;
-               while (st->r1_mod > ADF4350_MAX_MODULUS) {
-                       r_cnt = adf4350_tune_r_cnt(st, r_cnt);
-                       st->r1_mod = st->fpfd / st->chspc;
-               }
+       do  {
+               do {
+                       do {
+                               r_cnt = adf4350_tune_r_cnt(st, r_cnt);
+                               st->r1_mod = st->fpfd / chspc;
+                               if (r_cnt > ADF4350_MAX_R_CNT) {
+                                       /* try higher spacing values */
+                                       chspc++;
+                                       r_cnt = 0;
+                               }
+                       } while ((st->r1_mod > ADF4350_MAX_MODULUS) && r_cnt);
+               } while (r_cnt == 0);
 
                tmp = freq * (u64)st->r1_mod + (st->fpfd > 1);
                do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */
@@ -194,7 +200,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
        st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) |
                                 ADF4350_REG0_FRACT(st->r0_fract);
 
-       st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(0) |
+       st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(1) |
                                 ADF4350_REG1_MOD(st->r1_mod) |
                                 prescaler;
 
index 1cbb449b319a8e9399af3b427342fb1702b1b173..9a99f43094f0824dde61203647462a8872faab83 100644 (file)
@@ -271,9 +271,10 @@ static int adjd_s311_update_scan_mode(struct iio_dev *indio_dev,
        const unsigned long *scan_mask)
 {
        struct adjd_s311_data *data = iio_priv(indio_dev);
-       data->buffer = krealloc(data->buffer, indio_dev->scan_bytes,
-                               GFP_KERNEL);
-       if (!data->buffer)
+
+       kfree(data->buffer);
+       data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+       if (data->buffer == NULL)
                return -ENOMEM;
 
        return 0;
index c3e7bac1312318470f29c805ca2ccdcfb6790402..e45712a921ce600cee7c10aa2d8a4dcbc46fccba 100644 (file)
@@ -404,7 +404,7 @@ out:
        return ret;
 }
 
-static int show_thresh_either_en(struct device *dev,
+static ssize_t show_thresh_either_en(struct device *dev,
                                        struct device_attribute *attr,
                                        char *buf)
 {
@@ -424,7 +424,7 @@ static int show_thresh_either_en(struct device *dev,
        return scnprintf(buf, PAGE_SIZE, "%u\n", enable);
 }
 
-static int store_thresh_either_en(struct device *dev,
+static ssize_t store_thresh_either_en(struct device *dev,
                                        struct device_attribute *attr,
                                        const char *buf, size_t len)
 {
index 6bf8504228957eb8341342c16cfa9b88a234c8bd..055ed59838dca128eef4986a9b3186a1f0588b84 100644 (file)
@@ -267,6 +267,7 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
        if (!uevent)
                return event->event == RDMA_CM_EVENT_CONNECT_REQUEST;
 
+       mutex_lock(&ctx->file->mut);
        uevent->cm_id = cm_id;
        ucma_set_event_context(ctx, event, uevent);
        uevent->resp.event = event->event;
@@ -277,7 +278,6 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
                ucma_copy_conn_event(&uevent->resp.param.conn,
                                     &event->param.conn);
 
-       mutex_lock(&ctx->file->mut);
        if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) {
                if (!ctx->backlog) {
                        ret = -ENOMEM;
index 8c81992fa6db26275615d8f7f9e3998dd4223b7a..e4a73158fc7fc0392d9308146f2c695936b80532 100644 (file)
@@ -439,7 +439,7 @@ static int c2_rnic_close(struct c2_dev *c2dev)
 
 /*
  * Called by c2_probe to initialize the RNIC. This principally
- * involves initalizing the various limits and resouce pools that
+ * involves initializing the various limits and resource pools that
  * comprise the RNIC instance.
  */
 int __devinit c2_rnic_init(struct c2_dev *c2dev)
index 77b6b182778ad642b23bb9dc6a8f943cf83a6a10..aaf88ef9409cddfabef4fb90c88347e27887d464 100644 (file)
@@ -1680,7 +1680,7 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
  * T3A does 3 things when a TERM is received:
  * 1) send up a CPL_RDMA_TERMINATE message with the TERM packet
  * 2) generate an async event on the QP with the TERMINATE opcode
- * 3) post a TERMINATE opcde cqe into the associated CQ.
+ * 3) post a TERMINATE opcode cqe into the associated CQ.
  *
  * For (1), we save the message in the qp for later consumer consumption.
  * For (2), we move the QP into TERMINATE, post a QP event and disconnect.
index c27141fef1ab2f6dca170bb07aecd11ecaa3d48b..9c2ae7efd00f4c03db74d67a4b5e8d84b0a87e28 100644 (file)
@@ -125,6 +125,7 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl)
 {
        struct ib_ah *new_ah;
        struct ib_ah_attr ah_attr;
+       unsigned long flags;
 
        if (!dev->send_agent[port_num - 1][0])
                return;
@@ -139,11 +140,11 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl)
        if (IS_ERR(new_ah))
                return;
 
-       spin_lock(&dev->sm_lock);
+       spin_lock_irqsave(&dev->sm_lock, flags);
        if (dev->sm_ah[port_num - 1])
                ib_destroy_ah(dev->sm_ah[port_num - 1]);
        dev->sm_ah[port_num - 1] = new_ah;
-       spin_unlock(&dev->sm_lock);
+       spin_unlock_irqrestore(&dev->sm_lock, flags);
 }
 
 /*
@@ -197,13 +198,15 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
 static void node_desc_override(struct ib_device *dev,
                               struct ib_mad *mad)
 {
+       unsigned long flags;
+
        if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
             mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
            mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP &&
            mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) {
-               spin_lock(&to_mdev(dev)->sm_lock);
+               spin_lock_irqsave(&to_mdev(dev)->sm_lock, flags);
                memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64);
-               spin_unlock(&to_mdev(dev)->sm_lock);
+               spin_unlock_irqrestore(&to_mdev(dev)->sm_lock, flags);
        }
 }
 
@@ -213,6 +216,7 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma
        struct ib_mad_send_buf *send_buf;
        struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn];
        int ret;
+       unsigned long flags;
 
        if (agent) {
                send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR,
@@ -225,13 +229,13 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma
                 * wrong following the IB spec strictly, but we know
                 * it's OK for our devices).
                 */
-               spin_lock(&dev->sm_lock);
+               spin_lock_irqsave(&dev->sm_lock, flags);
                memcpy(send_buf->mad, mad, sizeof *mad);
                if ((send_buf->ah = dev->sm_ah[port_num - 1]))
                        ret = ib_post_send_mad(send_buf, NULL);
                else
                        ret = -EINVAL;
-               spin_unlock(&dev->sm_lock);
+               spin_unlock_irqrestore(&dev->sm_lock, flags);
 
                if (ret)
                        ib_free_send_mad(send_buf);
index fe2088cfa6eef699f0222b710aeb3de930c1c139..cc05579ebce7fd6b5f5fc9c86b2a1452db0101a7 100644 (file)
@@ -423,6 +423,7 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask,
                                 struct ib_device_modify *props)
 {
        struct mlx4_cmd_mailbox *mailbox;
+       unsigned long flags;
 
        if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
                return -EOPNOTSUPP;
@@ -430,9 +431,9 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask,
        if (!(mask & IB_DEVICE_MODIFY_NODE_DESC))
                return 0;
 
-       spin_lock(&to_mdev(ibdev)->sm_lock);
+       spin_lock_irqsave(&to_mdev(ibdev)->sm_lock, flags);
        memcpy(ibdev->node_desc, props->node_desc, 64);
-       spin_unlock(&to_mdev(ibdev)->sm_lock);
+       spin_unlock_irqrestore(&to_mdev(ibdev)->sm_lock, flags);
 
        /*
         * If possible, pass node desc to FW, so it can generate
index a6d8ea060ea896ad4f7c7d9a8639a8be8f67fb4e..f585eddef4b7d5c7921575cebaa508eefde4f934 100644 (file)
@@ -1407,6 +1407,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
        struct mlx4_wqe_mlx_seg *mlx = wqe;
        struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx;
        struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah);
+       struct net_device *ndev;
        union ib_gid sgid;
        u16 pkey;
        int send_size;
@@ -1483,7 +1484,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
 
                memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6);
                /* FIXME: cache smac value? */
-               smac = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]->dev_addr;
+               ndev = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1];
+               if (!ndev)
+                       return -ENODEV;
+               smac = ndev->dev_addr;
                memcpy(sqp->ud_header.eth.smac_h, smac, 6);
                if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6))
                        mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK);
index 5a044526e4f4c379bf52e05f9b15c00953453df7..c4e0131f1b578fec8fa62d029ff380b3d976b13b 100644 (file)
@@ -161,7 +161,7 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev)
        ocrdma_get_guid(dev, &sgid->raw[8]);
 }
 
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#if IS_ENABLED(CONFIG_VLAN_8021Q)
 static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
 {
        struct net_device *netdev, *tmp;
@@ -202,14 +202,13 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
        return 0;
 }
 
-#if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_VLAN_8021Q)
+#if IS_ENABLED(CONFIG_IPV6)
 
 static int ocrdma_inet6addr_event(struct notifier_block *notifier,
                                  unsigned long event, void *ptr)
 {
        struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
-       struct net_device *event_netdev = ifa->idev->dev;
-       struct net_device *netdev = NULL;
+       struct net_device *netdev = ifa->idev->dev;
        struct ib_event gid_event;
        struct ocrdma_dev *dev;
        bool found = false;
@@ -217,11 +216,12 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
        bool is_vlan = false;
        u16 vid = 0;
 
-       netdev = vlan_dev_real_dev(event_netdev);
-       if (netdev != event_netdev) {
-               is_vlan = true;
-               vid = vlan_dev_vlan_id(event_netdev);
+       is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN;
+       if (is_vlan) {
+               vid = vlan_dev_vlan_id(netdev);
+               netdev = vlan_dev_real_dev(netdev);
        }
+
        rcu_read_lock();
        list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) {
                if (dev->nic_info.netdev == netdev) {
index 0d7280af99bc81084d1977d5bfe8480450c85c77..3f6b21e9dc110513c0522b099adcfa0f131ef6b4 100644 (file)
@@ -6346,8 +6346,10 @@ static int qib_init_7322_variables(struct qib_devdata *dd)
                        dd->piobcnt4k * dd->align4k;
                dd->piovl15base = ioremap_nocache(vl15off,
                                                  NUM_VL15_BUFS * dd->align4k);
-               if (!dd->piovl15base)
+               if (!dd->piovl15base) {
+                       ret = -ENOMEM;
                        goto bail;
+               }
        }
        qib_7322_set_baseaddrs(dd); /* set chip access pointers now */
 
index a322d5171a2c793d0ec3cb5e08632a0264fd2ab5..50a8a0d4fe676f5467c677d66a4985170900059d 100644 (file)
@@ -372,7 +372,7 @@ static void qib_sd_trimdone_monitor(struct qib_devdata *dd,
                /* Read CTRL reg for each channel to check TRIMDONE */
                if (baduns & (1 << chn)) {
                        qib_dev_err(dd,
-                               "Reseting TRIMDONE on chn %d (%s)\n",
+                               "Resetting TRIMDONE on chn %d (%s)\n",
                                chn, where);
                        ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES,
                                IB_CTRL2(chn), 0x10, 0x10);
index 95ecf4eadf5f75949f6a7e14acfa01a50fbdc0cd..24683fda8e21cdbaca2973cc69454013a2bbb995 100644 (file)
@@ -1271,12 +1271,15 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path
 void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
 {
        struct ipoib_dev_priv *priv = netdev_priv(tx->dev);
+       unsigned long flags;
        if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) {
+               spin_lock_irqsave(&priv->lock, flags);
                list_move(&tx->list, &priv->cm.reap_list);
                queue_work(ipoib_workqueue, &priv->cm.reap_task);
                ipoib_dbg(priv, "Reap connection for gid %pI6\n",
                          tx->neigh->daddr + 4);
                tx->neigh = NULL;
+               spin_unlock_irqrestore(&priv->lock, flags);
        }
 }
 
index 97920b77a5d0abe2f378ed060aa8243a2c5c33e7..3e2085a3ee474fc0111c7034ca013bfda7d63d7e 100644 (file)
@@ -1052,7 +1052,7 @@ void ipoib_neigh_free(struct ipoib_neigh *neigh)
        for (n = rcu_dereference_protected(*np,
                                            lockdep_is_held(&ntbl->rwlock));
             n != NULL;
-            n = rcu_dereference_protected(neigh->hnext,
+            n = rcu_dereference_protected(*np,
                                        lockdep_is_held(&ntbl->rwlock))) {
                if (n == neigh) {
                        /* found */
index bcbf22ee0aa77d3b99ae3fcceabd3ebce1302ee9..1b5b0c7300549cefee683b3d5745b39a446b5bca 100644 (file)
@@ -586,24 +586,62 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
                        scmnd->sc_data_direction);
 }
 
-static void srp_remove_req(struct srp_target_port *target,
-                          struct srp_request *req, s32 req_lim_delta)
+/**
+ * srp_claim_req - Take ownership of the scmnd associated with a request.
+ * @target: SRP target port.
+ * @req: SRP request.
+ * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take
+ *         ownership of @req->scmnd if it equals @scmnd.
+ *
+ * Return value:
+ * Either NULL or a pointer to the SCSI command the caller became owner of.
+ */
+static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target,
+                                      struct srp_request *req,
+                                      struct scsi_cmnd *scmnd)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&target->lock, flags);
+       if (!scmnd) {
+               scmnd = req->scmnd;
+               req->scmnd = NULL;
+       } else if (req->scmnd == scmnd) {
+               req->scmnd = NULL;
+       } else {
+               scmnd = NULL;
+       }
+       spin_unlock_irqrestore(&target->lock, flags);
+
+       return scmnd;
+}
+
+/**
+ * srp_free_req() - Unmap data and add request to the free request list.
+ */
+static void srp_free_req(struct srp_target_port *target,
+                        struct srp_request *req, struct scsi_cmnd *scmnd,
+                        s32 req_lim_delta)
 {
        unsigned long flags;
 
-       srp_unmap_data(req->scmnd, target, req);
+       srp_unmap_data(scmnd, target, req);
+
        spin_lock_irqsave(&target->lock, flags);
        target->req_lim += req_lim_delta;
-       req->scmnd = NULL;
        list_add_tail(&req->list, &target->free_reqs);
        spin_unlock_irqrestore(&target->lock, flags);
 }
 
 static void srp_reset_req(struct srp_target_port *target, struct srp_request *req)
 {
-       req->scmnd->result = DID_RESET << 16;
-       req->scmnd->scsi_done(req->scmnd);
-       srp_remove_req(target, req, 0);
+       struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL);
+
+       if (scmnd) {
+               scmnd->result = DID_RESET << 16;
+               scmnd->scsi_done(scmnd);
+               srp_free_req(target, req, scmnd, 0);
+       }
 }
 
 static int srp_reconnect_target(struct srp_target_port *target)
@@ -1073,11 +1111,18 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                complete(&target->tsk_mgmt_done);
        } else {
                req = &target->req_ring[rsp->tag];
-               scmnd = req->scmnd;
-               if (!scmnd)
+               scmnd = srp_claim_req(target, req, NULL);
+               if (!scmnd) {
                        shost_printk(KERN_ERR, target->scsi_host,
                                     "Null scmnd for RSP w/tag %016llx\n",
                                     (unsigned long long) rsp->tag);
+
+                       spin_lock_irqsave(&target->lock, flags);
+                       target->req_lim += be32_to_cpu(rsp->req_lim_delta);
+                       spin_unlock_irqrestore(&target->lock, flags);
+
+                       return;
+               }
                scmnd->result = rsp->status;
 
                if (rsp->flags & SRP_RSP_FLAG_SNSVALID) {
@@ -1092,7 +1137,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
                        scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt));
 
-               srp_remove_req(target, req, be32_to_cpu(rsp->req_lim_delta));
+               srp_free_req(target, req, scmnd,
+                            be32_to_cpu(rsp->req_lim_delta));
+
                scmnd->host_scribble = NULL;
                scmnd->scsi_done(scmnd);
        }
@@ -1631,25 +1678,17 @@ static int srp_abort(struct scsi_cmnd *scmnd)
 {
        struct srp_target_port *target = host_to_target(scmnd->device->host);
        struct srp_request *req = (struct srp_request *) scmnd->host_scribble;
-       int ret = SUCCESS;
 
        shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
 
-       if (!req || target->qp_in_error)
+       if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd))
                return FAILED;
-       if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
-                             SRP_TSK_ABORT_TASK))
-               return FAILED;
-
-       if (req->scmnd) {
-               if (!target->tsk_mgmt_status) {
-                       srp_remove_req(target, req, 0);
-                       scmnd->result = DID_ABORT << 16;
-               } else
-                       ret = FAILED;
-       }
+       srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
+                         SRP_TSK_ABORT_TASK);
+       srp_free_req(target, req, scmnd, 0);
+       scmnd->result = DID_ABORT << 16;
 
-       return ret;
+       return SUCCESS;
 }
 
 static int srp_reset_device(struct scsi_cmnd *scmnd)
index 7a0ce8d42887e225e81d20702892d8ed0d056f39..9e1449f8c6a26ea62349352de3f8178db2faa6fe 100644 (file)
@@ -1469,7 +1469,7 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
  *
  * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping
  * the data that has been transferred via IB RDMA had to be postponed until the
- * check_stop_free() callback.  None of this is nessecary anymore and needs to
+ * check_stop_free() callback.  None of this is necessary anymore and needs to
  * be cleaned up.
  */
 static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch,
index 503c7096ed36263aac57c0165e846cb2d46fae49..908407efc672be69bcc0a13c5603b38b45d50440 100644 (file)
@@ -48,7 +48,7 @@ struct eeti_ts_priv {
        struct input_dev *input;
        struct work_struct work;
        struct mutex mutex;
-       int irq, irq_active_high;
+       int irq_gpio, irq, irq_active_high;
 };
 
 #define EETI_TS_BITDEPTH       (11)
@@ -62,7 +62,7 @@ struct eeti_ts_priv {
 
 static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv)
 {
-       return gpio_get_value(irq_to_gpio(priv->irq)) == priv->irq_active_high;
+       return gpio_get_value(priv->irq_gpio) == priv->irq_active_high;
 }
 
 static void eeti_ts_read(struct work_struct *work)
@@ -157,7 +157,7 @@ static void eeti_ts_close(struct input_dev *dev)
 static int __devinit eeti_ts_probe(struct i2c_client *client,
                                   const struct i2c_device_id *idp)
 {
-       struct eeti_ts_platform_data *pdata;
+       struct eeti_ts_platform_data *pdata = client->dev.platform_data;
        struct eeti_ts_priv *priv;
        struct input_dev *input;
        unsigned int irq_flags;
@@ -199,9 +199,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
 
        priv->client = client;
        priv->input = input;
-       priv->irq = client->irq;
+       priv->irq_gpio = pdata->irq_gpio;
+       priv->irq = gpio_to_irq(pdata->irq_gpio);
 
-       pdata = client->dev.platform_data;
+       err = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name);
+       if (err < 0)
+               goto err1;
 
        if (pdata)
                priv->irq_active_high = pdata->irq_active_high;
@@ -215,13 +218,13 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
 
        err = input_register_device(input);
        if (err)
-               goto err1;
+               goto err2;
 
        err = request_irq(priv->irq, eeti_ts_isr, irq_flags,
                          client->name, priv);
        if (err) {
                dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
-               goto err2;
+               goto err3;
        }
 
        /*
@@ -233,9 +236,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
        device_init_wakeup(&client->dev, 0);
        return 0;
 
-err2:
+err3:
        input_unregister_device(input);
        input = NULL; /* so we dont try to free it below */
+err2:
+       gpio_free(pdata->irq_gpio);
 err1:
        input_free_device(input);
        kfree(priv);
index 6d1cbdfc9b2a1af4a583460e8c4a5e5c80aabdfc..b64502dfa9f4567ca028bcb9b7913d4b38696019 100644 (file)
@@ -296,8 +296,13 @@ static int iommu_init_device(struct device *dev)
        } else
                dma_pdev = pci_dev_get(pdev);
 
+       /* Account for quirked devices */
        swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
 
+       /*
+        * If it's a multifunction device that does not support our
+        * required ACS flags, add to the same group as function 0.
+        */
        if (dma_pdev->multifunction &&
            !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
                swap_pci_ref(&dma_pdev,
@@ -305,14 +310,28 @@ static int iommu_init_device(struct device *dev)
                                          PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
                                          0)));
 
+       /*
+        * Devices on the root bus go through the iommu.  If that's not us,
+        * find the next upstream device and test ACS up to the root bus.
+        * Finding the next device may require skipping virtual buses.
+        */
        while (!pci_is_root_bus(dma_pdev->bus)) {
-               if (pci_acs_path_enabled(dma_pdev->bus->self,
-                                        NULL, REQ_ACS_FLAGS))
+               struct pci_bus *bus = dma_pdev->bus;
+
+               while (!bus->self) {
+                       if (!pci_is_root_bus(bus))
+                               bus = bus->parent;
+                       else
+                               goto root_bus;
+               }
+
+               if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
                        break;
 
-               swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self));
+               swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
        }
 
+root_bus:
        group = iommu_group_get(&dma_pdev->dev);
        pci_dev_put(dma_pdev);
        if (!group) {
index 500e7f15f5c266043d5d2bdc27a04f489595be79..18a89b760aaa3d78940021f0637e7f090116bb23 100644 (file)
@@ -1111,7 +1111,7 @@ static void print_iommu_info(void)
 
                if (iommu->cap & (1 << IOMMU_CAP_EFR)) {
                        pr_info("AMD-Vi:  Extended features: ");
-                       for (i = 0; ARRAY_SIZE(feat_str); ++i) {
+                       for (i = 0; i < ARRAY_SIZE(feat_str); ++i) {
                                if (iommu_feature(iommu, (1ULL << i)))
                                        pr_cont(" %s", feat_str[i]);
                        }
@@ -1131,9 +1131,6 @@ static int __init amd_iommu_init_pci(void)
                        break;
        }
 
-       /* Make sure ACS will be enabled */
-       pci_request_acs();
-
        ret = amd_iommu_init_devices();
 
        print_iommu_info();
@@ -1652,6 +1649,9 @@ static bool detect_ivrs(void)
 
        early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
 
+       /* Make sure ACS will be enabled during PCI probe */
+       pci_request_acs();
+
        return true;
 }
 
index 45350ff5e93c9cbe58c1f73c49e932c5f57eb376..80bad32aa46394443ad5a0aaa4a241c4e0e4b2c0 100644 (file)
@@ -732,9 +732,9 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain)
        spin_lock_init(&priv->pgtablelock);
        INIT_LIST_HEAD(&priv->clients);
 
-       dom->geometry.aperture_start = 0;
-       dom->geometry.aperture_end   = ~0UL;
-       dom->geometry.force_aperture = true;
+       domain->geometry.aperture_start = 0;
+       domain->geometry.aperture_end   = ~0UL;
+       domain->geometry.force_aperture = true;
 
        domain->priv = priv;
        return 0;
index 7469b5346643595fe1788b04d76135ed30075cfd..2297ec193eb4b645812c85519c335361e935f296 100644 (file)
@@ -2008,6 +2008,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
        if (!drhd) {
                printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
                        pci_name(pdev));
+               free_domain_mem(domain);
                return NULL;
        }
        iommu = drhd->iommu;
@@ -4124,8 +4125,13 @@ static int intel_iommu_add_device(struct device *dev)
        } else
                dma_pdev = pci_dev_get(pdev);
 
+       /* Account for quirked devices */
        swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
 
+       /*
+        * If it's a multifunction device that does not support our
+        * required ACS flags, add to the same group as function 0.
+        */
        if (dma_pdev->multifunction &&
            !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
                swap_pci_ref(&dma_pdev,
@@ -4133,14 +4139,28 @@ static int intel_iommu_add_device(struct device *dev)
                                          PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
                                          0)));
 
+       /*
+        * Devices on the root bus go through the iommu.  If that's not us,
+        * find the next upstream device and test ACS up to the root bus.
+        * Finding the next device may require skipping virtual buses.
+        */
        while (!pci_is_root_bus(dma_pdev->bus)) {
-               if (pci_acs_path_enabled(dma_pdev->bus->self,
-                                        NULL, REQ_ACS_FLAGS))
+               struct pci_bus *bus = dma_pdev->bus;
+
+               while (!bus->self) {
+                       if (!pci_is_root_bus(bus))
+                               bus = bus->parent;
+                       else
+                               goto root_bus;
+               }
+
+               if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
                        break;
 
-               swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self));
+               swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
        }
 
+root_bus:
        group = iommu_group_get(&dma_pdev->dev);
        pci_dev_put(dma_pdev);
        if (!group) {
index e0b18f3ae9a862a22a8bc2ebe2eccc224c456252..af8904de1d44e63ca35be4a58320889b2bab7a8b 100644 (file)
@@ -736,6 +736,7 @@ int __init parse_ioapics_under_ir(void)
 {
        struct dmar_drhd_unit *drhd;
        int ir_supported = 0;
+       int ioapic_idx;
 
        for_each_drhd_unit(drhd) {
                struct intel_iommu *iommu = drhd->iommu;
@@ -748,13 +749,20 @@ int __init parse_ioapics_under_ir(void)
                }
        }
 
-       if (ir_supported && ir_ioapic_num != nr_ioapics) {
-               printk(KERN_WARNING
-                      "Not all IO-APIC's listed under remapping hardware\n");
-               return -1;
+       if (!ir_supported)
+               return 0;
+
+       for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) {
+               int ioapic_id = mpc_ioapic_id(ioapic_idx);
+               if (!map_ioapic_to_ir(ioapic_id)) {
+                       pr_err(FW_BUG "ioapic %d has no mapping iommu, "
+                              "interrupt remapping will be disabled\n",
+                              ioapic_id);
+                       return -1;
+               }
        }
 
-       return ir_supported;
+       return 1;
 }
 
 int __init ir_dev_scope_init(void)
index 4ba325ab626249c2aa2aee1271a6d0c68ec20d9a..2a4bb36bc6888a9c91aee304df7c19bad1e42f83 100644 (file)
@@ -799,14 +799,14 @@ static void smmu_iommu_detach_dev(struct iommu_domain *domain,
                        goto out;
                }
        }
-       dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev));
+       dev_err(smmu->dev, "Couldn't find %s\n", dev_name(dev));
 out:
        spin_unlock(&as->client_lock);
 }
 
 static int smmu_iommu_domain_init(struct iommu_domain *domain)
 {
-       int i, err = -ENODEV;
+       int i, err = -EAGAIN;
        unsigned long flags;
        struct smmu_as *as;
        struct smmu_device *smmu = smmu_handle;
@@ -814,11 +814,14 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain)
        /* Look for a free AS with lock held */
        for  (i = 0; i < smmu->num_as; i++) {
                as = &smmu->as[i];
-               if (!as->pdir_page) {
-                       err = alloc_pdir(as);
-                       if (!err)
-                               goto found;
-               }
+
+               if (as->pdir_page)
+                       continue;
+
+               err = alloc_pdir(as);
+               if (!err)
+                       goto found;
+
                if (err != -EAGAIN)
                        break;
        }
index 5405ec644db3ee910df3765499300f11f7d1832c..baf2686aa8eb0cb027044e815dafa8b2aa6afae4 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/sched.h>
 #include "isdnloop.h"
 
-static char *revision = "$Revision: 1.11.6.7 $";
 static char *isdnloop_id = "loop0";
 
 MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card");
@@ -1494,17 +1493,6 @@ isdnloop_addcard(char *id1)
 static int __init
 isdnloop_init(void)
 {
-       char *p;
-       char rev[10];
-
-       if ((p = strchr(revision, ':'))) {
-               strcpy(rev, p + 1);
-               p = strchr(rev, '$');
-               *p = 0;
-       } else
-               strcpy(rev, " ??? ");
-       printk(KERN_NOTICE "isdnloop-ISDN-driver Rev%s\n", rev);
-
        if (isdnloop_id)
                return (isdnloop_addcard(isdnloop_id));
 
index 0dc8abca14079223c868effc3258e4b5f36590fe..949cabb88f1c113c9606d26ff72627f6cf9db108 100644 (file)
@@ -2222,7 +2222,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
        InitWin(l2);
        l2->l2m.fsm = &l2fsm;
        if (test_bit(FLG_LAPB, &l2->flag) ||
-           test_bit(FLG_PTP, &l2->flag) ||
+           test_bit(FLG_FIXED_TEI, &l2->flag) ||
            test_bit(FLG_LAPD_NET, &l2->flag))
                l2->l2m.state = ST_L2_4;
        else
index 6157cbbf41131cb1f2fdf7b4f02e96f48771a8b1..363975b3c925989badc13117d7a5309a5860a1b8 100644 (file)
@@ -224,7 +224,7 @@ void led_trigger_event(struct led_trigger *trig,
                struct led_classdev *led_cdev;
 
                led_cdev = list_entry(entry, struct led_classdev, trig_list);
-               led_set_brightness(led_cdev, brightness);
+               __led_set_brightness(led_cdev, brightness);
        }
        read_unlock(&trig->leddev_list_lock);
 }
index 53bd136f1ef070a1e045b97f8dbc6b55e30c0ca6..0ade6ebfc914dba6e6809b46a428fc9ee219b83e 100644 (file)
@@ -63,7 +63,7 @@ static int lp8788_led_init_device(struct lp8788_led *led,
        /* scale configuration */
        addr = LP8788_ISINK_CTRL;
        mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
-       val = cfg->scale << cfg->num;
+       val = cfg->scale << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
        ret = lp8788_update_bits(led->lp, addr, mask, val);
        if (ret)
                return ret;
index 9ee12c28059a0a8e60bc879dd083db2b90ae2fdc..771ea067e680f8b64e9cd54672007a5d66091d9c 100644 (file)
@@ -247,7 +247,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev)
 
        if (!cfg) {
                dev_err(&pdev->dev, "missing platform data\n");
-               goto err0;
+               return -ENODEV;
        }
 
        p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
index fcd098794d37d16c7b48b12c54b5ba6f5e6ba60e..3f6203a4c7ea0dd730b80a6b441b99e8a4da3216 100644 (file)
@@ -1108,8 +1108,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
                        ret = 0;
        }
        rdev->sectors = rdev->sb_start;
-       /* Limit to 4TB as metadata cannot record more than that */
-       if (rdev->sectors >= (2ULL << 32))
+       /* Limit to 4TB as metadata cannot record more than that.
+        * (not needed for Linear and RAID0 as metadata doesn't
+        * record this size)
+        */
+       if (rdev->sectors >= (2ULL << 32) && sb->level >= 1)
                rdev->sectors = (2ULL << 32) - 2;
 
        if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1)
@@ -1400,7 +1403,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)
        /* Limit to 4TB as metadata cannot record more than that.
         * 4TB == 2^32 KB, or 2*2^32 sectors.
         */
-       if (num_sectors >= (2ULL << 32))
+       if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1)
                num_sectors = (2ULL << 32) - 2;
        md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
                       rdev->sb_page);
index de5ed6fd8806c3c3db39bbd894fabb04734b4523..1c2eb38f3c51a6dcc93148ca34b1a6a1de7aa465 100644 (file)
@@ -659,7 +659,11 @@ static int raid10_mergeable_bvec(struct request_queue *q,
                max = biovec->bv_len;
 
        if (mddev->merge_check_needed) {
-               struct r10bio r10_bio;
+               struct {
+                       struct r10bio r10_bio;
+                       struct r10dev devs[conf->copies];
+               } on_stack;
+               struct r10bio *r10_bio = &on_stack.r10_bio;
                int s;
                if (conf->reshape_progress != MaxSector) {
                        /* Cannot give any guidance during reshape */
@@ -667,18 +671,18 @@ static int raid10_mergeable_bvec(struct request_queue *q,
                                return biovec->bv_len;
                        return 0;
                }
-               r10_bio.sector = sector;
-               raid10_find_phys(conf, &r10_bio);
+               r10_bio->sector = sector;
+               raid10_find_phys(conf, r10_bio);
                rcu_read_lock();
                for (s = 0; s < conf->copies; s++) {
-                       int disk = r10_bio.devs[s].devnum;
+                       int disk = r10_bio->devs[s].devnum;
                        struct md_rdev *rdev = rcu_dereference(
                                conf->mirrors[disk].rdev);
                        if (rdev && !test_bit(Faulty, &rdev->flags)) {
                                struct request_queue *q =
                                        bdev_get_queue(rdev->bdev);
                                if (q->merge_bvec_fn) {
-                                       bvm->bi_sector = r10_bio.devs[s].addr
+                                       bvm->bi_sector = r10_bio->devs[s].addr
                                                + rdev->data_offset;
                                        bvm->bi_bdev = rdev->bdev;
                                        max = min(max, q->merge_bvec_fn(
@@ -690,7 +694,7 @@ static int raid10_mergeable_bvec(struct request_queue *q,
                                struct request_queue *q =
                                        bdev_get_queue(rdev->bdev);
                                if (q->merge_bvec_fn) {
-                                       bvm->bi_sector = r10_bio.devs[s].addr
+                                       bvm->bi_sector = r10_bio->devs[s].addr
                                                + rdev->data_offset;
                                        bvm->bi_bdev = rdev->bdev;
                                        max = min(max, q->merge_bvec_fn(
@@ -4414,14 +4418,18 @@ static int handle_reshape_read_error(struct mddev *mddev,
 {
        /* Use sync reads to get the blocks from somewhere else */
        int sectors = r10_bio->sectors;
-       struct r10bio r10b;
        struct r10conf *conf = mddev->private;
+       struct {
+               struct r10bio r10_bio;
+               struct r10dev devs[conf->copies];
+       } on_stack;
+       struct r10bio *r10b = &on_stack.r10_bio;
        int slot = 0;
        int idx = 0;
        struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec;
 
-       r10b.sector = r10_bio->sector;
-       __raid10_find_phys(&conf->prev, &r10b);
+       r10b->sector = r10_bio->sector;
+       __raid10_find_phys(&conf->prev, r10b);
 
        while (sectors) {
                int s = sectors;
@@ -4432,7 +4440,7 @@ static int handle_reshape_read_error(struct mddev *mddev,
                        s = PAGE_SIZE >> 9;
 
                while (!success) {
-                       int d = r10b.devs[slot].devnum;
+                       int d = r10b->devs[slot].devnum;
                        struct md_rdev *rdev = conf->mirrors[d].rdev;
                        sector_t addr;
                        if (rdev == NULL ||
@@ -4440,7 +4448,7 @@ static int handle_reshape_read_error(struct mddev *mddev,
                            !test_bit(In_sync, &rdev->flags))
                                goto failed;
 
-                       addr = r10b.devs[slot].addr + idx * PAGE_SIZE;
+                       addr = r10b->devs[slot].addr + idx * PAGE_SIZE;
                        success = sync_page_io(rdev,
                                               addr,
                                               s << 9,
index 007c2c68dd8369f2acbcd9ae8d3c155399d13674..1054cf602345250f059ef81fae8bf9ef330cccd1 100644 (file)
@@ -110,7 +110,7 @@ struct r10bio {
         * We choose the number when they are allocated.
         * We sometimes need an extra bio to write to the replacement.
         */
-       struct {
+       struct r10dev {
                struct bio      *bio;
                union {
                        struct bio      *repl_bio; /* used for resync and
index 664e460f247b5a7d1d53629959da7705fb259aa1..aac622200e99a9e244523b8ead9994d510cac891 100644 (file)
@@ -481,7 +481,7 @@ static int smsusb_resume(struct usb_interface *intf)
        return 0;
 }
 
-static const struct usb_device_id smsusb_id_table[] __devinitconst = {
+static const struct usb_device_id smsusb_id_table[] = {
        { USB_DEVICE(0x187f, 0x0010),
                .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
        { USB_DEVICE(0x187f, 0x0100),
index d0b6bb507634a5756e7c5d6335a42f8da2b0d90f..72ded29728bbb2cbf459184095be31cf45a81270 100644 (file)
 #include <media/v4l2-device.h>
 #include <sound/tea575x-tuner.h>
 
+#if defined(CONFIG_LEDS_CLASS) || \
+    (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE))
+#define SHARK_USE_LEDS 1
+#endif
+
 /*
  * Version Information
  */
@@ -56,44 +61,18 @@ MODULE_LICENSE("GPL");
 
 enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS };
 
-static void shark_led_set_blue(struct led_classdev *led_cdev,
-                              enum led_brightness value);
-static void shark_led_set_blue_pulse(struct led_classdev *led_cdev,
-                                    enum led_brightness value);
-static void shark_led_set_red(struct led_classdev *led_cdev,
-                             enum led_brightness value);
-
-static const struct led_classdev shark_led_templates[NO_LEDS] = {
-       [BLUE_LED] = {
-               .name           = "%s:blue:",
-               .brightness     = LED_OFF,
-               .max_brightness = 127,
-               .brightness_set = shark_led_set_blue,
-       },
-       [BLUE_PULSE_LED] = {
-               .name           = "%s:blue-pulse:",
-               .brightness     = LED_OFF,
-               .max_brightness = 255,
-               .brightness_set = shark_led_set_blue_pulse,
-       },
-       [RED_LED] = {
-               .name           = "%s:red:",
-               .brightness     = LED_OFF,
-               .max_brightness = 1,
-               .brightness_set = shark_led_set_red,
-       },
-};
-
 struct shark_device {
        struct usb_device *usbdev;
        struct v4l2_device v4l2_dev;
        struct snd_tea575x tea;
 
+#ifdef SHARK_USE_LEDS
        struct work_struct led_work;
        struct led_classdev leds[NO_LEDS];
        char led_names[NO_LEDS][32];
        atomic_t brightness[NO_LEDS];
        unsigned long brightness_new;
+#endif
 
        u8 *transfer_buffer;
        u32 last_val;
@@ -175,20 +154,13 @@ static struct snd_tea575x_ops shark_tea_ops = {
        .read_val  = shark_read_val,
 };
 
+#ifdef SHARK_USE_LEDS
 static void shark_led_work(struct work_struct *work)
 {
        struct shark_device *shark =
                container_of(work, struct shark_device, led_work);
        int i, res, brightness, actual_len;
 
-       /*
-        * We use the v4l2_dev lock and registered bit to ensure the device
-        * does not get unplugged and unreffed while we're running.
-        */
-       mutex_lock(&shark->tea.mutex);
-       if (!video_is_registered(&shark->tea.vd))
-               goto leave;
-
        for (i = 0; i < 3; i++) {
                if (!test_and_clear_bit(i, &shark->brightness_new))
                        continue;
@@ -208,8 +180,6 @@ static void shark_led_work(struct work_struct *work)
                        v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
                                 shark->led_names[i], res);
        }
-leave:
-       mutex_unlock(&shark->tea.mutex);
 }
 
 static void shark_led_set_blue(struct led_classdev *led_cdev,
@@ -245,19 +215,78 @@ static void shark_led_set_red(struct led_classdev *led_cdev,
        schedule_work(&shark->led_work);
 }
 
+static const struct led_classdev shark_led_templates[NO_LEDS] = {
+       [BLUE_LED] = {
+               .name           = "%s:blue:",
+               .brightness     = LED_OFF,
+               .max_brightness = 127,
+               .brightness_set = shark_led_set_blue,
+       },
+       [BLUE_PULSE_LED] = {
+               .name           = "%s:blue-pulse:",
+               .brightness     = LED_OFF,
+               .max_brightness = 255,
+               .brightness_set = shark_led_set_blue_pulse,
+       },
+       [RED_LED] = {
+               .name           = "%s:red:",
+               .brightness     = LED_OFF,
+               .max_brightness = 1,
+               .brightness_set = shark_led_set_red,
+       },
+};
+
+static int shark_register_leds(struct shark_device *shark, struct device *dev)
+{
+       int i, retval;
+
+       INIT_WORK(&shark->led_work, shark_led_work);
+       for (i = 0; i < NO_LEDS; i++) {
+               shark->leds[i] = shark_led_templates[i];
+               snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
+                        shark->leds[i].name, shark->v4l2_dev.name);
+               shark->leds[i].name = shark->led_names[i];
+               retval = led_classdev_register(dev, &shark->leds[i]);
+               if (retval) {
+                       v4l2_err(&shark->v4l2_dev,
+                                "couldn't register led: %s\n",
+                                shark->led_names[i]);
+                       return retval;
+               }
+       }
+       return 0;
+}
+
+static void shark_unregister_leds(struct shark_device *shark)
+{
+       int i;
+
+       for (i = 0; i < NO_LEDS; i++)
+               led_classdev_unregister(&shark->leds[i]);
+
+       cancel_work_sync(&shark->led_work);
+}
+#else
+static int shark_register_leds(struct shark_device *shark, struct device *dev)
+{
+       v4l2_warn(&shark->v4l2_dev,
+                 "CONFIG_LED_CLASS not enabled, LED support disabled\n");
+       return 0;
+}
+static inline void shark_unregister_leds(struct shark_device *shark) { }
+#endif
+
 static void usb_shark_disconnect(struct usb_interface *intf)
 {
        struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
        struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
-       int i;
 
        mutex_lock(&shark->tea.mutex);
        v4l2_device_disconnect(&shark->v4l2_dev);
        snd_tea575x_exit(&shark->tea);
        mutex_unlock(&shark->tea.mutex);
 
-       for (i = 0; i < NO_LEDS; i++)
-               led_classdev_unregister(&shark->leds[i]);
+       shark_unregister_leds(shark);
 
        v4l2_device_put(&shark->v4l2_dev);
 }
@@ -266,7 +295,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev)
 {
        struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
 
-       cancel_work_sync(&shark->led_work);
        v4l2_device_unregister(&shark->v4l2_dev);
        kfree(shark->transfer_buffer);
        kfree(shark);
@@ -276,7 +304,7 @@ static int usb_shark_probe(struct usb_interface *intf,
                           const struct usb_device_id *id)
 {
        struct shark_device *shark;
-       int i, retval = -ENOMEM;
+       int retval = -ENOMEM;
 
        shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
        if (!shark)
@@ -286,17 +314,13 @@ static int usb_shark_probe(struct usb_interface *intf,
        if (!shark->transfer_buffer)
                goto err_alloc_buffer;
 
-       /*
-        * Work around a bug in usbhid/hid-core.c, where it leaves a dangling
-        * pointer in intfdata causing v4l2-device.c to not set it. Which
-        * results in usb_shark_disconnect() referencing the dangling pointer
-        *
-        * REMOVE (as soon as the above bug is fixed, patch submitted)
-        */
-       usb_set_intfdata(intf, NULL);
+       v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
+
+       retval = shark_register_leds(shark, &intf->dev);
+       if (retval)
+               goto err_reg_leds;
 
        shark->v4l2_dev.release = usb_shark_release;
-       v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
        retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
        if (retval) {
                v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
@@ -320,32 +344,13 @@ static int usb_shark_probe(struct usb_interface *intf,
                goto err_init_tea;
        }
 
-       INIT_WORK(&shark->led_work, shark_led_work);
-       for (i = 0; i < NO_LEDS; i++) {
-               shark->leds[i] = shark_led_templates[i];
-               snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
-                        shark->leds[i].name, shark->v4l2_dev.name);
-               shark->leds[i].name = shark->led_names[i];
-               /*
-                * We don't fail the probe if we fail to register the leds,
-                * because once we've called snd_tea575x_init, the /dev/radio0
-                * node may be opened from userspace holding a reference to us!
-                *
-                * Note we cannot register the leds first instead as
-                * shark_led_work depends on the v4l2 mutex and registered bit.
-                */
-               retval = led_classdev_register(&intf->dev, &shark->leds[i]);
-               if (retval)
-                       v4l2_err(&shark->v4l2_dev,
-                                "couldn't register led: %s\n",
-                                shark->led_names[i]);
-       }
-
        return 0;
 
 err_init_tea:
        v4l2_device_unregister(&shark->v4l2_dev);
 err_reg_dev:
+       shark_unregister_leds(shark);
+err_reg_leds:
        kfree(shark->transfer_buffer);
 err_alloc_buffer:
        kfree(shark);
index b9575de3e7e8306d5f9cdf6fa6efbd2b74c0984d..7b4efdfaae283748edea0dc359ae647667add6b6 100644 (file)
 #include <media/v4l2-device.h>
 #include "radio-tea5777.h"
 
+#if defined(CONFIG_LEDS_CLASS) || \
+    (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK2_MODULE))
+#define SHARK_USE_LEDS 1
+#endif
+
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver");
 MODULE_LICENSE("GPL");
@@ -43,7 +48,6 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-
 #define SHARK_IN_EP            0x83
 #define SHARK_OUT_EP           0x05
 
@@ -54,36 +58,18 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 enum { BLUE_LED, RED_LED, NO_LEDS };
 
-static void shark_led_set_blue(struct led_classdev *led_cdev,
-                              enum led_brightness value);
-static void shark_led_set_red(struct led_classdev *led_cdev,
-                             enum led_brightness value);
-
-static const struct led_classdev shark_led_templates[NO_LEDS] = {
-       [BLUE_LED] = {
-               .name           = "%s:blue:",
-               .brightness     = LED_OFF,
-               .max_brightness = 127,
-               .brightness_set = shark_led_set_blue,
-       },
-       [RED_LED] = {
-               .name           = "%s:red:",
-               .brightness     = LED_OFF,
-               .max_brightness = 1,
-               .brightness_set = shark_led_set_red,
-       },
-};
-
 struct shark_device {
        struct usb_device *usbdev;
        struct v4l2_device v4l2_dev;
        struct radio_tea5777 tea;
 
+#ifdef SHARK_USE_LEDS
        struct work_struct led_work;
        struct led_classdev leds[NO_LEDS];
        char led_names[NO_LEDS][32];
        atomic_t brightness[NO_LEDS];
        unsigned long brightness_new;
+#endif
 
        u8 *transfer_buffer;
 };
@@ -161,18 +147,12 @@ static struct radio_tea5777_ops shark_tea_ops = {
        .read_reg  = shark_read_reg,
 };
 
+#ifdef SHARK_USE_LEDS
 static void shark_led_work(struct work_struct *work)
 {
        struct shark_device *shark =
                container_of(work, struct shark_device, led_work);
        int i, res, brightness, actual_len;
-       /*
-        * We use the v4l2_dev lock and registered bit to ensure the device
-        * does not get unplugged and unreffed while we're running.
-        */
-       mutex_lock(&shark->tea.mutex);
-       if (!video_is_registered(&shark->tea.vd))
-               goto leave;
 
        for (i = 0; i < 2; i++) {
                if (!test_and_clear_bit(i, &shark->brightness_new))
@@ -191,8 +171,6 @@ static void shark_led_work(struct work_struct *work)
                        v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
                                 shark->led_names[i], res);
        }
-leave:
-       mutex_unlock(&shark->tea.mutex);
 }
 
 static void shark_led_set_blue(struct led_classdev *led_cdev,
@@ -217,19 +195,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev,
        schedule_work(&shark->led_work);
 }
 
+static const struct led_classdev shark_led_templates[NO_LEDS] = {
+       [BLUE_LED] = {
+               .name           = "%s:blue:",
+               .brightness     = LED_OFF,
+               .max_brightness = 127,
+               .brightness_set = shark_led_set_blue,
+       },
+       [RED_LED] = {
+               .name           = "%s:red:",
+               .brightness     = LED_OFF,
+               .max_brightness = 1,
+               .brightness_set = shark_led_set_red,
+       },
+};
+
+static int shark_register_leds(struct shark_device *shark, struct device *dev)
+{
+       int i, retval;
+
+       INIT_WORK(&shark->led_work, shark_led_work);
+       for (i = 0; i < NO_LEDS; i++) {
+               shark->leds[i] = shark_led_templates[i];
+               snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
+                        shark->leds[i].name, shark->v4l2_dev.name);
+               shark->leds[i].name = shark->led_names[i];
+               retval = led_classdev_register(dev, &shark->leds[i]);
+               if (retval) {
+                       v4l2_err(&shark->v4l2_dev,
+                                "couldn't register led: %s\n",
+                                shark->led_names[i]);
+                       return retval;
+               }
+       }
+       return 0;
+}
+
+static void shark_unregister_leds(struct shark_device *shark)
+{
+       int i;
+
+       for (i = 0; i < NO_LEDS; i++)
+               led_classdev_unregister(&shark->leds[i]);
+
+       cancel_work_sync(&shark->led_work);
+}
+#else
+static int shark_register_leds(struct shark_device *shark, struct device *dev)
+{
+       v4l2_warn(&shark->v4l2_dev,
+                 "CONFIG_LED_CLASS not enabled, LED support disabled\n");
+       return 0;
+}
+static inline void shark_unregister_leds(struct shark_device *shark) { }
+#endif
+
 static void usb_shark_disconnect(struct usb_interface *intf)
 {
        struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
        struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
-       int i;
 
        mutex_lock(&shark->tea.mutex);
        v4l2_device_disconnect(&shark->v4l2_dev);
        radio_tea5777_exit(&shark->tea);
        mutex_unlock(&shark->tea.mutex);
 
-       for (i = 0; i < NO_LEDS; i++)
-               led_classdev_unregister(&shark->leds[i]);
+       shark_unregister_leds(shark);
 
        v4l2_device_put(&shark->v4l2_dev);
 }
@@ -238,7 +269,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev)
 {
        struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
 
-       cancel_work_sync(&shark->led_work);
        v4l2_device_unregister(&shark->v4l2_dev);
        kfree(shark->transfer_buffer);
        kfree(shark);
@@ -248,7 +278,7 @@ static int usb_shark_probe(struct usb_interface *intf,
                           const struct usb_device_id *id)
 {
        struct shark_device *shark;
-       int i, retval = -ENOMEM;
+       int retval = -ENOMEM;
 
        shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
        if (!shark)
@@ -258,17 +288,13 @@ static int usb_shark_probe(struct usb_interface *intf,
        if (!shark->transfer_buffer)
                goto err_alloc_buffer;
 
-       /*
-        * Work around a bug in usbhid/hid-core.c, where it leaves a dangling
-        * pointer in intfdata causing v4l2-device.c to not set it. Which
-        * results in usb_shark_disconnect() referencing the dangling pointer
-        *
-        * REMOVE (as soon as the above bug is fixed, patch submitted)
-        */
-       usb_set_intfdata(intf, NULL);
+       v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
+
+       retval = shark_register_leds(shark, &intf->dev);
+       if (retval)
+               goto err_reg_leds;
 
        shark->v4l2_dev.release = usb_shark_release;
-       v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
        retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
        if (retval) {
                v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
@@ -292,32 +318,13 @@ static int usb_shark_probe(struct usb_interface *intf,
                goto err_init_tea;
        }
 
-       INIT_WORK(&shark->led_work, shark_led_work);
-       for (i = 0; i < NO_LEDS; i++) {
-               shark->leds[i] = shark_led_templates[i];
-               snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
-                        shark->leds[i].name, shark->v4l2_dev.name);
-               shark->leds[i].name = shark->led_names[i];
-               /*
-                * We don't fail the probe if we fail to register the leds,
-                * because once we've called radio_tea5777_init, the /dev/radio0
-                * node may be opened from userspace holding a reference to us!
-                *
-                * Note we cannot register the leds first instead as
-                * shark_led_work depends on the v4l2 mutex and registered bit.
-                */
-               retval = led_classdev_register(&intf->dev, &shark->leds[i]);
-               if (retval)
-                       v4l2_err(&shark->v4l2_dev,
-                                "couldn't register led: %s\n",
-                                shark->led_names[i]);
-       }
-
        return 0;
 
 err_init_tea:
        v4l2_device_unregister(&shark->v4l2_dev);
 err_reg_dev:
+       shark_unregister_leds(shark);
+err_reg_leds:
        kfree(shark->transfer_buffer);
 err_alloc_buffer:
        kfree(shark);
index 9e38132afec66488299ebd4227a94e9a2e5d3a11..9bb65e170d99bd87455107083379931c6bda40a6 100644 (file)
@@ -151,6 +151,7 @@ static const struct v4l2_frequency_band bands[] = {
                .index = 0,
                .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                            V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
+                           V4L2_TUNER_CAP_FREQ_BANDS |
                            V4L2_TUNER_CAP_HWSEEK_BOUNDED |
                            V4L2_TUNER_CAP_HWSEEK_WRAP,
                .rangelow   =  87500 * 16,
@@ -162,6 +163,7 @@ static const struct v4l2_frequency_band bands[] = {
                .index = 1,
                .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                            V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
+                           V4L2_TUNER_CAP_FREQ_BANDS |
                            V4L2_TUNER_CAP_HWSEEK_BOUNDED |
                            V4L2_TUNER_CAP_HWSEEK_WRAP,
                .rangelow   =  76000 * 16,
@@ -173,6 +175,7 @@ static const struct v4l2_frequency_band bands[] = {
                .index = 2,
                .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                            V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
+                           V4L2_TUNER_CAP_FREQ_BANDS |
                            V4L2_TUNER_CAP_HWSEEK_BOUNDED |
                            V4L2_TUNER_CAP_HWSEEK_WRAP,
                .rangelow   =  76000 * 16,
index 643a6ff7c5d0e629e70112c0c4e67fe0459c580b..f867f04cccc99626bb7fc5dee97d34f2adaed9fa 100644 (file)
@@ -225,8 +225,9 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
 {
        strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
        strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
-       capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
-               V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+       capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
+               V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
+       capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
 
        return 0;
 }
index 146be4263ea17d92ab072d13ae4d12fa610b9276..be076f7181e728b1ab177ca340290a2c1ae29dc4 100644 (file)
@@ -531,7 +531,7 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
        strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
        usb_make_path(radio->usbdev, capability->bus_info,
                        sizeof(capability->bus_info));
-       capability->device_caps = V4L2_CAP_HW_FREQ_SEEK |
+       capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
                V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
        capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
        return 0;
index 5180390be7ab0915ffa24189269ce4707e1e3baf..8be57634ba60f23e09fc5840a6bb6837920549e2 100644 (file)
@@ -261,6 +261,7 @@ config IR_WINBOND_CIR
 
 config IR_IGUANA
        tristate "IguanaWorks USB IR Transceiver"
+       depends on USB_ARCH_HAS_HCD
        depends on RC_CORE
        select USB
        ---help---
index cf9d9fca5b84005cd37e24cba853c9d132e504be..234777116e5fc5e8cc25a6f4e1940feca8a31412 100644 (file)
@@ -512,7 +512,7 @@ static const struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
        {USB_DEVICE(0x0979, 0x0227)},
        {}
 };
index 969bb5a4cd9307812cc45f2224f3be5bd1fa5617..bab01c86c3154933c819d941bbcfe3c6ffea60ef 100644 (file)
@@ -579,7 +579,7 @@ static const struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static const struct usb_device_id device_table[] = {
        {USB_DEVICE(0x06e1, 0xa190)},
 /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
        {USB_DEVICE(0x0733, 0x0430)}, */
index 7efe9ad7acc7f90f0942644ee4d909b8b9705618..0b91a5cd38ebaaba2e940b7cf93244e9e5476f3c 100644 (file)
@@ -431,7 +431,7 @@ static int vidioc_querycap(struct file *file, void *priv,
        strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
        strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
        strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info));
-       cap->capabilities = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
+       cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
        return 0;
 }
index d2e6f82ecfac080cc951d1aa59014f58dbb35487..560a65aa7038dd3cded8d08395958c70e3c537bb 100644 (file)
@@ -403,7 +403,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
 
        dev_dbg(pcdev->icd->parent, "Activate device\n");
 
-       clk_enable(pcdev->clk);
+       clk_prepare_enable(pcdev->clk);
 
        /* enable CSI before doing anything else */
        __raw_writel(csicr1, pcdev->base + CSICR1);
@@ -422,7 +422,7 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
        /* Disable all CSI interface */
        __raw_writel(0x00, pcdev->base + CSICR1);
 
-       clk_disable(pcdev->clk);
+       clk_disable_unprepare(pcdev->clk);
 }
 
 /*
index 637bde8aca28e25c2799cd85aded6eedafa3075c..ac175406e582a0c12c2d62fe8de713f89a5353cc 100644 (file)
@@ -272,7 +272,7 @@ struct mx2_camera_dev {
        struct device           *dev;
        struct soc_camera_host  soc_host;
        struct soc_camera_device *icd;
-       struct clk              *clk_csi, *clk_emma;
+       struct clk              *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
 
        unsigned int            irq_csi, irq_emma;
        void __iomem            *base_csi, *base_emma;
@@ -407,7 +407,7 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
 {
        unsigned long flags;
 
-       clk_disable(pcdev->clk_csi);
+       clk_disable_unprepare(pcdev->clk_csi);
        writel(0, pcdev->base_csi + CSICR1);
        if (cpu_is_mx27()) {
                writel(0, pcdev->base_emma + PRP_CNTL);
@@ -435,7 +435,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
        if (pcdev->icd)
                return -EBUSY;
 
-       ret = clk_enable(pcdev->clk_csi);
+       ret = clk_prepare_enable(pcdev->clk_csi);
        if (ret < 0)
                return ret;
 
@@ -1633,23 +1633,34 @@ static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev)
                goto exit_iounmap;
        }
 
-       pcdev->clk_emma = clk_get(NULL, "emma");
-       if (IS_ERR(pcdev->clk_emma)) {
-               err = PTR_ERR(pcdev->clk_emma);
+       pcdev->clk_emma_ipg = clk_get(pcdev->dev, "emma-ipg");
+       if (IS_ERR(pcdev->clk_emma_ipg)) {
+               err = PTR_ERR(pcdev->clk_emma_ipg);
                goto exit_free_irq;
        }
 
-       clk_enable(pcdev->clk_emma);
+       clk_prepare_enable(pcdev->clk_emma_ipg);
+
+       pcdev->clk_emma_ahb = clk_get(pcdev->dev, "emma-ahb");
+       if (IS_ERR(pcdev->clk_emma_ahb)) {
+               err = PTR_ERR(pcdev->clk_emma_ahb);
+               goto exit_clk_emma_ipg_put;
+       }
+
+       clk_prepare_enable(pcdev->clk_emma_ahb);
 
        err = mx27_camera_emma_prp_reset(pcdev);
        if (err)
-               goto exit_clk_emma_put;
+               goto exit_clk_emma_ahb_put;
 
        return err;
 
-exit_clk_emma_put:
-       clk_disable(pcdev->clk_emma);
-       clk_put(pcdev->clk_emma);
+exit_clk_emma_ahb_put:
+       clk_disable_unprepare(pcdev->clk_emma_ahb);
+       clk_put(pcdev->clk_emma_ahb);
+exit_clk_emma_ipg_put:
+       clk_disable_unprepare(pcdev->clk_emma_ipg);
+       clk_put(pcdev->clk_emma_ipg);
 exit_free_irq:
        free_irq(pcdev->irq_emma, pcdev);
 exit_iounmap:
@@ -1685,7 +1696,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
                goto exit;
        }
 
-       pcdev->clk_csi = clk_get(&pdev->dev, NULL);
+       pcdev->clk_csi = clk_get(&pdev->dev, "ahb");
        if (IS_ERR(pcdev->clk_csi)) {
                dev_err(&pdev->dev, "Could not get csi clock\n");
                err = PTR_ERR(pcdev->clk_csi);
@@ -1785,8 +1796,10 @@ exit_free_emma:
 eallocctx:
        if (cpu_is_mx27()) {
                free_irq(pcdev->irq_emma, pcdev);
-               clk_disable(pcdev->clk_emma);
-               clk_put(pcdev->clk_emma);
+               clk_disable_unprepare(pcdev->clk_emma_ipg);
+               clk_put(pcdev->clk_emma_ipg);
+               clk_disable_unprepare(pcdev->clk_emma_ahb);
+               clk_put(pcdev->clk_emma_ahb);
                iounmap(pcdev->base_emma);
                release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma));
        }
@@ -1825,8 +1838,10 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
        iounmap(pcdev->base_csi);
 
        if (cpu_is_mx27()) {
-               clk_disable(pcdev->clk_emma);
-               clk_put(pcdev->clk_emma);
+               clk_disable_unprepare(pcdev->clk_emma_ipg);
+               clk_put(pcdev->clk_emma_ipg);
+               clk_disable_unprepare(pcdev->clk_emma_ahb);
+               clk_put(pcdev->clk_emma_ahb);
                iounmap(pcdev->base_emma);
                res = pcdev->res_emma;
                release_mem_region(res->start, resource_size(res));
index f13643d313531d16b59f98b532df328762c23b41..af2297dd49c8d7277000a03c2c4083ca0598aaa4 100644 (file)
 
 #define MAX_VIDEO_MEM 16
 
-enum csi_buffer_state {
-       CSI_BUF_NEEDS_INIT,
-       CSI_BUF_PREPARED,
-};
-
 struct mx3_camera_buffer {
        /* common v4l buffer stuff -- must be first */
        struct vb2_buffer                       vb;
-       enum csi_buffer_state                   state;
        struct list_head                        queue;
 
        /* One descriptot per scatterlist (per frame) */
@@ -285,7 +279,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
                goto error;
        }
 
-       if (buf->state == CSI_BUF_NEEDS_INIT) {
+       if (!buf->txd) {
                sg_dma_address(sg)      = vb2_dma_contig_plane_dma_addr(vb, 0);
                sg_dma_len(sg)          = new_size;
 
@@ -298,7 +292,6 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
                txd->callback_param     = txd;
                txd->callback           = mx3_cam_dma_done;
 
-               buf->state              = CSI_BUF_PREPARED;
                buf->txd                = txd;
        } else {
                txd = buf->txd;
@@ -385,7 +378,6 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
 
        /* Doesn't hurt also if the list is empty */
        list_del_init(&buf->queue);
-       buf->state = CSI_BUF_NEEDS_INIT;
 
        if (txd) {
                buf->txd = NULL;
@@ -405,13 +397,13 @@ static int mx3_videobuf_init(struct vb2_buffer *vb)
        struct mx3_camera_dev *mx3_cam = ici->priv;
        struct mx3_camera_buffer *buf = to_mx3_vb(vb);
 
-       /* This is for locking debugging only */
-       INIT_LIST_HEAD(&buf->queue);
-       sg_init_table(&buf->sg, 1);
+       if (!buf->txd) {
+               /* This is for locking debugging only */
+               INIT_LIST_HEAD(&buf->queue);
+               sg_init_table(&buf->sg, 1);
 
-       buf->state = CSI_BUF_NEEDS_INIT;
-
-       mx3_cam->buf_total += vb2_plane_size(vb, 0);
+               mx3_cam->buf_total += vb2_plane_size(vb, 0);
+       }
 
        return 0;
 }
index b03ffecb7438002ee5aad631453d0fa9030c2edc..1bde255e45dfcd4554594e6fd5f844d130fa5d16 100644 (file)
@@ -171,7 +171,8 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd,
        dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
                pixfmtstr(pix->pixelformat), pix->width, pix->height);
 
-       if (!(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) {
+       if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
+           !(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) {
                pix->bytesperline = 0;
                pix->sizeimage = 0;
        }
index 89dce097a827a57d918702b0a4cd415b48ee409e..a397812635d6a6a05d2a0ba4606794f2566a8786 100644 (file)
@@ -378,6 +378,9 @@ EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
 
 s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
 {
+       if (mf->fourcc == V4L2_PIX_FMT_JPEG)
+               return 0;
+
        if (mf->layout != SOC_MBUS_LAYOUT_PACKED)
                return width * mf->bits_per_sample / 8;
 
@@ -400,6 +403,9 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line);
 s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
                        u32 bytes_per_line, u32 height)
 {
+       if (mf->fourcc == V4L2_PIX_FMT_JPEG)
+               return 0;
+
        if (mf->layout == SOC_MBUS_LAYOUT_PACKED)
                return bytes_per_line * height;
 
index 9288fbd5001b26e8bcf3210ffbfc0da7891f1182..5577381b5bf057357c6c4f591e4eb09269c2eb38 100644 (file)
@@ -338,6 +338,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
        if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) {
                buf->error = 0;
                buf->state = UVC_BUF_STATE_QUEUED;
+               buf->bytesused = 0;
                vb2_set_plane_payload(&buf->buf, 0, 0);
                return buf;
        }
index c3b7b5f59b328a8beea170977261e4d650da88b7..6bc47fc82fe2f799bfff8a3f885fae27bf1a0aa0 100644 (file)
@@ -402,8 +402,10 @@ static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
 {
        const struct v4l2_hw_freq_seek *p = arg;
 
-       pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
-               p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
+       pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, "
+               "rangelow=%u, rangehigh=%u\n",
+               p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
+               p->rangelow, p->rangehigh);
 }
 
 static void v4l_print_requestbuffers(const void *arg, bool write_only)
@@ -1853,6 +1855,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
                        .type = type,
                };
 
+               if (p->index)
+                       return -EINVAL;
                err = ops->vidioc_g_tuner(file, fh, &t);
                if (err)
                        return err;
@@ -1870,6 +1874,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
 
                if (type != V4L2_TUNER_RADIO)
                        return -EINVAL;
+               if (p->index)
+                       return -EINVAL;
                err = ops->vidioc_g_modulator(file, fh, &m);
                if (err)
                        return err;
index d1facef28a60d77bc4f3eb8264e7fffeab1fc445..b1a146205c0862587aa81a4a6b32dd7b19322152 100644 (file)
@@ -395,7 +395,8 @@ config MFD_TC6387XB
 
 config MFD_TC6393XB
        bool "Support Toshiba TC6393XB"
-       depends on GPIOLIB && ARM && HAVE_CLK
+       depends on ARM && HAVE_CLK
+       select GPIOLIB
        select MFD_CORE
        select MFD_TMIO
        help
index 383421bf57609a994b7f8d537f97c269d2ab6302..683e18a23329802875d03f92d53e354a6474ad9d 100644 (file)
@@ -925,6 +925,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
                        goto out;
        }
 
+       ret = 0;
        if (pdata->leds) {
                int i;
 
index 43a76c41cfcc9fe39084dd2967eaba23a4e87a52..db662e2dcfa5ba3cae4cd07694dc0caa95e72d80 100644 (file)
@@ -202,7 +202,7 @@ static void pcap_isr_work(struct work_struct *work)
                }
                local_irq_enable();
                ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
-       } while (gpio_get_value(irq_to_gpio(pcap->spi->irq)));
+       } while (gpio_get_value(pdata->gpio));
 }
 
 static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
index c6ffbbe5a6c014b11ee05855795c1c941d0f0abe..d78c05e693f7d45c8cf8ca0971ef2184a73c0597 100644 (file)
@@ -1253,7 +1253,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
                        if (dev->wd_timeout)
                                *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
                        else
-                               *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
+                               *slots -= mei_data2slots(MEI_WD_PARAMS_SIZE);
                }
        }
        if (dev->stop)
index 092330208869640a1e474abfd781bce41a5c6043..7422c76528458134f450eb496d52b1a297e18f8a 100644 (file)
@@ -924,6 +924,27 @@ static struct miscdevice  mei_misc_device = {
                .minor = MISC_DYNAMIC_MINOR,
 };
 
+/**
+ * mei_quirk_probe - probe for devices that doesn't valid ME interface
+ * @pdev: PCI device structure
+ * @ent: entry into pci_device_table
+ *
+ * returns true if ME Interface is valid, false otherwise
+ */
+static bool __devinit mei_quirk_probe(struct pci_dev *pdev,
+                               const struct pci_device_id *ent)
+{
+       u32 reg;
+       if (ent->device == MEI_DEV_ID_PBG_1) {
+               pci_read_config_dword(pdev, 0x48, &reg);
+               /* make sure that bit 9 is up and bit 10 is down */
+               if ((reg & 0x600) == 0x200) {
+                       dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
+                       return false;
+               }
+       }
+       return true;
+}
 /**
  * mei_probe - Device Initialization Routine
  *
@@ -939,6 +960,12 @@ static int __devinit mei_probe(struct pci_dev *pdev,
        int err;
 
        mutex_lock(&mei_mutex);
+
+       if (!mei_quirk_probe(pdev, ent)) {
+               err = -ENODEV;
+               goto end;
+       }
+
        if (mei_device) {
                err = -EEXIST;
                goto end;
index 87b251ab6ec582f2c8177687d0b330d97110fb50..b9e2000969f025894be4bcae2c6950d699ded3a9 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <asm/uv/uv_hub.h>
@@ -59,6 +61,8 @@ static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
                                         XPC_NOTIFY_MSG_SIZE_UV)
 #define XPC_NOTIFY_IRQ_NAME            "xpc_notify"
 
+static int xpc_mq_node = -1;
+
 static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
 static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
 
@@ -109,11 +113,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
 #if defined CONFIG_X86_64
        mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
                        UV_AFFINITY_CPU);
-       if (mq->irq < 0) {
-               dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
-                       -mq->irq);
+       if (mq->irq < 0)
                return mq->irq;
-       }
 
        mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
 
@@ -238,8 +239,9 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
        mq->mmr_blade = uv_cpu_to_blade_id(cpu);
 
        nid = cpu_to_node(cpu);
-       page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
-                               pg_order);
+       page = alloc_pages_exact_node(nid,
+                                     GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+                                     pg_order);
        if (page == NULL) {
                dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
                        "bytes of memory on nid=%d for GRU mq\n", mq_size, nid);
@@ -1731,9 +1733,50 @@ static struct xpc_arch_operations xpc_arch_ops_uv = {
        .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
 };
 
+static int
+xpc_init_mq_node(int nid)
+{
+       int cpu;
+
+       get_online_cpus();
+
+       for_each_cpu(cpu, cpumask_of_node(nid)) {
+               xpc_activate_mq_uv =
+                       xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid,
+                                            XPC_ACTIVATE_IRQ_NAME,
+                                            xpc_handle_activate_IRQ_uv);
+               if (!IS_ERR(xpc_activate_mq_uv))
+                       break;
+       }
+       if (IS_ERR(xpc_activate_mq_uv)) {
+               put_online_cpus();
+               return PTR_ERR(xpc_activate_mq_uv);
+       }
+
+       for_each_cpu(cpu, cpumask_of_node(nid)) {
+               xpc_notify_mq_uv =
+                       xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid,
+                                            XPC_NOTIFY_IRQ_NAME,
+                                            xpc_handle_notify_IRQ_uv);
+               if (!IS_ERR(xpc_notify_mq_uv))
+                       break;
+       }
+       if (IS_ERR(xpc_notify_mq_uv)) {
+               xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
+               put_online_cpus();
+               return PTR_ERR(xpc_notify_mq_uv);
+       }
+
+       put_online_cpus();
+       return 0;
+}
+
 int
 xpc_init_uv(void)
 {
+       int nid;
+       int ret = 0;
+
        xpc_arch_ops = xpc_arch_ops_uv;
 
        if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
@@ -1742,21 +1785,21 @@ xpc_init_uv(void)
                return -E2BIG;
        }
 
-       xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0,
-                                                 XPC_ACTIVATE_IRQ_NAME,
-                                                 xpc_handle_activate_IRQ_uv);
-       if (IS_ERR(xpc_activate_mq_uv))
-               return PTR_ERR(xpc_activate_mq_uv);
+       if (xpc_mq_node < 0)
+               for_each_online_node(nid) {
+                       ret = xpc_init_mq_node(nid);
 
-       xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0,
-                                               XPC_NOTIFY_IRQ_NAME,
-                                               xpc_handle_notify_IRQ_uv);
-       if (IS_ERR(xpc_notify_mq_uv)) {
-               xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
-               return PTR_ERR(xpc_notify_mq_uv);
-       }
+                       if (!ret)
+                               break;
+               }
+       else
+               ret = xpc_init_mq_node(xpc_mq_node);
 
-       return 0;
+       if (ret < 0)
+               dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n",
+                       -ret);
+
+       return ret;
 }
 
 void
@@ -1765,3 +1808,6 @@ xpc_exit_uv(void)
        xpc_destroy_gru_mq_uv(xpc_notify_mq_uv);
        xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
 }
+
+module_param(xpc_mq_node, int, 0);
+MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues.");
index 1ff460a8e9c74f67e584d634016fa25332fd351c..93b4d67cc4a3a6bc30197acf709d4f73faaad070 100644 (file)
@@ -87,7 +87,7 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
        /* communicate to platform about chip wakeup */
        kim_data = st_data->kim_data;
        pdata = kim_data->kim_pdev->dev.platform_data;
-       if (pdata->chip_asleep)
+       if (pdata->chip_awake)
                pdata->chip_awake(NULL);
 }
 
index cfff454f628ba73498f0876355e9c1266d67c7fa..c3bb304eca076ffab133b7cd1e6a363a0763dfaa 100644 (file)
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 #include <asm/io.h>
+#include <asm/sections.h>
 
 /****************************************************************************/
 
-extern char _ebss;
-
 struct map_info uclinux_ram_map = {
        .name = "RAM",
-       .phys = (unsigned long)&_ebss,
+       .phys = (unsigned long)__bss_stop,
        .size = 0,
 };
 
index 0d93407989542a7744b513dc26ae8a3c0f9c792d..598cd0a3adeeabf7953344bc95dc7898b0559abe 100644 (file)
@@ -440,7 +440,7 @@ config MTD_NAND_NANDSIM
 
 config MTD_NAND_GPMI_NAND
         bool "GPMI NAND Flash Controller driver"
-        depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q)
+        depends on MTD_NAND && MXS_DMA
         help
         Enables NAND Flash support for IMX23 or IMX28.
         The GPMI controller is very powerful, with the help of BCH
index e9309b3659e746096b08a953fd055e2517babb3d..ac4fd756eda375ab40f873b9f29bcaad0a5aeea0 100644 (file)
@@ -1245,7 +1245,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
                        goto out_release_mem_region;
                } else {
                        struct dma_slave_config cfg;
-                       int rc;
 
                        memset(&cfg, 0, sizeof(cfg));
                        cfg.src_addr = info->phys_base;
@@ -1254,10 +1253,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
                        cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
                        cfg.src_maxburst = 16;
                        cfg.dst_maxburst = 16;
-                       rc = dmaengine_slave_config(info->dma, &cfg);
-                       if (rc) {
+                       err = dmaengine_slave_config(info->dma, &cfg);
+                       if (err) {
                                dev_err(&pdev->dev, "DMA engine slave config failed: %d\n",
-                                       rc);
+                                       err);
                                goto out_release_mem_region;
                        }
                        info->nand.read_buf   = omap_read_buf_dma_pref;
index 545c09ed9079baead2abff5ad9b309a5a0856cac..cff6f023c03a2c78e9869375f93b00c3201af802 100644 (file)
@@ -996,9 +996,7 @@ static int __init cops_module_init(void)
                printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
                        cardname);
        cops_dev = cops_probe(-1);
-       if (IS_ERR(cops_dev))
-               return PTR_ERR(cops_dev);
-        return 0;
+       return PTR_RET(cops_dev);
 }
 
 static void __exit cops_module_exit(void)
index 0910dce3996d08a64c5c158056e0430c472962f1..b5782cdf0bcae1b5500b31477c26a54194f67f41 100644 (file)
@@ -1243,9 +1243,7 @@ static int __init ltpc_module_init(void)
                       "ltpc: Autoprobing is not recommended for modules\n");
 
        dev_ltpc = ltpc_probe();
-       if (IS_ERR(dev_ltpc))
-               return PTR_ERR(dev_ltpc);
-       return 0;
+       return PTR_RET(dev_ltpc);
 }
 module_init(ltpc_module_init);
 #endif
index 6fae5f3ec7f6d646e4efc79aac1a0449ca5bde21..d688a8af432c52a8ea3dc5e45607c2801e9fb831 100644 (file)
@@ -398,7 +398,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
                     sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
        skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping;
 
-       if (unlikely(netpoll_tx_running(slave_dev)))
+       if (unlikely(netpoll_tx_running(bond->dev)))
                bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
        else
                dev_queue_xmit(skb);
@@ -1235,12 +1235,12 @@ static inline int slave_enable_netpoll(struct slave *slave)
        struct netpoll *np;
        int err = 0;
 
-       np = kzalloc(sizeof(*np), GFP_KERNEL);
+       np = kzalloc(sizeof(*np), GFP_ATOMIC);
        err = -ENOMEM;
        if (!np)
                goto out;
 
-       err = __netpoll_setup(np, slave->dev);
+       err = __netpoll_setup(np, slave->dev, GFP_ATOMIC);
        if (err) {
                kfree(np);
                goto out;
@@ -1257,9 +1257,7 @@ static inline void slave_disable_netpoll(struct slave *slave)
                return;
 
        slave->np = NULL;
-       synchronize_rcu_bh();
-       __netpoll_cleanup(np);
-       kfree(np);
+       __netpoll_free_rcu(np);
 }
 static inline bool slave_dev_support_netpoll(struct net_device *slave_dev)
 {
@@ -1292,7 +1290,7 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev)
        read_unlock(&bond->lock);
 }
 
-static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
+static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, gfp_t gfp)
 {
        struct bonding *bond = netdev_priv(dev);
        struct slave *slave;
index f0c8bd54ce2930d87a5c6479fef7e9f39e4ca37d..021d69c5d9bc951797ede8e72dde15bad706613b 100644 (file)
@@ -1712,7 +1712,7 @@ e100_set_network_leds(int active)
 static void
 e100_netpoll(struct net_device* netdev)
 {
-       e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL);
+       e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev);
 }
 #endif
 
index 77bcd4cb4ffb945a8c696cc3f6bab1e363733c48..463b9ec57d8077c8a1599457974ab15dc1210536 100644 (file)
@@ -1278,7 +1278,7 @@ struct bnx2x {
 #define BNX2X_FW_RX_ALIGN_START        (1UL << BNX2X_RX_ALIGN_SHIFT)
 
 #define BNX2X_FW_RX_ALIGN_END                                  \
-       max(1UL << BNX2X_RX_ALIGN_SHIFT,                        \
+       max_t(u64, 1UL << BNX2X_RX_ALIGN_SHIFT,                 \
            SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
 
 #define BNX2X_PXP_DRAM_ALIGN           (BNX2X_RX_ALIGN_SHIFT - 5)
index dd451c3dd83d1d614a13070e85ffc9a3e8c458e8..02b5a343b19506a2edc60be5dd6b41d781aadb85 100644 (file)
@@ -4041,20 +4041,6 @@ static bool bnx2x_get_load_status(struct bnx2x *bp, int engine)
        return val != 0;
 }
 
-/*
- * Reset the load status for the current engine.
- */
-static void bnx2x_clear_load_status(struct bnx2x *bp)
-{
-       u32 val;
-       u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
-                   BNX2X_PATH0_LOAD_CNT_MASK);
-       bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
-       val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
-       REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask));
-       bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
-}
-
 static void _print_next_block(int idx, const char *blk)
 {
        pr_cont("%s%s", idx ? ", " : "", blk);
@@ -9384,32 +9370,24 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp)
        return rc;
 }
 
-static bool __devinit bnx2x_can_flr(struct bnx2x *bp)
-{
-       int pos;
-       u32 cap;
-       struct pci_dev *dev = bp->pdev;
-
-       pos = pci_pcie_cap(dev);
-       if (!pos)
-               return false;
-
-       pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
-       if (!(cap & PCI_EXP_DEVCAP_FLR))
-               return false;
-
-       return true;
-}
-
 static int __devinit bnx2x_do_flr(struct bnx2x *bp)
 {
        int i, pos;
        u16 status;
        struct pci_dev *dev = bp->pdev;
 
-       /* probe the capability first */
-       if (bnx2x_can_flr(bp))
-               return -ENOTTY;
+
+       if (CHIP_IS_E1x(bp)) {
+               BNX2X_DEV_INFO("FLR not supported in E1/E1H\n");
+               return -EINVAL;
+       }
+
+       /* only bootcode REQ_BC_VER_4_INITIATE_FLR and onwards support flr */
+       if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) {
+               BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n",
+                         bp->common.bc_ver);
+               return -EINVAL;
+       }
 
        pos = pci_pcie_cap(dev);
        if (!pos)
@@ -9429,12 +9407,8 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp)
                "transaction is not cleared; proceeding with reset anyway\n");
 
 clear:
-       if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) {
-               BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n",
-                         bp->common.bc_ver);
-               return -EINVAL;
-       }
 
+       BNX2X_DEV_INFO("Initiating FLR\n");
        bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0);
 
        return 0;
@@ -9454,8 +9428,21 @@ static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp)
         * the one required, then FLR will be sufficient to clean any residue
         * left by previous driver
         */
-       if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp))
-               return bnx2x_do_flr(bp);
+       rc = bnx2x_test_firmware_version(bp, false);
+
+       if (!rc) {
+               /* fw version is good */
+               BNX2X_DEV_INFO("FW version matches our own. Attempting FLR\n");
+               rc = bnx2x_do_flr(bp);
+       }
+
+       if (!rc) {
+               /* FLR was performed */
+               BNX2X_DEV_INFO("FLR successful\n");
+               return 0;
+       }
+
+       BNX2X_DEV_INFO("Could not FLR\n");
 
        /* Close the MCP request, return failure*/
        rc = bnx2x_prev_mcp_done(bp);
@@ -11427,9 +11414,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
        if (!chip_is_e1x)
                REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
 
-       /* Reset the load counter */
-       bnx2x_clear_load_status(bp);
-
        dev->watchdog_timeo = TX_TIMEOUT;
 
        dev->netdev_ops = &bnx2x_netdev_ops;
index 734fd87cd99093e0d30899006cb12cacd10a027c..62f754bd0dfe65704a1af826a754a720dc8cfd43 100644 (file)
@@ -2485,6 +2485,7 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp,
                break;
 
        default:
+               kfree(new_cmd);
                BNX2X_ERR("Unknown command: %d\n", cmd);
                return -EINVAL;
        }
index c60de89b66696759a453ff4d69650c1905209c58..90a903d83d8747ca26d711b7b3a188f81a554611 100644 (file)
@@ -1948,7 +1948,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
 
        if (adapter->num_rx_qs != MAX_RX_QS)
                dev_info(&adapter->pdev->dev,
-                       "Created only %d receive queues", adapter->num_rx_qs);
+                       "Created only %d receive queues\n", adapter->num_rx_qs);
 
        return 0;
 }
index 0f2d1a710909e5044b3c2c402bf2aba0b950ff88..151453309401694360f311ccb09e0caea8480b01 100644 (file)
@@ -174,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
 
        new_bus->phy_mask = ~0;
        new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
-       if (!new_bus->irq)
+       if (!new_bus->irq) {
+               ret = -ENOMEM;
                goto out_unmap_regs;
+       }
 
        new_bus->parent = &ofdev->dev;
        dev_set_drvdata(&ofdev->dev, new_bus);
index 55bb867258e6aa1d2baa1dbf4da546c705a2e83f..cdf702a594858146fd4f04ab02966d941edeeea5 100644 (file)
@@ -137,8 +137,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
        snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
 
        fec->fecp = ioremap(res.start, resource_size(&res));
-       if (!fec->fecp)
+       if (!fec->fecp) {
+               ret = -ENOMEM;
                goto out_fec;
+       }
 
        if (get_bus_freq) {
                clock = get_bus_freq(ofdev->dev.of_node);
@@ -172,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
 
        new_bus->phy_mask = ~0;
        new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
-       if (!new_bus->irq)
+       if (!new_bus->irq) {
+               ret = -ENOMEM;
                goto out_unmap_regs;
+       }
 
        new_bus->parent = &ofdev->dev;
        dev_set_drvdata(&ofdev->dev, new_bus);
index 0b3bade957fd8424f59f16ff6e5e27a7c0b6058e..080c89093feb5df6393c6d8f58421ff254f2b05d 100644 (file)
@@ -999,7 +999,7 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
  **/
 static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
 {
-       u32 ctrl, ctrl_ext, eecd;
+       u32 ctrl, ctrl_ext, eecd, tctl;
        s32 ret_val;
 
        /*
@@ -1014,7 +1014,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
        ew32(IMC, 0xffffffff);
 
        ew32(RCTL, 0);
-       ew32(TCTL, E1000_TCTL_PSP);
+       tctl = er32(TCTL);
+       tctl &= ~E1000_TCTL_EN;
+       ew32(TCTL, tctl);
        e1e_flush();
 
        usleep_range(10000, 20000);
@@ -1601,10 +1603,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
                         * auto-negotiation in the TXCW register and disable
                         * forced link in the Device Control register in an
                         * attempt to auto-negotiate with our link partner.
-                        * If the partner code word is null, stop forcing
-                        * and restart auto negotiation.
                         */
-                       if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW))  {
+                       if (rxcw & E1000_RXCW_C) {
                                /* Enable autoneg, and unforce link up */
                                ew32(TXCW, mac->txcw);
                                ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
index 95b245310f1761fa4f9b06de319cea48fdc28c92..46c3b1f9ff8997af685836bb82fb0e1bd5e599cf 100644 (file)
@@ -178,6 +178,24 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
        pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]);
 }
 
+static void e1000e_dump_ps_pages(struct e1000_adapter *adapter,
+                                struct e1000_buffer *bi)
+{
+       int i;
+       struct e1000_ps_page *ps_page;
+
+       for (i = 0; i < adapter->rx_ps_pages; i++) {
+               ps_page = &bi->ps_pages[i];
+
+               if (ps_page->page) {
+                       pr_info("packet dump for ps_page %d:\n", i);
+                       print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
+                                      16, 1, page_address(ps_page->page),
+                                      PAGE_SIZE, true);
+               }
+       }
+}
+
 /*
  * e1000e_dump - Print registers, Tx-ring and Rx-ring
  */
@@ -299,10 +317,10 @@ static void e1000e_dump(struct e1000_adapter *adapter)
                        (unsigned long long)buffer_info->time_stamp,
                        buffer_info->skb, next_desc);
 
-               if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
+               if (netif_msg_pktdata(adapter) && buffer_info->skb)
                        print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
-                                      16, 1, phys_to_virt(buffer_info->dma),
-                                      buffer_info->length, true);
+                                      16, 1, buffer_info->skb->data,
+                                      buffer_info->skb->len, true);
        }
 
        /* Print Rx Ring Summary */
@@ -381,10 +399,8 @@ rx_ring_summary:
                                        buffer_info->skb, next_desc);
 
                                if (netif_msg_pktdata(adapter))
-                                       print_hex_dump(KERN_INFO, "",
-                                               DUMP_PREFIX_ADDRESS, 16, 1,
-                                               phys_to_virt(buffer_info->dma),
-                                               adapter->rx_ps_bsize0, true);
+                                       e1000e_dump_ps_pages(adapter,
+                                                            buffer_info);
                        }
                }
                break;
@@ -444,12 +460,12 @@ rx_ring_summary:
                                        (unsigned long long)buffer_info->dma,
                                        buffer_info->skb, next_desc);
 
-                               if (netif_msg_pktdata(adapter))
+                               if (netif_msg_pktdata(adapter) &&
+                                   buffer_info->skb)
                                        print_hex_dump(KERN_INFO, "",
                                                       DUMP_PREFIX_ADDRESS, 16,
                                                       1,
-                                                      phys_to_virt
-                                                      (buffer_info->dma),
+                                                      buffer_info->skb->data,
                                                       adapter->rx_buffer_len,
                                                       true);
                        }
index 5e84eaac48c191727d9ac733c80ffbb13ce1473f..ba994fb4cec69bc60baaff7c9407faf9553d40be 100644 (file)
@@ -254,6 +254,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
         */
        size += NVM_WORD_SIZE_BASE_SHIFT;
 
+       /*
+        * Check for invalid size
+        */
+       if ((hw->mac.type == e1000_82576) && (size > 15)) {
+               pr_notice("The NVM size is not valid, defaulting to 32K\n");
+               size = 15;
+       }
+
        nvm->word_size = 1 << size;
        if (hw->mac.type < e1000_i210) {
                nvm->opcode_bits        = 8;
@@ -281,14 +289,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
        } else
                nvm->type = e1000_nvm_flash_hw;
 
-       /*
-        * Check for invalid size
-        */
-       if ((hw->mac.type == e1000_82576) && (size > 15)) {
-               pr_notice("The NVM size is not valid, defaulting to 32K\n");
-               size = 15;
-       }
-
        /* NVM Function Pointers */
        switch (hw->mac.type) {
        case e1000_82580:
index 10efcd88dca00c81ef2539914851d25536447c78..28394bea5253fc280e1aba973b20958ed1b9662f 100644 (file)
                                    : (0x0E018 + ((_n) * 0x40)))
 #define E1000_TXDCTL(_n)  ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
                                    : (0x0E028 + ((_n) * 0x40)))
-#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
-#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
+#define E1000_RXCTL(_n)          ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \
+                                     (0x0C014 + ((_n) * 0x40)))
+#define E1000_DCA_RXCTRL(_n)   E1000_RXCTL(_n)
+#define E1000_TXCTL(_n)   ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \
+                                     (0x0E014 + ((_n) * 0x40)))
+#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n)
 #define E1000_TDWBAL(_n)  ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
                                    : (0x0E038 + ((_n) * 0x40)))
 #define E1000_TDWBAH(_n)  ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \
index a19c84cad0e991fc429b846b913f704e9cc41f30..70591117051bf2faa446af5a3b81055f091d491d 100644 (file)
@@ -209,8 +209,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
        /* When SoL/IDER sessions are active, autoneg/speed/duplex
         * cannot be changed */
        if (igb_check_reset_block(hw)) {
-               dev_err(&adapter->pdev->dev, "Cannot change link "
-                       "characteristics when SoL/IDER is active.\n");
+               dev_err(&adapter->pdev->dev,
+                       "Cannot change link characteristics when SoL/IDER is active.\n");
                return -EINVAL;
        }
 
@@ -1089,8 +1089,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
                wr32(reg, (_test[pat] & write));
                val = rd32(reg) & mask;
                if (val != (_test[pat] & write & mask)) {
-                       dev_err(&adapter->pdev->dev, "pattern test reg %04X "
-                               "failed: got 0x%08X expected 0x%08X\n",
+                       dev_err(&adapter->pdev->dev,
+                               "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n",
                                reg, val, (_test[pat] & write & mask));
                        *data = reg;
                        return 1;
@@ -1108,8 +1108,8 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
        wr32(reg, write & mask);
        val = rd32(reg);
        if ((write & mask) != (val & mask)) {
-               dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
-                       " got 0x%08X expected 0x%08X\n", reg,
+               dev_err(&adapter->pdev->dev,
+                       "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg,
                        (val & mask), (write & mask));
                *data = reg;
                return 1;
@@ -1171,8 +1171,9 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
        wr32(E1000_STATUS, toggle);
        after = rd32(E1000_STATUS) & toggle;
        if (value != after) {
-               dev_err(&adapter->pdev->dev, "failed STATUS register test "
-                       "got: 0x%08X expected: 0x%08X\n", after, value);
+               dev_err(&adapter->pdev->dev,
+                       "failed STATUS register test got: 0x%08X expected: 0x%08X\n",
+                       after, value);
                *data = 1;
                return 1;
        }
@@ -1497,6 +1498,9 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
                break;
        }
 
+       /* add small delay to avoid loopback test failure */
+       msleep(50);
+
        /* force 1000, set loopback */
        igb_write_phy_reg(hw, PHY_CONTROL, 0x4140);
 
@@ -1777,16 +1781,14 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data)
         * sessions are active */
        if (igb_check_reset_block(&adapter->hw)) {
                dev_err(&adapter->pdev->dev,
-                       "Cannot do PHY loopback test "
-                       "when SoL/IDER is active.\n");
+                       "Cannot do PHY loopback test when SoL/IDER is active.\n");
                *data = 0;
                goto out;
        }
        if ((adapter->hw.mac.type == e1000_i210)
-               || (adapter->hw.mac.type == e1000_i210)) {
+               || (adapter->hw.mac.type == e1000_i211)) {
                dev_err(&adapter->pdev->dev,
-                       "Loopback test not supported "
-                       "on this part at this time.\n");
+                       "Loopback test not supported on this part at this time.\n");
                *data = 0;
                goto out;
        }
index b7c2d5050572828c8d07e228b2e44235e9f01801..48cc4fb1a307f0d7c2821cc9f57c4c67d0ffc31b 100644 (file)
@@ -462,10 +462,10 @@ static void igb_dump(struct igb_adapter *adapter)
                                (u64)buffer_info->time_stamp,
                                buffer_info->skb, next_desc);
 
-                       if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
+                       if (netif_msg_pktdata(adapter) && buffer_info->skb)
                                print_hex_dump(KERN_INFO, "",
                                        DUMP_PREFIX_ADDRESS,
-                                       16, 1, phys_to_virt(buffer_info->dma),
+                                       16, 1, buffer_info->skb->data,
                                        buffer_info->length, true);
                }
        }
@@ -547,18 +547,17 @@ rx_ring_summary:
                                        (u64)buffer_info->dma,
                                        buffer_info->skb, next_desc);
 
-                               if (netif_msg_pktdata(adapter)) {
+                               if (netif_msg_pktdata(adapter) &&
+                                   buffer_info->dma && buffer_info->skb) {
                                        print_hex_dump(KERN_INFO, "",
-                                               DUMP_PREFIX_ADDRESS,
-                                               16, 1,
-                                               phys_to_virt(buffer_info->dma),
-                                               IGB_RX_HDR_LEN, true);
+                                                 DUMP_PREFIX_ADDRESS,
+                                                 16, 1, buffer_info->skb->data,
+                                                 IGB_RX_HDR_LEN, true);
                                        print_hex_dump(KERN_INFO, "",
                                          DUMP_PREFIX_ADDRESS,
                                          16, 1,
-                                         phys_to_virt(
-                                           buffer_info->page_dma +
-                                           buffer_info->page_offset),
+                                         page_address(buffer_info->page) +
+                                                     buffer_info->page_offset,
                                          PAGE_SIZE/2, true);
                                }
                        }
index 50fc137501da087d9cb73c1c924a0e9f85562c79..18bf08c9d7a4428e3a82f9f29a5837fddc3f6860 100644 (file)
@@ -804,12 +804,13 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
            link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
                /* Set KX4/KX/KR support according to speed requested */
                autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
-               if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+               if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
                        if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
                                autoc |= IXGBE_AUTOC_KX4_SUPP;
                        if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) &&
                            (hw->phy.smart_speed_active == false))
                                autoc |= IXGBE_AUTOC_KR_SUPP;
+               }
                if (speed & IXGBE_LINK_SPEED_1GB_FULL)
                        autoc |= IXGBE_AUTOC_KX_SUPP;
        } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) &&
index f32e703007702ba0652bca4bce23f7ac44287c14..5aba5ecdf1e28157fadf44072c87a4a98511d249 100644 (file)
@@ -614,8 +614,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                /* If source MAC is equal to our own MAC and not performing
                 * the selftest or flb disabled - drop the packet */
                if (s_mac == priv->mac &&
-                       (!(dev->features & NETIF_F_LOOPBACK) ||
-                        !priv->validate_loopback))
+                   !((dev->features & NETIF_F_LOOPBACK) ||
+                     priv->validate_loopback))
                        goto next;
 
                /*
index 019d856b1334fc4e7b389eb00d16da872d63ee4a..10bba09c44ea508d047123aeafb5e001b6bbd1be 100644 (file)
@@ -164,7 +164,6 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
        ring->cons = 0xffffffff;
        ring->last_nr_txbb = 1;
        ring->poll_cnt = 0;
-       ring->blocked = 0;
        memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info));
        memset(ring->buf, 0, ring->buf_size);
 
@@ -365,14 +364,13 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
        ring->cons += txbbs_skipped;
        netdev_tx_completed_queue(ring->tx_queue, packets, bytes);
 
-       /* Wakeup Tx queue if this ring stopped it */
-       if (unlikely(ring->blocked)) {
-               if ((u32) (ring->prod - ring->cons) <=
-                    ring->size - HEADROOM - MAX_DESC_TXBBS) {
-                       ring->blocked = 0;
-                       netif_tx_wake_queue(ring->tx_queue);
-                       priv->port_stats.wake_queue++;
-               }
+       /*
+        * Wakeup Tx queue if this stopped, and at least 1 packet
+        * was completed
+        */
+       if (netif_tx_queue_stopped(ring->tx_queue) && txbbs_skipped > 0) {
+               netif_tx_wake_queue(ring->tx_queue);
+               priv->port_stats.wake_queue++;
        }
 }
 
@@ -592,7 +590,6 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
                     ring->size - HEADROOM - MAX_DESC_TXBBS)) {
                /* every full Tx ring stops queue */
                netif_tx_stop_queue(ring->tx_queue);
-               ring->blocked = 1;
                priv->port_stats.queue_stopped++;
 
                return NETDEV_TX_BUSY;
index 88b7b3e75ab197706b3a1f0c7fa953e1f5f9da0b..daf41792366147c7381e9f8f7f1017489c55a57e 100644 (file)
@@ -358,13 +358,14 @@ void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
 }
 
 int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
-                       u64 virt, int obj_size, int nobj, int reserved,
+                       u64 virt, int obj_size, u32 nobj, int reserved,
                        int use_lowmem, int use_coherent)
 {
        int obj_per_chunk;
        int num_icm;
        unsigned chunk_size;
        int i;
+       u64 size;
 
        obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size;
        num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk;
@@ -380,10 +381,12 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
        table->coherent = use_coherent;
        mutex_init(&table->mutex);
 
+       size = (u64) nobj * obj_size;
        for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) {
                chunk_size = MLX4_TABLE_CHUNK_SIZE;
-               if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > nobj * obj_size)
-                       chunk_size = PAGE_ALIGN(nobj * obj_size - i * MLX4_TABLE_CHUNK_SIZE);
+               if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > size)
+                       chunk_size = PAGE_ALIGN(size -
+                                       i * MLX4_TABLE_CHUNK_SIZE);
 
                table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT,
                                               (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
index 19e4efc0b3429adb982b69c5366321385c8d3e05..a67744f53506af7f86c0de581445e1e67568de7f 100644 (file)
@@ -78,7 +78,7 @@ int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
 void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
                          int start, int end);
 int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
-                       u64 virt, int obj_size, int nobj, int reserved,
+                       u64 virt, int obj_size, u32 nobj, int reserved,
                        int use_lowmem, int use_coherent);
 void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table);
 void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle);
index 48d0e90194cb19d2a322990425b478f9e178b623..827b72dfce99690093f0fe81ee3ccf804d59db85 100644 (file)
@@ -157,9 +157,6 @@ int mlx4_check_port_params(struct mlx4_dev *dev,
                                         "on this HCA, aborting.\n");
                                return -EINVAL;
                        }
-                       if (port_type[i] == MLX4_PORT_TYPE_ETH &&
-                           port_type[i + 1] == MLX4_PORT_TYPE_IB)
-                               return -EINVAL;
                }
        }
 
index 4ec3835e1bc2cb8dd88958ce7a1276150898e86f..a018ea2a43deb9c67e773032e62d8a83f54bb3d9 100644 (file)
@@ -432,8 +432,10 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
                        if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) {
                                /* Entry already exists, add to duplicates */
                                dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
-                               if (!dqp)
+                               if (!dqp) {
+                                       err = -ENOMEM;
                                        goto out_mailbox;
+                               }
                                dqp->qpn = qpn;
                                list_add_tail(&dqp->list, &entry->duplicates);
                                found = true;
index 59ebc0339638a3c760f8b540d2066a7aaa7fa9cb..4d9df8f2a12617047355fc9988d5187af80a95f5 100644 (file)
@@ -249,7 +249,7 @@ struct mlx4_bitmap {
 struct mlx4_buddy {
        unsigned long         **bits;
        unsigned int           *num_free;
-       int                     max_order;
+       u32                     max_order;
        spinlock_t              lock;
 };
 
@@ -258,7 +258,7 @@ struct mlx4_icm;
 struct mlx4_icm_table {
        u64                     virt;
        int                     num_icm;
-       int                     num_obj;
+       u32                     num_obj;
        int                     obj_size;
        int                     lowmem;
        int                     coherent;
index 5f1ab105debc28b4b8ba7bdaca3f0bcb2f1cdb66..9d27e42264e2b64aea3827d760c409ab3de0c301 100644 (file)
@@ -248,7 +248,6 @@ struct mlx4_en_tx_ring {
        u32 doorbell_qpn;
        void *buf;
        u16 poll_cnt;
-       int blocked;
        struct mlx4_en_tx_info *tx_info;
        u8 *bounce_buf;
        u32 last_nr_txbb;
index af55b7ce53413cc27273b9102e609c0ae97d6169..c202d3ad2a0efbb6a852b18874414ba1036a1129 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/vmalloc.h>
 
 #include <linux/mlx4/cmd.h>
 
@@ -120,7 +121,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)
        buddy->max_order = max_order;
        spin_lock_init(&buddy->lock);
 
-       buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *),
+       buddy->bits = kcalloc(buddy->max_order + 1, sizeof (long *),
                              GFP_KERNEL);
        buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free,
                                  GFP_KERNEL);
@@ -129,10 +130,12 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)
 
        for (i = 0; i <= buddy->max_order; ++i) {
                s = BITS_TO_LONGS(1 << (buddy->max_order - i));
-               buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL);
-               if (!buddy->bits[i])
-                       goto err_out_free;
-               bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i));
+               buddy->bits[i] = kcalloc(s, sizeof (long), GFP_KERNEL | __GFP_NOWARN);
+               if (!buddy->bits[i]) {
+                       buddy->bits[i] = vzalloc(s * sizeof(long));
+                       if (!buddy->bits[i])
+                               goto err_out_free;
+               }
        }
 
        set_bit(0, buddy->bits[buddy->max_order]);
@@ -142,7 +145,10 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)
 
 err_out_free:
        for (i = 0; i <= buddy->max_order; ++i)
-               kfree(buddy->bits[i]);
+               if (buddy->bits[i] && is_vmalloc_addr(buddy->bits[i]))
+                       vfree(buddy->bits[i]);
+               else
+                       kfree(buddy->bits[i]);
 
 err_out:
        kfree(buddy->bits);
@@ -156,7 +162,10 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy)
        int i;
 
        for (i = 0; i <= buddy->max_order; ++i)
-               kfree(buddy->bits[i]);
+               if (is_vmalloc_addr(buddy->bits[i]))
+                       vfree(buddy->bits[i]);
+               else
+                       kfree(buddy->bits[i]);
 
        kfree(buddy->bits);
        kfree(buddy->num_free);
@@ -668,7 +677,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
                return err;
 
        err = mlx4_buddy_init(&mr_table->mtt_buddy,
-                             ilog2(dev->caps.num_mtts /
+                             ilog2((u32)dev->caps.num_mtts /
                              (1 << log_mtts_per_seg)));
        if (err)
                goto err_buddy;
@@ -678,7 +687,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
                        mlx4_alloc_mtt_range(dev,
                                             fls(dev->caps.reserved_mtts - 1));
                if (priv->reserved_mtts < 0) {
-                       mlx4_warn(dev, "MTT table of order %d is too small.\n",
+                       mlx4_warn(dev, "MTT table of order %u is too small.\n",
                                  mr_table->mtt_buddy.max_order);
                        err = -ENOMEM;
                        goto err_reserve_mtts;
index 9ee4725363d5d25d88135d2bbffb4d67a67023ab..8e0c3cc2a1ec786739de7298fc450c483d8fe37a 100644 (file)
@@ -76,7 +76,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
                u64 size;
                u64 start;
                int type;
-               int num;
+               u32 num;
                int log_num;
        };
 
@@ -105,7 +105,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
        si_meminfo(&si);
        request->num_mtt =
                roundup_pow_of_two(max_t(unsigned, request->num_mtt,
-                                        min(1UL << 31,
+                                        min(1UL << (31 - log_mtts_per_seg),
                                             si.totalram >> (log_mtts_per_seg - 1))));
 
        profile[MLX4_RES_QP].size     = dev_cap->qpc_entry_sz;
index 802498293528307b5c2e123eae089f84929759ea..34ee09bae36e98dcb28c8ff9b4c8d12a2da97292 100644 (file)
@@ -80,20 +80,6 @@ void mlx4_do_sense_ports(struct mlx4_dev *dev,
                        stype[i - 1] = defaults[i - 1];
        }
 
-       /*
-        * Adjust port configuration:
-        * If port 1 sensed nothing and port 2 is IB, set both as IB
-        * If port 2 sensed nothing and port 1 is Eth, set both as Eth
-        */
-       if (stype[0] == MLX4_PORT_TYPE_ETH) {
-               for (i = 1; i < dev->caps.num_ports; i++)
-                       stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH;
-       }
-       if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) {
-               for (i = 0; i < dev->caps.num_ports - 1; i++)
-                       stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB;
-       }
-
        /*
         * If sensed nothing, remain in current configuration.
         */
index 4069edab229e9a53cfc3bdec5256cf4cdbc573ae..53743f7a2ca9604d6f264de3a2e3c727556a0619 100644 (file)
@@ -346,28 +346,15 @@ static phy_interface_t lpc_phy_interface_mode(struct device *dev)
                                                   "phy-mode", NULL);
                if (mode && !strcmp(mode, "mii"))
                        return PHY_INTERFACE_MODE_MII;
-               return PHY_INTERFACE_MODE_RMII;
        }
-
-       /* non-DT */
-#ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT
-       return PHY_INTERFACE_MODE_MII;
-#else
        return PHY_INTERFACE_MODE_RMII;
-#endif
 }
 
 static bool use_iram_for_net(struct device *dev)
 {
        if (dev && dev->of_node)
                return of_property_read_bool(dev->of_node, "use-iram");
-
-       /* non-DT */
-#ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET
-       return true;
-#else
        return false;
-#endif
 }
 
 /* Receive Status information word */
index 46df3a04030c20af3a3288d7a27423b095694dfc..24c2305d7948455ca52ada710893599067533104 100644 (file)
@@ -8,7 +8,7 @@ config SH_ETH
                (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
                 CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
                 CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
-                CPU_SUBTYPE_SH7757 || ARCH_R8A7740)
+                CPU_SUBTYPE_SH7757 || ARCH_R8A7740 || ARCH_R8A7779)
        select CRC32
        select NET_CORE
        select MII
@@ -18,4 +18,4 @@ config SH_ETH
          Renesas SuperH Ethernet device driver.
          This driver supporting CPUs are:
                - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757,
-                 and R8A7740.
+                 R8A7740 and R8A7779.
index af0b867a6cf6247ccf4f002af29d5832c03f368b..bad8f2eec9b46f652298a3d9f0b48edbef1ac6b8 100644 (file)
@@ -78,7 +78,7 @@ static void sh_eth_select_mii(struct net_device *ndev)
 #endif
 
 /* There is CPU dependent code */
-#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+#if defined(CONFIG_CPU_SUBTYPE_SH7724) || defined(CONFIG_ARCH_R8A7779)
 #define SH_ETH_RESET_DEFAULT   1
 static void sh_eth_set_duplex(struct net_device *ndev)
 {
@@ -93,13 +93,18 @@ static void sh_eth_set_duplex(struct net_device *ndev)
 static void sh_eth_set_rate(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
+       unsigned int bits = ECMR_RTM;
+
+#if defined(CONFIG_ARCH_R8A7779)
+       bits |= ECMR_ELB;
+#endif
 
        switch (mdp->speed) {
        case 10: /* 10BASE */
-               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
+               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~bits, ECMR);
                break;
        case 100:/* 100BASE */
-               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
+               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | bits, ECMR);
                break;
        default:
                break;
index 70554a1b2b02dd37440db75ba06ec9eed8c84fe9..65a8d49106a4c63c6a7faf04c8e3334421ce6472 100644 (file)
@@ -1503,6 +1503,11 @@ static int efx_probe_all(struct efx_nic *efx)
                goto fail2;
        }
 
+       BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT);
+       if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) {
+               rc = -EINVAL;
+               goto fail3;
+       }
        efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
 
        rc = efx_probe_filters(efx);
@@ -2070,6 +2075,7 @@ static int efx_register_netdev(struct efx_nic *efx)
        net_dev->irq = efx->pci_dev->irq;
        net_dev->netdev_ops = &efx_netdev_ops;
        SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
+       net_dev->gso_max_segs = EFX_TSO_MAX_SEGS;
 
        rtnl_lock();
 
index be8f9158a7149388b5e4edfeb41ee2c848319a28..70755c97251aaab4e9cafe969b0a8b95821a1cbb 100644 (file)
@@ -30,6 +30,7 @@ extern netdev_tx_t
 efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
 extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
 extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc);
+extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
 
 /* RX */
 extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
@@ -52,10 +53,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
 #define EFX_MAX_EVQ_SIZE 16384UL
 #define EFX_MIN_EVQ_SIZE 512UL
 
-/* The smallest [rt]xq_entries that the driver supports. Callers of
- * efx_wake_queue() assume that they can subsequently send at least one
- * skb. Falcon/A1 may require up to three descriptors per skb_frag. */
-#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
+/* Maximum number of TCP segments we support for soft-TSO */
+#define EFX_TSO_MAX_SEGS       100
+
+/* The smallest [rt]xq_entries that the driver supports.  RX minimum
+ * is a bit arbitrary.  For TX, we must have space for at least 2
+ * TSO skbs.
+ */
+#define EFX_RXQ_MIN_ENT                128U
+#define EFX_TXQ_MIN_ENT(efx)   (2 * efx_tx_max_skb_descs(efx))
 
 /* Filters */
 extern int efx_probe_filters(struct efx_nic *efx);
index 10536f93b5611d15a22a56b3ca280e0f107ea828..8cba2df82b18b9f2dfa1ff82eee3b22ef9eeb0c9 100644 (file)
@@ -680,21 +680,27 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev,
                                     struct ethtool_ringparam *ring)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
+       u32 txq_entries;
 
        if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
            ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
            ring->tx_pending > EFX_MAX_DMAQ_SIZE)
                return -EINVAL;
 
-       if (ring->rx_pending < EFX_MIN_RING_SIZE ||
-           ring->tx_pending < EFX_MIN_RING_SIZE) {
+       if (ring->rx_pending < EFX_RXQ_MIN_ENT) {
                netif_err(efx, drv, efx->net_dev,
-                         "TX and RX queues cannot be smaller than %ld\n",
-                         EFX_MIN_RING_SIZE);
+                         "RX queues cannot be smaller than %u\n",
+                         EFX_RXQ_MIN_ENT);
                return -EINVAL;
        }
 
-       return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
+       txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx));
+       if (txq_entries != ring->tx_pending)
+               netif_warn(efx, drv, efx->net_dev,
+                          "increasing TX queue size to minimum of %u\n",
+                          txq_entries);
+
+       return efx_realloc_channels(efx, ring->rx_pending, txq_entries);
 }
 
 static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
index 9b225a7769f765a1f1bf3ef024ae3b73a18a66c2..18713436b44345a110ed263d54c5411d1e93c6fa 100644 (file)
@@ -119,6 +119,25 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr)
        return len;
 }
 
+unsigned int efx_tx_max_skb_descs(struct efx_nic *efx)
+{
+       /* Header and payload descriptor for each output segment, plus
+        * one for every input fragment boundary within a segment
+        */
+       unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS;
+
+       /* Possibly one more per segment for the alignment workaround */
+       if (EFX_WORKAROUND_5391(efx))
+               max_descs += EFX_TSO_MAX_SEGS;
+
+       /* Possibly more for PCIe page boundaries within input fragments */
+       if (PAGE_SIZE > EFX_PAGE_SIZE)
+               max_descs += max_t(unsigned int, MAX_SKB_FRAGS,
+                                  DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE));
+
+       return max_descs;
+}
+
 /*
  * Add a socket buffer to a TX queue
  *
index fd8882f9602afc43b6fe6ecd79a14defb5ac8dbe..c136162e6473e1746b48f50a0c7cc0adc57986d6 100644 (file)
@@ -2077,7 +2077,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
                goto error_netdev_register;
        }
 
-       priv->stmmac_clk = clk_get(priv->device, NULL);
+       priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
        if (IS_ERR(priv->stmmac_clk)) {
                pr_warning("%s: warning: cannot get CSR clock\n", __func__);
                goto error_clk_get;
index cd01ee7ecef19339c90765747a57b2d621765806..b93245c11995bc15329321e6879be78d4c1b44dc 100644 (file)
@@ -74,7 +74,7 @@ static int __devinit stmmac_probe_config_dt(struct platform_device *pdev,
  * the necessary resources and invokes the main to init
  * the net device, register the mdio bus etc.
  */
-static int stmmac_pltfr_probe(struct platform_device *pdev)
+static int __devinit stmmac_pltfr_probe(struct platform_device *pdev)
 {
        int ret = 0;
        struct resource *res;
index 3b5c4571b55e3c922a4b6e5a94a0a4a8adcb2fce..d15c888e9df8a15b02d104ace349c1926ad81107 100644 (file)
@@ -538,11 +538,12 @@ EXPORT_SYMBOL_GPL(cpdma_chan_create);
 
 int cpdma_chan_destroy(struct cpdma_chan *chan)
 {
-       struct cpdma_ctlr *ctlr = chan->ctlr;
+       struct cpdma_ctlr *ctlr;
        unsigned long flags;
 
        if (!chan)
                return -EINVAL;
+       ctlr = chan->ctlr;
 
        spin_lock_irqsave(&ctlr->lock, flags);
        if (chan->state != CPDMA_STATE_IDLE)
index 482648fcf0b6327bb9c482c1c36880ece1627caa..98934bdf6acffc053fcd317721e8d92cf649ba14 100644 (file)
@@ -1003,6 +1003,7 @@ static int ixp4xx_nway_reset(struct net_device *dev)
 }
 
 int ixp46x_phc_index = -1;
+EXPORT_SYMBOL_GPL(ixp46x_phc_index);
 
 static int ixp4xx_get_ts_info(struct net_device *dev,
                              struct ethtool_ts_info *info)
index 6cee2917eb0276369e6933ebf933c386167fa9a4..4a1a5f58fa73ffd7899429bcaf28062e29f83dc3 100644 (file)
@@ -383,13 +383,6 @@ int netvsc_device_remove(struct hv_device *device)
        unsigned long flags;
 
        net_device = hv_get_drvdata(device);
-       spin_lock_irqsave(&device->channel->inbound_lock, flags);
-       net_device->destroy = true;
-       spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
-
-       /* Wait for all send completions */
-       wait_event(net_device->wait_drain,
-                  atomic_read(&net_device->num_outstanding_sends) == 0);
 
        netvsc_disconnect_vsp(net_device);
 
index e5d6146937fa0aade2476662ce87084b7337187c..1e88a1095934a6d7b62c84cf1fff0e083f088881 100644 (file)
@@ -718,6 +718,9 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
 {
        struct rndis_request *request;
        struct rndis_halt_request *halt;
+       struct netvsc_device *nvdev = dev->net_dev;
+       struct hv_device *hdev = nvdev->dev;
+       ulong flags;
 
        /* Attempt to do a rndis device halt */
        request = get_rndis_request(dev, RNDIS_MSG_HALT,
@@ -735,6 +738,14 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
        dev->state = RNDIS_DEV_UNINITIALIZED;
 
 cleanup:
+       spin_lock_irqsave(&hdev->channel->inbound_lock, flags);
+       nvdev->destroy = true;
+       spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
+
+       /* Wait for all send completions */
+       wait_event(nvdev->wait_drain,
+               atomic_read(&nvdev->num_outstanding_sends) == 0);
+
        if (request)
                put_rndis_request(dev, request);
        return;
index a561ae44a9ac1c982b1d5390a6f288abe0094523..c6a0299aa9f912241e6b544727df47913b01db1d 100644 (file)
@@ -158,7 +158,7 @@ static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed)
        /* If not add the 'RPOLC', we can't catch the receive interrupt.
         * It's related with the HW layout and the IR transiver.
         */
-       val |= IREN | RPOLC;
+       val |= UMOD_IRDA | RPOLC;
        UART_PUT_GCTL(port, val);
        return ret;
 }
@@ -432,7 +432,7 @@ static void bfin_sir_shutdown(struct bfin_sir_port *port, struct net_device *dev
        bfin_sir_stop_rx(port);
 
        val = UART_GET_GCTL(port);
-       val &= ~(UCEN | IREN | RPOLC);
+       val &= ~(UCEN | UMOD_MASK | RPOLC);
        UART_PUT_GCTL(port, val);
 
 #ifdef CONFIG_SIR_BFIN_DMA
@@ -518,10 +518,10 @@ static void bfin_sir_send_work(struct work_struct *work)
         * reset all the UART.
         */
        val = UART_GET_GCTL(port);
-       val &= ~(IREN | RPOLC);
+       val &= ~(UMOD_MASK | RPOLC);
        UART_PUT_GCTL(port, val);
        SSYNC();
-       val |= IREN | RPOLC;
+       val |= UMOD_IRDA | RPOLC;
        UART_PUT_GCTL(port, val);
        SSYNC();
        /* bfin_sir_set_speed(port, self->speed); */
index 824e2a93fe8a68d0228897828a51a010e9a8306b..5f3aeac3f86df57e297b1559a5bda2b7669145a9 100644 (file)
@@ -542,6 +542,7 @@ static int ks959_net_open(struct net_device *netdev)
        sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
        kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
        if (!kingsun->irlap) {
+               err = -ENOMEM;
                dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
                goto free_mem;
        }
index 5a278ab83c2f040e3ac0f8427f6744b15e42de26..2d4b6a1ab2029b0d2267cf967931e47c84796123 100644 (file)
@@ -436,6 +436,7 @@ static int ksdazzle_net_open(struct net_device *netdev)
        sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
        kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
        if (!kingsun->irlap) {
+               err = -ENOMEM;
                dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
                goto free_mem;
        }
index 0737bd4d16696e4a90475a124f17568f87eb2c14..0f0f9ce3a7769ec552cc9f01f1915b44e44958fe 100644 (file)
@@ -94,7 +94,8 @@ static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q)
        int i;
 
        for (i = 0; i < MAX_MACVTAP_QUEUES; i++) {
-               if (rcu_dereference(vlan->taps[i]) == q)
+               if (rcu_dereference_protected(vlan->taps[i],
+                                             lockdep_is_held(&macvtap_lock)) == q)
                        return i;
        }
 
index f9347ea3d381e113d20c6a13ec32f0f51c5fc04c..b3321129a83c6dc33180fbbb07aadad296f14554 100644 (file)
@@ -640,15 +640,9 @@ static int netconsole_netdev_event(struct notifier_block *this,
                                 * rtnl_lock already held
                                 */
                                if (nt->np.dev) {
-                                       spin_unlock_irqrestore(
-                                                             &target_list_lock,
-                                                             flags);
                                        __netpoll_cleanup(&nt->np);
-                                       spin_lock_irqsave(&target_list_lock,
-                                                         flags);
                                        dev_put(nt->np.dev);
                                        nt->np.dev = NULL;
-                                       netconsole_target_put(nt);
                                }
                                nt->enabled = 0;
                                stopped = true;
index e0cc4ef33dee2b035ee576ecbb17196984925d74..eefe49e8713ca633c8383b1c388826f45e5c9e0c 100644 (file)
@@ -101,7 +101,6 @@ err:
                n--;
                gpio_free(s->gpio[n]);
        }
-       devm_kfree(&pdev->dev, s);
        return r;
 }
 
index 5c120189ec86d419866b7320c36f4d618dc5df64..4d4d25efc1e10a2b87e3c8ab993ae3ba6167a7dd 100644 (file)
@@ -132,7 +132,7 @@ int mdio_mux_init(struct device *dev,
        pb->mii_bus = parent_bus;
 
        ret_val = -ENODEV;
-       for_each_child_of_node(dev->of_node, child_bus_node) {
+       for_each_available_child_of_node(dev->of_node, child_bus_node) {
                u32 v;
 
                r = of_property_read_u32(child_bus_node, "reg", &v);
index 1c98321b56cc1547eb105b39758d2663e54de3ae..162464fe86bf7634fb9ac6c21ecd76e25beb10b6 100644 (file)
@@ -189,7 +189,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        if (sk_pppox(po)->sk_state & PPPOX_DEAD)
                goto tx_error;
 
-       rt = ip_route_output_ports(&init_net, &fl4, NULL,
+       rt = ip_route_output_ports(sock_net(sk), &fl4, NULL,
                                   opt->dst_addr.sin_addr.s_addr,
                                   opt->src_addr.sin_addr.s_addr,
                                   0, 0, IPPROTO_GRE,
@@ -468,7 +468,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
        po->chan.private = sk;
        po->chan.ops = &pptp_chan_ops;
 
-       rt = ip_route_output_ports(&init_net, &fl4, sk,
+       rt = ip_route_output_ports(sock_net(sk), &fl4, sk,
                                   opt->dst_addr.sin_addr.s_addr,
                                   opt->src_addr.sin_addr.s_addr,
                                   0, 0,
index 87707ab3943084821e1b7e5c5b9a201d51a944ba..341b65dbbcd324d9512f957fc7b663481a073aea 100644 (file)
@@ -795,16 +795,17 @@ static void team_port_leave(struct team *team, struct team_port *port)
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
+static int team_port_enable_netpoll(struct team *team, struct team_port *port,
+                                   gfp_t gfp)
 {
        struct netpoll *np;
        int err;
 
-       np = kzalloc(sizeof(*np), GFP_KERNEL);
+       np = kzalloc(sizeof(*np), gfp);
        if (!np)
                return -ENOMEM;
 
-       err = __netpoll_setup(np, port->dev);
+       err = __netpoll_setup(np, port->dev, gfp);
        if (err) {
                kfree(np);
                return err;
@@ -833,7 +834,8 @@ static struct netpoll_info *team_netpoll_info(struct team *team)
 }
 
 #else
-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
+static int team_port_enable_netpoll(struct team *team, struct team_port *port,
+                                   gfp_t gfp)
 {
        return 0;
 }
@@ -913,7 +915,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
        }
 
        if (team_netpoll_info(team)) {
-               err = team_port_enable_netpoll(team, port);
+               err = team_port_enable_netpoll(team, port, GFP_KERNEL);
                if (err) {
                        netdev_err(dev, "Failed to enable netpoll on device %s\n",
                                   portname);
@@ -1443,7 +1445,7 @@ static void team_netpoll_cleanup(struct net_device *dev)
 }
 
 static int team_netpoll_setup(struct net_device *dev,
-                             struct netpoll_info *npifo)
+                             struct netpoll_info *npifo, gfp_t gfp)
 {
        struct team *team = netdev_priv(dev);
        struct team_port *port;
@@ -1451,7 +1453,7 @@ static int team_netpoll_setup(struct net_device *dev,
 
        mutex_lock(&team->lock);
        list_for_each_entry(port, &team->port_list, list) {
-               err = team_port_enable_netpoll(team, port);
+               err = team_port_enable_netpoll(team, port, gfp);
                if (err) {
                        __team_netpoll_cleanup(team);
                        break;
index 926d4db5cb384f2de6df5ae871d0ec6171c6fe7d..3a16d4fdaa052817135c885b23cb28d90d872ec6 100644 (file)
@@ -187,7 +187,6 @@ static void __tun_detach(struct tun_struct *tun)
        netif_tx_lock_bh(tun->dev);
        netif_carrier_off(tun->dev);
        tun->tfile = NULL;
-       tun->socket.file = NULL;
        netif_tx_unlock_bh(tun->dev);
 
        /* Drop read queue */
index 64610048ce87c178770059b163395a285cb69e77..7d78669000d704d8448aea5e24a8a73c312badfc 100644 (file)
@@ -232,6 +232,7 @@ static int usbpn_open(struct net_device *dev)
                struct urb *req = usb_alloc_urb(0, GFP_KERNEL);
 
                if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) {
+                       usb_free_urb(req);
                        usbpn_close(dev);
                        return -ENOMEM;
                }
index f4ce5957df326bb94131031fabdb1daf6dcabf42..4cd582a4f625d55d5edd8c2cd3952d5571074921 100644 (file)
@@ -1225,6 +1225,26 @@ static const struct usb_device_id cdc_devs[] = {
          .driver_info = (unsigned long) &wwan_info,
        },
 
+       /* Dell branded MBM devices like DW5550 */
+       { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+               | USB_DEVICE_ID_MATCH_VENDOR,
+         .idVendor = 0x413c,
+         .bInterfaceClass = USB_CLASS_COMM,
+         .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM,
+         .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+         .driver_info = (unsigned long) &wwan_info,
+       },
+
+       /* Toshiba branded MBM devices */
+       { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+               | USB_DEVICE_ID_MATCH_VENDOR,
+         .idVendor = 0x0930,
+         .bInterfaceClass = USB_CLASS_COMM,
+         .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM,
+         .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+         .driver_info = (unsigned long) &wwan_info,
+       },
+
        /* Generic CDC-NCM devices */
        { USB_INTERFACE_INFO(USB_CLASS_COMM,
                USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
index 2ea126a16d79add1f5271e8848942ffc2a755b37..328397c66730cae37a9c1cdc02cdb7dde523e2b3 100644 (file)
@@ -247,30 +247,12 @@ err:
  */
 static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf)
 {
-       int rv;
        struct qmi_wwan_state *info = (void *)&dev->data;
 
-       /* ZTE makes devices where the interface descriptors and endpoint
-        * configurations of two or more interfaces are identical, even
-        * though the functions are completely different.  If set, then
-        * driver_info->data is a bitmap of acceptable interface numbers
-        * allowing us to bind to one such interface without binding to
-        * all of them
-        */
-       if (dev->driver_info->data &&
-           !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) {
-               dev_info(&intf->dev, "not on our whitelist - ignored");
-               rv = -ENODEV;
-               goto err;
-       }
-
        /*  control and data is shared */
        info->control = intf;
        info->data = intf;
-       rv = qmi_wwan_register_subdriver(dev);
-
-err:
-       return rv;
+       return qmi_wwan_register_subdriver(dev);
 }
 
 static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
@@ -356,214 +338,64 @@ static const struct driver_info  qmi_wwan_shared = {
        .manage_power   = qmi_wwan_manage_power,
 };
 
-static const struct driver_info        qmi_wwan_force_int0 = {
-       .description    = "Qualcomm WWAN/QMI device",
-       .flags          = FLAG_WWAN,
-       .bind           = qmi_wwan_bind_shared,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-       .data           = BIT(0), /* interface whitelist bitmap */
-};
-
-static const struct driver_info        qmi_wwan_force_int1 = {
-       .description    = "Qualcomm WWAN/QMI device",
-       .flags          = FLAG_WWAN,
-       .bind           = qmi_wwan_bind_shared,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-       .data           = BIT(1), /* interface whitelist bitmap */
-};
-
-static const struct driver_info qmi_wwan_force_int2 = {
-       .description    = "Qualcomm WWAN/QMI device",
-       .flags          = FLAG_WWAN,
-       .bind           = qmi_wwan_bind_shared,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-       .data           = BIT(2), /* interface whitelist bitmap */
-};
-
-static const struct driver_info        qmi_wwan_force_int3 = {
-       .description    = "Qualcomm WWAN/QMI device",
-       .flags          = FLAG_WWAN,
-       .bind           = qmi_wwan_bind_shared,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-       .data           = BIT(3), /* interface whitelist bitmap */
-};
-
-static const struct driver_info        qmi_wwan_force_int4 = {
-       .description    = "Qualcomm WWAN/QMI device",
-       .flags          = FLAG_WWAN,
-       .bind           = qmi_wwan_bind_shared,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-       .data           = BIT(4), /* interface whitelist bitmap */
-};
-
-/* Sierra Wireless provide equally useless interface descriptors
- * Devices in QMI mode can be switched between two different
- * configurations:
- *   a) USB interface #8 is QMI/wwan
- *   b) USB interfaces #8, #19 and #20 are QMI/wwan
- *
- * Both configurations provide a number of other interfaces (serial++),
- * some of which have the same endpoint configuration as we expect, so
- * a whitelist or blacklist is necessary.
- *
- * FIXME: The below whitelist should include BIT(20).  It does not
- * because I cannot get it to work...
- */
-static const struct driver_info        qmi_wwan_sierra = {
-       .description    = "Sierra Wireless wwan/QMI device",
-       .flags          = FLAG_WWAN,
-       .bind           = qmi_wwan_bind_shared,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-       .data           = BIT(8) | BIT(19), /* interface whitelist bitmap */
-};
-
 #define HUAWEI_VENDOR_ID       0x12D1
 
+/* map QMI/wwan function by a fixed interface number */
+#define QMI_FIXED_INTF(vend, prod, num) \
+       USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \
+       .driver_info = (unsigned long)&qmi_wwan_shared
+
 /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
 #define QMI_GOBI1K_DEVICE(vend, prod) \
-       USB_DEVICE(vend, prod), \
-       .driver_info = (unsigned long)&qmi_wwan_force_int3
+       QMI_FIXED_INTF(vend, prod, 3)
 
-/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */
+/* Gobi 2000/3000 QMI/wwan interface number is 0 according to qcserial */
 #define QMI_GOBI_DEVICE(vend, prod) \
-       USB_DEVICE(vend, prod), \
-       .driver_info = (unsigned long)&qmi_wwan_force_int0
+       QMI_FIXED_INTF(vend, prod, 0)
 
 static const struct usb_device_id products[] = {
+       /* 1. CDC ECM like devices match on the control interface */
        {       /* Huawei E392, E398 and possibly others sharing both device id and more... */
-               .match_flags        = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = HUAWEI_VENDOR_ID,
-               .bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
-               .bInterfaceSubClass = 1,
-               .bInterfaceProtocol = 9, /* CDC Ethernet *control* interface */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 9),
                .driver_info        = (unsigned long)&qmi_wwan_info,
        },
        {       /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */
-               .match_flags        = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = HUAWEI_VENDOR_ID,
-               .bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
-               .bInterfaceSubClass = 1,
-               .bInterfaceProtocol = 57, /* CDC Ethernet *control* interface */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57),
                .driver_info        = (unsigned long)&qmi_wwan_info,
        },
-       {       /* Huawei E392, E398 and possibly others in "Windows mode"
-                * using a combined control and data interface without any CDC
-                * functional descriptors
-                */
-               .match_flags        = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = HUAWEI_VENDOR_ID,
-               .bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
-               .bInterfaceSubClass = 1,
-               .bInterfaceProtocol = 17,
+
+       /* 2. Combined interface devices matching on class+protocol */
+       {       /* Huawei E392, E398 and possibly others in "Windows mode" */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
        {       /* Pantech UML290 */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x106c,
-               .idProduct          = 0x3718,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xf0,
-               .bInterfaceProtocol = 0xff,
+               USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
-       {       /* ZTE MF820D */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x0167,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
-       },
-       {       /* ZTE MF821D */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x0326,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
-       },
-       {       /* ZTE (Vodafone) K3520-Z */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x0055,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int1,
-       },
-       {       /* ZTE (Vodafone) K3565-Z */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x0063,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
-       },
-       {       /* ZTE (Vodafone) K3570-Z */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x1008,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
-       },
-       {       /* ZTE (Vodafone) K3571-Z */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x1010,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
-       },
-       {       /* ZTE (Vodafone) K3765-Z */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x2002,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
-       },
-       {       /* ZTE (Vodafone) K4505-Z */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x0104,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
-       },
-       {       /* ZTE MF60 */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x19d2,
-               .idProduct          = 0x1402,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_force_int2,
-       },
-       {       /* Sierra Wireless MC77xx in QMI mode */
-               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = 0x1199,
-               .idProduct          = 0x68a2,
-               .bInterfaceClass    = 0xff,
-               .bInterfaceSubClass = 0xff,
-               .bInterfaceProtocol = 0xff,
-               .driver_info        = (unsigned long)&qmi_wwan_sierra,
+       {       /* Pantech UML290 - newer firmware */
+               USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff),
+               .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
 
-       /* Gobi 1000 devices */
+       /* 3. Combined interface devices matching on interface number */
+       {QMI_FIXED_INTF(0x19d2, 0x0055, 1)},    /* ZTE (Vodafone) K3520-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x0063, 4)},    /* ZTE (Vodafone) K3565-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x0104, 4)},    /* ZTE (Vodafone) K4505-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x0167, 4)},    /* ZTE MF820D */
+       {QMI_FIXED_INTF(0x19d2, 0x0326, 4)},    /* ZTE MF821D */
+       {QMI_FIXED_INTF(0x19d2, 0x1008, 4)},    /* ZTE (Vodafone) K3570-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x1010, 4)},    /* ZTE (Vodafone) K3571-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x1018, 3)},    /* ZTE (Vodafone) K5006-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x1402, 2)},    /* ZTE MF60 */
+       {QMI_FIXED_INTF(0x19d2, 0x2002, 4)},    /* ZTE (Vodafone) K3765-Z */
+       {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)},    /* Sierra Wireless MC7700 */
+       {QMI_FIXED_INTF(0x114f, 0x68a2, 8)},    /* Sierra Wireless MC7750 */
+       {QMI_FIXED_INTF(0x1199, 0x68a2, 8)},    /* Sierra Wireless MC7710 in QMI mode */
+       {QMI_FIXED_INTF(0x1199, 0x68a2, 19)},   /* Sierra Wireless MC7710 in QMI mode */
+       {QMI_FIXED_INTF(0x1199, 0x901c, 8)},    /* Sierra Wireless EM7700 */
+
+       /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
        {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)},    /* HP un2400 Gobi Modem Device */
        {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)},    /* HP un2430 Mobile Broadband Module */
@@ -579,7 +411,7 @@ static const struct usb_device_id products[] = {
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)},    /* Generic Gobi Modem device */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)},    /* Generic Gobi Modem device */
 
-       /* Gobi 2000 and 3000 devices */
+       /* 5. Gobi 2000 and 3000 devices */
        {QMI_GOBI_DEVICE(0x413c, 0x8186)},      /* Dell Gobi 2000 Modem device (N0218, VU936) */
        {QMI_GOBI_DEVICE(0x05c6, 0x920b)},      /* Generic Gobi 2000 Modem device */
        {QMI_GOBI_DEVICE(0x05c6, 0x9225)},      /* Sony Gobi 2000 Modem device (N0279, VU730) */
@@ -589,6 +421,8 @@ static const struct usb_device_id products[] = {
        {QMI_GOBI_DEVICE(0x05c6, 0x9265)},      /* Asus Gobi 2000 Modem device (VR305) */
        {QMI_GOBI_DEVICE(0x05c6, 0x9235)},      /* Top Global Gobi 2000 Modem device (VR306) */
        {QMI_GOBI_DEVICE(0x05c6, 0x9275)},      /* iRex Technologies Gobi 2000 Modem device (VR307) */
+       {QMI_GOBI_DEVICE(0x1199, 0x68a5)},      /* Sierra Wireless Modem */
+       {QMI_GOBI_DEVICE(0x1199, 0x68a9)},      /* Sierra Wireless Modem */
        {QMI_GOBI_DEVICE(0x1199, 0x9001)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
        {QMI_GOBI_DEVICE(0x1199, 0x9002)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
        {QMI_GOBI_DEVICE(0x1199, 0x9003)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
@@ -600,11 +434,14 @@ static const struct usb_device_id products[] = {
        {QMI_GOBI_DEVICE(0x1199, 0x9009)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
        {QMI_GOBI_DEVICE(0x1199, 0x900a)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
        {QMI_GOBI_DEVICE(0x1199, 0x9011)},      /* Sierra Wireless Gobi 2000 Modem device (MC8305) */
+       {QMI_FIXED_INTF(0x1199, 0x9011, 5)},    /* alternate interface number!? */
        {QMI_GOBI_DEVICE(0x16d8, 0x8002)},      /* CMDTech Gobi 2000 Modem device (VU922) */
        {QMI_GOBI_DEVICE(0x05c6, 0x9205)},      /* Gobi 2000 Modem device */
        {QMI_GOBI_DEVICE(0x1199, 0x9013)},      /* Sierra Wireless Gobi 3000 Modem device (MC8355) */
        {QMI_GOBI_DEVICE(0x1199, 0x9015)},      /* Sierra Wireless Gobi 3000 Modem device */
        {QMI_GOBI_DEVICE(0x1199, 0x9019)},      /* Sierra Wireless Gobi 3000 Modem device */
+       {QMI_GOBI_DEVICE(0x1199, 0x901b)},      /* Sierra Wireless MC7770 */
+
        { }                                     /* END */
 };
 MODULE_DEVICE_TABLE(usb, products);
index d75d1f56becff95ae9cf7b8f8dc08990d142d06c..7be49ea60b6d8f9353720d757f47c2c61b16fc60 100644 (file)
@@ -68,15 +68,8 @@ static       atomic_t iface_counter = ATOMIC_INIT(0);
  */
 #define SIERRA_NET_USBCTL_BUF_LEN      1024
 
-/* list of interface numbers - used for constructing interface lists */
-struct sierra_net_iface_info {
-       const u32 infolen;      /* number of interface numbers on list */
-       const u8  *ifaceinfo;   /* pointer to the array holding the numbers */
-};
-
 struct sierra_net_info_data {
        u16 rx_urb_size;
-       struct sierra_net_iface_info whitelist;
 };
 
 /* Private data structure */
@@ -637,21 +630,6 @@ static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
        return usbnet_change_mtu(net, new_mtu);
 }
 
-static int is_whitelisted(const u8 ifnum,
-                       const struct sierra_net_iface_info *whitelist)
-{
-       if (whitelist) {
-               const u8 *list = whitelist->ifaceinfo;
-               int i;
-
-               for (i = 0; i < whitelist->infolen; i++) {
-                       if (list[i] == ifnum)
-                               return 1;
-               }
-       }
-       return 0;
-}
-
 static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
 {
        int result = 0;
@@ -706,11 +684,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
        dev_dbg(&dev->udev->dev, "%s", __func__);
 
        ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
-       /* We only accept certain interfaces */
-       if (!is_whitelisted(ifacenum, &data->whitelist)) {
-               dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
-               return -ENODEV;
-       }
        numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
        /* We have three endpoints, bulk in and out, and a status */
        if (numendpoints != 3) {
@@ -945,13 +918,8 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
        return NULL;
 }
 
-static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
 static const struct sierra_net_info_data sierra_net_info_data_direct_ip = {
        .rx_urb_size = 8 * 1024,
-       .whitelist = {
-               .infolen = ARRAY_SIZE(sierra_net_ifnum_list),
-               .ifaceinfo = sierra_net_ifnum_list
-       }
 };
 
 static const struct driver_info sierra_net_info_direct_ip = {
@@ -965,15 +933,19 @@ static const struct driver_info sierra_net_info_direct_ip = {
        .data = (unsigned long)&sierra_net_info_data_direct_ip,
 };
 
+#define DIRECT_IP_DEVICE(vend, prod) \
+       {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \
+       .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \
+       {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 10), \
+       .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \
+       {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 11), \
+       .driver_info = (unsigned long)&sierra_net_info_direct_ip}
+
 static const struct usb_device_id products[] = {
-       {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
-       .driver_info = (unsigned long) &sierra_net_info_direct_ip},
-       {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */
-       .driver_info = (unsigned long) &sierra_net_info_direct_ip},
-       {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */
-       .driver_info = (unsigned long) &sierra_net_info_direct_ip},
-       {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */
-       .driver_info = (unsigned long) &sierra_net_info_direct_ip},
+       DIRECT_IP_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
+       DIRECT_IP_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */
+       DIRECT_IP_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */
+       DIRECT_IP_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */
 
        {}, /* last item */
 };
index 93e0cfb739b89b3f53964e6596c5b36e804b4a1b..ce9d4f2c9776e08d1b543f18de8cb7100fe43a86 100644 (file)
@@ -3019,6 +3019,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
        netdev->watchdog_timeo = 5 * HZ;
 
        INIT_WORK(&adapter->work, vmxnet3_reset_work);
+       set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
 
        if (adapter->intr.type == VMXNET3_IT_MSIX) {
                int i;
@@ -3043,7 +3044,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
                goto err_register;
        }
 
-       set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
        vmxnet3_check_link(adapter, false);
        atomic_inc(&devices_found);
        return 0;
index 9eb6479306d699dba13c63124a41a64f07b616ec..ef36cafd44b72138436ce3175dd5dfca7d184082 100644 (file)
@@ -774,14 +774,15 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
        }
        /* Global interrupt queue */
        writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1);
+
+       rc = -ENOMEM;
+
        priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev,
                IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma);
        if (!priv->iqcfg)
                goto err_free_irq_5;
        writel(priv->iqcfg_dma, ioaddr + IQCFG);
 
-       rc = -ENOMEM;
-
        /*
         * SCC 0-3 private rx/tx irq structures
         * IQRX/TXi needs to be set soon. Learned it the hard way...
index 283237f6f074a775b5ce82d6db1a64459168cfaf..def12b38cbf7002d27b83253c3be238e7e7f0802 100644 (file)
@@ -326,8 +326,10 @@ int i2400m_barker_db_init(const char *_options)
                unsigned barker;
 
                options_orig = kstrdup(_options, GFP_KERNEL);
-               if (options_orig == NULL)
+               if (options_orig == NULL) {
+                       result = -ENOMEM;
                        goto error_parse;
+               }
                options = options_orig;
 
                while ((token = strsep(&options, ",")) != NULL) {
index efc162e0b511c6d67ecdd4d011caa84c84708b8b..88b8d64c90f1b49a302deaca3af07788ee4b27c1 100644 (file)
@@ -342,7 +342,7 @@ static int at76_dfu_get_status(struct usb_device *udev,
        return ret;
 }
 
-static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
+static int at76_dfu_get_state(struct usb_device *udev, u8 *state)
 {
        int ret;
 
index 8c4c040a47b8cf69e75b4f022dafc3542f2ae908..2aab20ee9f387f8c89289ca409e6ead0fa83722c 100644 (file)
@@ -2056,9 +2056,7 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf)
 void
 ath5k_beacon_config(struct ath5k_hw *ah)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&ah->block, flags);
+       spin_lock_bh(&ah->block);
        ah->bmisscount = 0;
        ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
 
@@ -2085,7 +2083,7 @@ ath5k_beacon_config(struct ath5k_hw *ah)
 
        ath5k_hw_set_imr(ah, ah->imask);
        mmiowb();
-       spin_unlock_irqrestore(&ah->block, flags);
+       spin_unlock_bh(&ah->block);
 }
 
 static void ath5k_tasklet_beacon(unsigned long data)
index 260e7dc7f7512af8442f957e2b4e6b2985355237..d56453e43d7e353e0890d3962e264448d7185771 100644 (file)
@@ -254,7 +254,6 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct ath5k_vif *avf = (void *)vif->drv_priv;
        struct ath5k_hw *ah = hw->priv;
        struct ath_common *common = ath5k_hw_common(ah);
-       unsigned long flags;
 
        mutex_lock(&ah->lock);
 
@@ -300,9 +299,9 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        }
 
        if (changes & BSS_CHANGED_BEACON) {
-               spin_lock_irqsave(&ah->block, flags);
+               spin_lock_bh(&ah->block);
                ath5k_beacon_update(hw, vif);
-               spin_unlock_irqrestore(&ah->block, flags);
+               spin_unlock_bh(&ah->block);
        }
 
        if (changes & BSS_CHANGED_BEACON_ENABLED)
index cfa91ab7acf8b1fd7c4b29fab82cb812f6423d5d..60b6a9daff7e21cde68fb6eda800e4ca065c62aa 100644 (file)
@@ -730,6 +730,7 @@ int ath9k_hw_init(struct ath_hw *ah)
        case AR9300_DEVID_QCA955X:
        case AR9300_DEVID_AR9580:
        case AR9300_DEVID_AR9462:
+       case AR9485_DEVID_AR1111:
                break;
        default:
                if (common->bus_ops->ath_bus_type == ATH_USB)
index dd0c146d81dccd77d1d735db888884be6227c782..ce7332c64efb2c5b417cd40fec2428522186142a 100644 (file)
@@ -49,6 +49,7 @@
 #define AR9300_DEVID_AR9462    0x0034
 #define AR9300_DEVID_AR9330    0x0035
 #define AR9300_DEVID_QCA955X   0x0038
+#define AR9485_DEVID_AR1111    0x0037
 
 #define AR5416_AR9100_DEVID    0x000b
 
index 7990cd55599cd319a51537ed0ad1981b6edf9a4b..b42be910a83dc94845fa6be33370357b18416e2f 100644 (file)
@@ -773,15 +773,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_intrpend);
 
-void ath9k_hw_disable_interrupts(struct ath_hw *ah)
+void ath9k_hw_kill_interrupts(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
 
-       if (!(ah->imask & ATH9K_INT_GLOBAL))
-               atomic_set(&ah->intr_ref_cnt, -1);
-       else
-               atomic_dec(&ah->intr_ref_cnt);
-
        ath_dbg(common, INTERRUPT, "disable IER\n");
        REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
        (void) REG_READ(ah, AR_IER);
@@ -793,6 +788,17 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
                (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
        }
 }
+EXPORT_SYMBOL(ath9k_hw_kill_interrupts);
+
+void ath9k_hw_disable_interrupts(struct ath_hw *ah)
+{
+       if (!(ah->imask & ATH9K_INT_GLOBAL))
+               atomic_set(&ah->intr_ref_cnt, -1);
+       else
+               atomic_dec(&ah->intr_ref_cnt);
+
+       ath9k_hw_kill_interrupts(ah);
+}
 EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
 
 void ath9k_hw_enable_interrupts(struct ath_hw *ah)
index 0eba36dca6f8fe897dcbbdc56cd0318af46f4fba..4a745e68dd941d9351e4fe911b47d76ec288551d 100644 (file)
@@ -738,6 +738,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah);
 void ath9k_hw_set_interrupts(struct ath_hw *ah);
 void ath9k_hw_enable_interrupts(struct ath_hw *ah);
 void ath9k_hw_disable_interrupts(struct ath_hw *ah);
+void ath9k_hw_kill_interrupts(struct ath_hw *ah);
 
 void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
 
index 6049d8b82855a7542192b247657e58964fc9f496..a22df749b8db3d8641b4ef8cb78ad99b9e34adbb 100644 (file)
@@ -462,8 +462,10 @@ irqreturn_t ath_isr(int irq, void *dev)
        if (!ath9k_hw_intrpend(ah))
                return IRQ_NONE;
 
-       if(test_bit(SC_OP_HW_RESET, &sc->sc_flags))
+       if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) {
+               ath9k_hw_kill_interrupts(ah);
                return IRQ_HANDLED;
+       }
 
        /*
         * Figure out the reason(s) for the interrupt.  Note
index 87b89d55e637758febf06629599ebe9e60478b85..a978984d78a53e93b5148ed54271deedf7b1d25c 100644 (file)
@@ -37,6 +37,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
        { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E  AR9485 */
        { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E  AR9580 */
        { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E  AR9462 */
+       { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E  AR1111/AR9485 */
        { 0 }
 };
 
@@ -320,6 +321,7 @@ static int ath_pci_suspend(struct device *device)
         * Otherwise the chip never moved to full sleep,
         * when no interface is up.
         */
+       ath9k_stop_btcoex(sc);
        ath9k_hw_disable(sc->sc_ah);
        ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
 
index 12aca02228c22e9c8f5c62db20687c03f5992959..4480c0cc655f6f6ffca73774b2178e748936155e 100644 (file)
@@ -1044,7 +1044,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
        struct ieee80211_hw *hw = sc->hw;
        struct ieee80211_hdr *hdr;
        int retval;
-       bool decrypt_error = false;
        struct ath_rx_status rs;
        enum ath9k_rx_qtype qtype;
        bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
@@ -1066,6 +1065,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
        tsf_lower = tsf & 0xffffffff;
 
        do {
+               bool decrypt_error = false;
                /* If handling rx interrupt and flush is in progress => exit */
                if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
                        break;
index b80352b308d54dabbc414c0d765122470f888c47..a140165dfee0515b70263cddf6e7902f4171de48 100644 (file)
@@ -2719,32 +2719,37 @@ static int b43_gpio_init(struct b43_wldev *dev)
        if (dev->dev->chip_id == 0x4301) {
                mask |= 0x0060;
                set |= 0x0060;
+       } else if (dev->dev->chip_id == 0x5354) {
+               /* Don't allow overtaking buttons GPIOs */
+               set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
        }
-       if (dev->dev->chip_id == 0x5354)
-               set &= 0xff02;
+
        if (0 /* FIXME: conditional unknown */ ) {
                b43_write16(dev, B43_MMIO_GPIO_MASK,
                            b43_read16(dev, B43_MMIO_GPIO_MASK)
                            | 0x0100);
-               mask |= 0x0180;
-               set |= 0x0180;
+               /* BT Coexistance Input */
+               mask |= 0x0080;
+               set |= 0x0080;
+               /* BT Coexistance Out */
+               mask |= 0x0100;
+               set |= 0x0100;
        }
        if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) {
+               /* PA is controlled by gpio 9, let ucode handle it */
                b43_write16(dev, B43_MMIO_GPIO_MASK,
                            b43_read16(dev, B43_MMIO_GPIO_MASK)
                            | 0x0200);
                mask |= 0x0200;
                set |= 0x0200;
        }
-       if (dev->dev->core_rev >= 2)
-               mask |= 0x0010; /* FIXME: This is redundant. */
 
        switch (dev->dev->bus_type) {
 #ifdef CONFIG_B43_BCMA
        case B43_BUS_BCMA:
                bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
                                (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc,
-                                       BCMA_CC_GPIOCTL) & mask) | set);
+                                       BCMA_CC_GPIOCTL) & ~mask) | set);
                break;
 #endif
 #ifdef CONFIG_B43_SSB
@@ -2753,7 +2758,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
                if (gpiodev)
                        ssb_write32(gpiodev, B43_GPIO_CONTROL,
                                    (ssb_read32(gpiodev, B43_GPIO_CONTROL)
-                                   & mask) | set);
+                                   & ~mask) | set);
                break;
 #endif
        }
index 9a4c63f927cb1817ee666cc070f14d1a810083c0..7ed7d7577024628d228a78f6e94433c810295bc2 100644 (file)
@@ -382,9 +382,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
 {
        struct brcms_c_info *wlc = wlc_cm->wlc;
        struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
-       const struct ieee80211_reg_rule *reg_rule;
        struct txpwr_limits txpwr;
-       int ret;
 
        brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
 
@@ -393,8 +391,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
        );
 
        /* set or restore gmode as required by regulatory */
-       ret = freq_reg_info(wlc->wiphy, ch->center_freq, 0, &reg_rule);
-       if (!ret && (reg_rule->flags & NL80211_RRF_NO_OFDM))
+       if (ch->flags & IEEE80211_CHAN_NO_OFDM)
                brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
        else
                brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
index 9e79d47e077f34e8b980dc6a8689c0735bba93bc..192ad5c1fcc8813805702d7b75c4ab89761cfd42 100644 (file)
@@ -121,7 +121,8 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = {
                 IEEE80211_CHAN_NO_HT40PLUS),
        CHAN2GHZ(14, 2484,
                 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
-                IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+                IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS |
+                IEEE80211_CHAN_NO_OFDM)
 };
 
 static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
index 6fddd2785e6e1fc9e846cc7099c1bf6a6414804c..a82f46c10f5ec036ca07ae6bbfa139bb50ab8052 100644 (file)
@@ -707,11 +707,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
  */
 static bool rs_use_green(struct ieee80211_sta *sta)
 {
-       struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct iwl_rxon_context *ctx = sta_priv->ctx;
-
-       return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
-               !(ctx->ht.non_gf_sta_present);
+       /*
+        * There's a bug somewhere in this code that causes the
+        * scaling to get stuck because GF+SGI can't be combined
+        * in SISO rates. Until we find that bug, disable GF, it
+        * has only limited benefit and we still interoperate with
+        * GF APs since we can always receive GF transmissions.
+        */
+       return false;
 }
 
 /**
index eb5de800ed9038109e9a80bfc9cd15863d3491e4..1c10b542ab231a45e5134a58ceb858c8ab82d331 100644 (file)
@@ -1254,6 +1254,7 @@ static int lbs_associate(struct lbs_private *priv,
                        netif_tx_wake_all_queues(priv->dev);
        }
 
+       kfree(cmd);
 done:
        lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
        return ret;
index 76caebaa43977f722cbd707d666f1f014002792e..e970897f6ab52370a632a64a62cc10bb3c39a3c6 100644 (file)
@@ -1314,6 +1314,7 @@ static void if_sdio_remove(struct sdio_func *func)
                kfree(packet);
        }
 
+       kfree(card);
        lbs_deb_leave(LBS_DEB_SDIO);
 }
 
index 58048189bd24475f3ca18960822b6b18219e637c..fe1ea43c5149ef03e9ed0e2809695773fa2a576d 100644 (file)
@@ -571,7 +571,10 @@ static int lbs_thread(void *data)
                        netdev_info(dev, "Timeout submitting command 0x%04x\n",
                                    le16_to_cpu(cmdnode->cmdbuf->command));
                        lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
-                       if (priv->reset_card)
+
+                       /* Reset card, but only when it isn't in the process
+                        * of being shutdown anyway. */
+                       if (!dev->dismantle && priv->reset_card)
                                priv->reset_card(priv);
                }
                priv->cmd_timed_out = 0;
index 7f207b6e9552c3eb795c62dde4457d30a924fde9..effb044a8a9d5d8169be88744d561c62ac160165 100644 (file)
@@ -42,7 +42,7 @@ MODULE_FIRMWARE("isl3887usb");
  * whenever you add a new device.
  */
 
-static struct usb_device_id p54u_table[] __devinitdata = {
+static struct usb_device_id p54u_table[] = {
        /* Version 1 devices (pci chip + net2280) */
        {USB_DEVICE(0x0411, 0x0050)},   /* Buffalo WLI2-USB2-G54 */
        {USB_DEVICE(0x045e, 0x00c2)},   /* Microsoft MN-710 */
index 241162e8111d2584f0fca6f47819cf924cdf1157..7a4ae9ee1c63057b78d582fd3a94964a6fdea264 100644 (file)
@@ -1803,6 +1803,7 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
                                                struct cfg80211_pmksa *pmksa,
                                                int max_pmkids)
 {
+       struct ndis_80211_pmkid *new_pmkids;
        int i, err, newlen;
        unsigned int count;
 
@@ -1833,11 +1834,12 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
        /* add new pmkid */
        newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]);
 
-       pmkids = krealloc(pmkids, newlen, GFP_KERNEL);
-       if (!pmkids) {
+       new_pmkids = krealloc(pmkids, newlen, GFP_KERNEL);
+       if (!new_pmkids) {
                err = -ENOMEM;
                goto error;
        }
+       pmkids = new_pmkids;
 
        pmkids->length = cpu_to_le32(newlen);
        pmkids->bssid_info_count = cpu_to_le32(count + 1);
index 88455b1b9fe05b299aff2cc667d3d90e7822855a..cb8c2aca54e4dfdac4a7e223a8070f4e4543399e 100644 (file)
@@ -221,6 +221,67 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
        mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
+static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+       int i, count;
+
+       rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
+       if (rt2x00_get_field32(reg, WLAN_EN))
+               return 0;
+
+       rt2x00_set_field32(&reg, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
+       rt2x00_set_field32(&reg, FRC_WL_ANT_SET, 1);
+       rt2x00_set_field32(&reg, WLAN_CLK_EN, 0);
+       rt2x00_set_field32(&reg, WLAN_EN, 1);
+       rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
+
+       udelay(REGISTER_BUSY_DELAY);
+
+       count = 0;
+       do {
+               /*
+                * Check PLL_LD & XTAL_RDY.
+                */
+               for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+                       rt2800_register_read(rt2x00dev, CMB_CTRL, &reg);
+                       if (rt2x00_get_field32(reg, PLL_LD) &&
+                           rt2x00_get_field32(reg, XTAL_RDY))
+                               break;
+                       udelay(REGISTER_BUSY_DELAY);
+               }
+
+               if (i >= REGISTER_BUSY_COUNT) {
+
+                       if (count >= 10)
+                               return -EIO;
+
+                       rt2800_register_write(rt2x00dev, 0x58, 0x018);
+                       udelay(REGISTER_BUSY_DELAY);
+                       rt2800_register_write(rt2x00dev, 0x58, 0x418);
+                       udelay(REGISTER_BUSY_DELAY);
+                       rt2800_register_write(rt2x00dev, 0x58, 0x618);
+                       udelay(REGISTER_BUSY_DELAY);
+                       count++;
+               } else {
+                       count = 0;
+               }
+
+               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
+               rt2x00_set_field32(&reg, PCIE_APP0_CLK_REQ, 0);
+               rt2x00_set_field32(&reg, WLAN_CLK_EN, 1);
+               rt2x00_set_field32(&reg, WLAN_RESET, 1);
+               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
+               udelay(10);
+               rt2x00_set_field32(&reg, WLAN_RESET, 0);
+               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
+               udelay(10);
+               rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff);
+       } while (count != 0);
+
+       return 0;
+}
+
 void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
                        const u8 command, const u8 token,
                        const u8 arg0, const u8 arg1)
@@ -400,6 +461,13 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 {
        unsigned int i;
        u32 reg;
+       int retval;
+
+       if (rt2x00_rt(rt2x00dev, RT3290)) {
+               retval = rt2800_enable_wlan_rt3290(rt2x00dev);
+               if (retval)
+                       return -EBUSY;
+       }
 
        /*
         * If driver doesn't wake up firmware here,
index 235376e9cb04c0066032493f2d86b008d604c14c..98aa426a35649828e3c70c0f2bab0acf24e49381 100644 (file)
@@ -980,66 +980,6 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
        return rt2800_validate_eeprom(rt2x00dev);
 }
 
-static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
-{
-       u32 reg;
-       int i, count;
-
-       rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
-       if (rt2x00_get_field32(reg, WLAN_EN))
-               return 0;
-
-       rt2x00_set_field32(&reg, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
-       rt2x00_set_field32(&reg, FRC_WL_ANT_SET, 1);
-       rt2x00_set_field32(&reg, WLAN_CLK_EN, 0);
-       rt2x00_set_field32(&reg, WLAN_EN, 1);
-       rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
-
-       udelay(REGISTER_BUSY_DELAY);
-
-       count = 0;
-       do {
-               /*
-                * Check PLL_LD & XTAL_RDY.
-                */
-               for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-                       rt2800_register_read(rt2x00dev, CMB_CTRL, &reg);
-                       if (rt2x00_get_field32(reg, PLL_LD) &&
-                           rt2x00_get_field32(reg, XTAL_RDY))
-                               break;
-                       udelay(REGISTER_BUSY_DELAY);
-               }
-
-               if (i >= REGISTER_BUSY_COUNT) {
-
-                       if (count >= 10)
-                               return -EIO;
-
-                       rt2800_register_write(rt2x00dev, 0x58, 0x018);
-                       udelay(REGISTER_BUSY_DELAY);
-                       rt2800_register_write(rt2x00dev, 0x58, 0x418);
-                       udelay(REGISTER_BUSY_DELAY);
-                       rt2800_register_write(rt2x00dev, 0x58, 0x618);
-                       udelay(REGISTER_BUSY_DELAY);
-                       count++;
-               } else {
-                       count = 0;
-               }
-
-               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
-               rt2x00_set_field32(&reg, PCIE_APP0_CLK_REQ, 0);
-               rt2x00_set_field32(&reg, WLAN_CLK_EN, 1);
-               rt2x00_set_field32(&reg, WLAN_RESET, 1);
-               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
-               udelay(10);
-               rt2x00_set_field32(&reg, WLAN_RESET, 0);
-               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
-               udelay(10);
-               rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff);
-       } while (count != 0);
-
-       return 0;
-}
 static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
@@ -1062,17 +1002,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
        if (retval)
                return retval;
 
-       /*
-        * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan
-        * clk for rt3290. That avoid the MCU fail in start phase.
-        */
-       if (rt2x00_rt(rt2x00dev, RT3290)) {
-               retval = rt2800_enable_wlan_rt3290(rt2x00dev);
-
-               if (retval)
-                       return retval;
-       }
-
        /*
         * This device has multiple filters for control frames
         * and has a separate filter for PS Poll frames.
index f32259686b45778b77630328e54e2c1298b18a84..3f7bc5cadf9a8a7a433688e8d480d76de3c1ab82 100644 (file)
@@ -2243,8 +2243,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
 
 static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev)
 {
-       struct ieee80211_conf conf = { .flags = 0 };
-       struct rt2x00lib_conf libconf = { .conf = &conf };
+       struct rt2x00lib_conf libconf = { .conf = &rt2x00dev->hw->conf };
 
        rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
 }
index 71a30b026089eddf6bf08658cf7e3f628992dbc5..533024095c43ad48871868d8522c6953399eb86a 100644 (file)
@@ -44,7 +44,7 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
 MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
 MODULE_LICENSE("GPL");
 
-static struct usb_device_id rtl8187_table[] __devinitdata = {
+static struct usb_device_id rtl8187_table[] = {
        /* Asus */
        {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
        /* Belkin */
index c181b94abc363b64a4a38c2e39625b7564dc2267..d4a1c9a043e12d3572faefe9a9fd11a1683cdd97 100644 (file)
@@ -363,6 +363,33 @@ struct device_node *of_get_next_child(const struct device_node *node,
 }
 EXPORT_SYMBOL(of_get_next_child);
 
+/**
+ *     of_get_next_available_child - Find the next available child node
+ *     @node:  parent node
+ *     @prev:  previous child of the parent node, or NULL to get first
+ *
+ *      This function is like of_get_next_child(), except that it
+ *      automatically skips any disabled nodes (i.e. status = "disabled").
+ */
+struct device_node *of_get_next_available_child(const struct device_node *node,
+       struct device_node *prev)
+{
+       struct device_node *next;
+
+       read_lock(&devtree_lock);
+       next = prev ? prev->sibling : node->child;
+       for (; next; next = next->sibling) {
+               if (!of_device_is_available(next))
+                       continue;
+               if (of_node_get(next))
+                       break;
+       }
+       of_node_put(prev);
+       read_unlock(&devtree_lock);
+       return next;
+}
+EXPORT_SYMBOL(of_get_next_available_child);
+
 /**
  *     of_find_node_by_path - Find a node matching a full OF path
  *     @path:  The full path to match
index fbf7b26c7c8a5119c527c00a15a35539b4aa3a2b..c5792d622dc4528ba572632d39c7c1f1d7ae438d 100644 (file)
@@ -266,8 +266,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        }
 
        if (!error)
-               dev_printk(KERN_INFO, &dev->dev,
-                               "power state changed by ACPI to D%d\n", state);
+               dev_info(&dev->dev, "power state changed by ACPI to %s\n",
+                        pci_power_name(state));
 
        return error;
 }
index 185be37033430adf53d8a390fd34a4c9dfd6e446..5270f1a99328d678396739781c7b0d4a87a586ef 100644 (file)
@@ -959,6 +959,13 @@ static int pci_pm_poweroff_noirq(struct device *dev)
        if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
                pci_prepare_to_sleep(pci_dev);
 
+       /*
+        * The reason for doing this here is the same as for the analogous code
+        * in pci_pm_suspend_noirq().
+        */
+       if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
+               pci_write_config_word(pci_dev, PCI_COMMAND, 0);
+
        return 0;
 }
 
index fb7f3bebdc69dadec1451773c596c9b901821265..dc5c126e398a0ac84fc13fa5f564d832ade0831e 100644 (file)
@@ -657,11 +657,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev)
        if (p != NULL)
                return ERR_PTR(-EBUSY);
 
-       p = create_pinctrl(dev);
-       if (IS_ERR(p))
-               return p;
-
-       return p;
+       return create_pinctrl(dev);
 }
 
 /**
@@ -738,11 +734,8 @@ static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p,
                        dev_dbg(p->dev, "using pinctrl dummy state (%s)\n",
                                name);
                        state = create_state(p, name);
-                       if (IS_ERR(state))
-                               return state;
-               } else {
-                       return ERR_PTR(-ENODEV);
-               }
+               } else
+                       state = ERR_PTR(-ENODEV);
        }
 
        return state;
index 75d3eff94296823e4959e63b6ec8c0531a129440..3674d877ed7c1db935b8e3831d60ea7b3e505c7f 100644 (file)
@@ -292,7 +292,7 @@ static int __init imx23_pinctrl_init(void)
 {
        return platform_driver_register(&imx23_pinctrl_driver);
 }
-arch_initcall(imx23_pinctrl_init);
+postcore_initcall(imx23_pinctrl_init);
 
 static void __exit imx23_pinctrl_exit(void)
 {
index b973026811a269978244a02177238d2f780726cf..0f5b2122b1bae358c8da2c1de90879a57a2a3911 100644 (file)
@@ -408,7 +408,7 @@ static int __init imx28_pinctrl_init(void)
 {
        return platform_driver_register(&imx28_pinctrl_driver);
 }
-arch_initcall(imx28_pinctrl_init);
+postcore_initcall(imx28_pinctrl_init);
 
 static void __exit imx28_pinctrl_exit(void)
 {
index 689b3c88dd2e723be68c5fd83a8bca99e9be78e8..9fd02162a3c21ec1ca810c163ab8c5143e1af41b 100644 (file)
@@ -974,7 +974,7 @@ static struct imx_pin_reg imx51_pin_regs[] = {
        IMX_PIN_REG(MX51_PAD_EIM_DA13, NO_PAD, 0x050, 0, 0x000, 0), /* MX51_PAD_EIM_DA13__EIM_DA13 */
        IMX_PIN_REG(MX51_PAD_EIM_DA14, NO_PAD, 0x054, 0, 0x000, 0), /* MX51_PAD_EIM_DA14__EIM_DA14 */
        IMX_PIN_REG(MX51_PAD_EIM_DA15, NO_PAD, 0x058, 0, 0x000, 0), /* MX51_PAD_EIM_DA15__EIM_DA15 */
-       IMX_PIN_REG(MX51_PAD_SD2_CMD, NO_PAD, 0x3b4, 2, 0x91c, 3), /* MX51_PAD_SD2_CMD__CSPI_MOSI */
+       IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 2, 0x91c, 3), /* MX51_PAD_SD2_CMD__CSPI_MOSI */
        IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 1, 0x9b0, 2), /* MX51_PAD_SD2_CMD__I2C1_SCL */
        IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 0, 0x000, 0), /* MX51_PAD_SD2_CMD__SD2_CMD */
        IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 2, 0x914, 3), /* MX51_PAD_SD2_CLK__CSPI_SCLK */
index 6f99769c6733a946ad3a67311e23b246ad0aae74..a39fb7a6fc5142b86a65630bd5a208c84b94cd9a 100644 (file)
@@ -505,6 +505,8 @@ static const unsigned kp_b_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
        DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1,
        DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2,
        DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 };
+static const unsigned kp_b_2_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
+       DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_F4, DB8500_PIN_E3};
 static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
        DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
        DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8,
@@ -662,6 +664,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
        DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B),
        DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B),
        DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(kp_b_2, NMK_GPIO_ALT_B),
        DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B),
        DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B),
        DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B),
@@ -751,7 +754,7 @@ DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1");
 DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1");
 DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1",
        "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1");
-DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_c_1", "kp_oc1_1");
+DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1");
 DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1");
 DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1");
 DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1");
@@ -766,7 +769,7 @@ DB8500_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio1_a_1", "ipgpio7_b_1",
 DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1");
 DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1");
 DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1dir_a_1");
-DB8500_FUNC_GROUPS(hsi, "hsir1_a_1", "hsit1_a_1", "hsit_a_2");
+DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2");
 DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1");
 DB8500_FUNC_GROUPS(usb, "usb_a_1");
 DB8500_FUNC_GROUPS(trig, "trig_b_1");
index 53b0d49a7a1c817a7316fc25e57fff3a5c5341bb..3dde6537adb878d7986a96b2dba528d41cf77d1a 100644 (file)
@@ -1292,7 +1292,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
                                                NOMADIK_GPIO_TO_IRQ(pdata->first_gpio),
                                                0, &nmk_gpio_irq_simple_ops, nmk_chip);
        if (!nmk_chip->domain) {
-               pr_err("%s: Failed to create irqdomain\n", np->full_name);
+               dev_err(&dev->dev, "failed to create irqdomain\n");
                ret = -ENOSYS;
                goto out;
        }
@@ -1731,7 +1731,6 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
        for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
                if (!nmk_gpio_chips[i]) {
                        dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
-                       devm_kfree(&pdev->dev, npct);
                        return -EPROBE_DEFER;
                }
                npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip;
index 2aae8a8978e99b4224ef0f0baff84b5745e913dd..7fca6ce5952b94a0f398bd1bca35795e20ba62e0 100644 (file)
@@ -1217,7 +1217,6 @@ out_no_rsc_remap:
        iounmap(spmx->gpio_virtbase);
 out_no_gpio_remap:
        platform_set_drvdata(pdev, NULL);
-       devm_kfree(&pdev->dev, spmx);
        return ret;
 }
 
index a7ad8c112d91e21c9e0c930082a451d4b4921798..309f5b9a70ec74d4b5e1cca07b6e8e31836f53fa 100644 (file)
@@ -1121,10 +1121,8 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev)
        upmx->dev = &pdev->dev;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               ret = -ENOENT;
-               goto out_no_resource;
-       }
+       if (!res)
+               return -ENOENT;
        upmx->phybase = res->start;
        upmx->physize = resource_size(res);
 
@@ -1165,8 +1163,6 @@ out_no_remap:
        platform_set_drvdata(pdev, NULL);
 out_no_memregion:
        release_mem_region(upmx->phybase, upmx->physize);
-out_no_resource:
-       devm_kfree(&pdev->dev, upmx);
        return ret;
 }
 
index 2a262f5c5c0ca5753671f74903a2e49d8e65d382..c86bae828c28258e8c98d4801742af679f277879 100644 (file)
@@ -289,6 +289,7 @@ config IDEAPAD_LAPTOP
        tristate "Lenovo IdeaPad Laptop Extras"
        depends on ACPI
        depends on RFKILL && INPUT
+       depends on SERIO_I8042
        select INPUT_SPARSEKMAP
        help
          This is a driver for the rfkill switches on Lenovo IdeaPad netbooks.
@@ -758,8 +759,11 @@ config SAMSUNG_Q10
 
 config APPLE_GMUX
        tristate "Apple Gmux Driver"
+       depends on ACPI
        depends on PNP
-       select BACKLIGHT_CLASS_DEVICE
+       depends on BACKLIGHT_CLASS_DEVICE
+       depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE
+       depends on ACPI_VIDEO=n || ACPI_VIDEO
        ---help---
          This driver provides support for the gmux device found on many
          Apple laptops, which controls the display mux for the hybrid
index 905fa01ac8df7abe86893964fd50c15a96b3b5d6..dfb1a92ce9497cb49e913fa23d8f8819300243e9 100644 (file)
@@ -2,6 +2,7 @@
  *  Gmux driver for Apple laptops
  *
  *  Copyright (C) Canonical Ltd. <seth.forshee@canonical.com>
+ *  Copyright (C) 2010-2012 Andreas Heider <andreas@meetr.de>
  *
  *  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
 #include <linux/pnp.h>
 #include <linux/apple_bl.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/vga_switcheroo.h>
 #include <acpi/video.h>
 #include <asm/io.h>
 
 struct apple_gmux_data {
        unsigned long iostart;
        unsigned long iolen;
+       bool indexed;
+       struct mutex index_lock;
 
        struct backlight_device *bdev;
+
+       /* switcheroo data */
+       acpi_handle dhandle;
+       int gpe;
+       enum vga_switcheroo_client_id resume_client_id;
+       enum vga_switcheroo_state power_state;
+       struct completion powerchange_done;
 };
 
+static struct apple_gmux_data *apple_gmux_data;
+
 /*
  * gmux port offsets. Many of these are not yet used, but may be in the
  * future, and it's useful to have them documented here anyhow.
@@ -45,6 +60,9 @@ struct apple_gmux_data {
 #define GMUX_PORT_DISCRETE_POWER       0x50
 #define GMUX_PORT_MAX_BRIGHTNESS       0x70
 #define GMUX_PORT_BRIGHTNESS           0x74
+#define GMUX_PORT_VALUE                        0xc2
+#define GMUX_PORT_READ                 0xd0
+#define GMUX_PORT_WRITE                        0xd4
 
 #define GMUX_MIN_IO_LEN                        (GMUX_PORT_BRIGHTNESS + 4)
 
@@ -59,22 +77,172 @@ struct apple_gmux_data {
 #define GMUX_BRIGHTNESS_MASK           0x00ffffff
 #define GMUX_MAX_BRIGHTNESS            GMUX_BRIGHTNESS_MASK
 
-static inline u8 gmux_read8(struct apple_gmux_data *gmux_data, int port)
+static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port)
 {
        return inb(gmux_data->iostart + port);
 }
 
-static inline void gmux_write8(struct apple_gmux_data *gmux_data, int port,
+static void gmux_pio_write8(struct apple_gmux_data *gmux_data, int port,
                               u8 val)
 {
        outb(val, gmux_data->iostart + port);
 }
 
-static inline u32 gmux_read32(struct apple_gmux_data *gmux_data, int port)
+static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int port)
 {
        return inl(gmux_data->iostart + port);
 }
 
+static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,
+                            u32 val)
+{
+       int i;
+       u8 tmpval;
+
+       for (i = 0; i < 4; i++) {
+               tmpval = (val >> (i * 8)) & 0xff;
+               outb(tmpval, port + i);
+       }
+}
+
+static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data)
+{
+       int i = 200;
+       u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
+
+       while (i && (gwr & 0x01)) {
+               inb(gmux_data->iostart + GMUX_PORT_READ);
+               gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
+               udelay(100);
+               i--;
+       }
+
+       return !!i;
+}
+
+static int gmux_index_wait_complete(struct apple_gmux_data *gmux_data)
+{
+       int i = 200;
+       u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
+
+       while (i && !(gwr & 0x01)) {
+               gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
+               udelay(100);
+               i--;
+       }
+
+       if (gwr & 0x01)
+               inb(gmux_data->iostart + GMUX_PORT_READ);
+
+       return !!i;
+}
+
+static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port)
+{
+       u8 val;
+
+       mutex_lock(&gmux_data->index_lock);
+       outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
+       gmux_index_wait_ready(gmux_data);
+       val = inb(gmux_data->iostart + GMUX_PORT_VALUE);
+       mutex_unlock(&gmux_data->index_lock);
+
+       return val;
+}
+
+static void gmux_index_write8(struct apple_gmux_data *gmux_data, int port,
+                             u8 val)
+{
+       mutex_lock(&gmux_data->index_lock);
+       outb(val, gmux_data->iostart + GMUX_PORT_VALUE);
+       gmux_index_wait_ready(gmux_data);
+       outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
+       gmux_index_wait_complete(gmux_data);
+       mutex_unlock(&gmux_data->index_lock);
+}
+
+static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port)
+{
+       u32 val;
+
+       mutex_lock(&gmux_data->index_lock);
+       outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
+       gmux_index_wait_ready(gmux_data);
+       val = inl(gmux_data->iostart + GMUX_PORT_VALUE);
+       mutex_unlock(&gmux_data->index_lock);
+
+       return val;
+}
+
+static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port,
+                              u32 val)
+{
+       int i;
+       u8 tmpval;
+
+       mutex_lock(&gmux_data->index_lock);
+
+       for (i = 0; i < 4; i++) {
+               tmpval = (val >> (i * 8)) & 0xff;
+               outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i);
+       }
+
+       gmux_index_wait_ready(gmux_data);
+       outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
+       gmux_index_wait_complete(gmux_data);
+       mutex_unlock(&gmux_data->index_lock);
+}
+
+static u8 gmux_read8(struct apple_gmux_data *gmux_data, int port)
+{
+       if (gmux_data->indexed)
+               return gmux_index_read8(gmux_data, port);
+       else
+               return gmux_pio_read8(gmux_data, port);
+}
+
+static void gmux_write8(struct apple_gmux_data *gmux_data, int port, u8 val)
+{
+       if (gmux_data->indexed)
+               gmux_index_write8(gmux_data, port, val);
+       else
+               gmux_pio_write8(gmux_data, port, val);
+}
+
+static u32 gmux_read32(struct apple_gmux_data *gmux_data, int port)
+{
+       if (gmux_data->indexed)
+               return gmux_index_read32(gmux_data, port);
+       else
+               return gmux_pio_read32(gmux_data, port);
+}
+
+static void gmux_write32(struct apple_gmux_data *gmux_data, int port,
+                            u32 val)
+{
+       if (gmux_data->indexed)
+               gmux_index_write32(gmux_data, port, val);
+       else
+               gmux_pio_write32(gmux_data, port, val);
+}
+
+static bool gmux_is_indexed(struct apple_gmux_data *gmux_data)
+{
+       u16 val;
+
+       outb(0xaa, gmux_data->iostart + 0xcc);
+       outb(0x55, gmux_data->iostart + 0xcd);
+       outb(0x00, gmux_data->iostart + 0xce);
+
+       val = inb(gmux_data->iostart + 0xcc) |
+               (inb(gmux_data->iostart + 0xcd) << 8);
+
+       if (val == 0x55aa)
+               return true;
+
+       return false;
+}
+
 static int gmux_get_brightness(struct backlight_device *bd)
 {
        struct apple_gmux_data *gmux_data = bl_get_data(bd);
@@ -90,16 +258,7 @@ static int gmux_update_status(struct backlight_device *bd)
        if (bd->props.state & BL_CORE_SUSPENDED)
                return 0;
 
-       /*
-        * Older gmux versions require writing out lower bytes first then
-        * setting the upper byte to 0 to flush the values. Newer versions
-        * accept a single u32 write, but the old method also works, so we
-        * just use the old method for all gmux versions.
-        */
-       gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS, brightness);
-       gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 1, brightness >> 8);
-       gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 2, brightness >> 16);
-       gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 3, 0);
+       gmux_write32(gmux_data, GMUX_PORT_BRIGHTNESS, brightness);
 
        return 0;
 }
@@ -110,6 +269,146 @@ static const struct backlight_ops gmux_bl_ops = {
        .update_status = gmux_update_status,
 };
 
+static int gmux_switchto(enum vga_switcheroo_client_id id)
+{
+       if (id == VGA_SWITCHEROO_IGD) {
+               gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
+               gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2);
+               gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2);
+       } else {
+               gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
+               gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3);
+               gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
+       }
+
+       return 0;
+}
+
+static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data,
+                                  enum vga_switcheroo_state state)
+{
+       INIT_COMPLETION(gmux_data->powerchange_done);
+
+       if (state == VGA_SWITCHEROO_ON) {
+               gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1);
+               gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3);
+               pr_debug("Discrete card powered up\n");
+       } else {
+               gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1);
+               gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0);
+               pr_debug("Discrete card powered down\n");
+       }
+
+       gmux_data->power_state = state;
+
+       if (gmux_data->gpe >= 0 &&
+           !wait_for_completion_interruptible_timeout(&gmux_data->powerchange_done,
+                                                      msecs_to_jiffies(200)))
+               pr_warn("Timeout waiting for gmux switch to complete\n");
+
+       return 0;
+}
+
+static int gmux_set_power_state(enum vga_switcheroo_client_id id,
+                               enum vga_switcheroo_state state)
+{
+       if (id == VGA_SWITCHEROO_IGD)
+               return 0;
+
+       return gmux_set_discrete_state(apple_gmux_data, state);
+}
+
+static int gmux_get_client_id(struct pci_dev *pdev)
+{
+       /*
+        * Early Macbook Pros with switchable graphics use nvidia
+        * integrated graphics. Hardcode that the 9400M is integrated.
+        */
+       if (pdev->vendor == PCI_VENDOR_ID_INTEL)
+               return VGA_SWITCHEROO_IGD;
+       else if (pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
+                pdev->device == 0x0863)
+               return VGA_SWITCHEROO_IGD;
+       else
+               return VGA_SWITCHEROO_DIS;
+}
+
+static enum vga_switcheroo_client_id
+gmux_active_client(struct apple_gmux_data *gmux_data)
+{
+       if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2)
+               return VGA_SWITCHEROO_IGD;
+
+       return VGA_SWITCHEROO_DIS;
+}
+
+static struct vga_switcheroo_handler gmux_handler = {
+       .switchto = gmux_switchto,
+       .power_state = gmux_set_power_state,
+       .get_client_id = gmux_get_client_id,
+};
+
+static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data)
+{
+       gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE,
+                   GMUX_INTERRUPT_DISABLE);
+}
+
+static inline void gmux_enable_interrupts(struct apple_gmux_data *gmux_data)
+{
+       gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE,
+                   GMUX_INTERRUPT_ENABLE);
+}
+
+static inline u8 gmux_interrupt_get_status(struct apple_gmux_data *gmux_data)
+{
+       return gmux_read8(gmux_data, GMUX_PORT_INTERRUPT_STATUS);
+}
+
+static void gmux_clear_interrupts(struct apple_gmux_data *gmux_data)
+{
+       u8 status;
+
+       /* to clear interrupts write back current status */
+       status = gmux_interrupt_get_status(gmux_data);
+       gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status);
+}
+
+static void gmux_notify_handler(acpi_handle device, u32 value, void *context)
+{
+       u8 status;
+       struct pnp_dev *pnp = (struct pnp_dev *)context;
+       struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
+
+       status = gmux_interrupt_get_status(gmux_data);
+       gmux_disable_interrupts(gmux_data);
+       pr_debug("Notify handler called: status %d\n", status);
+
+       gmux_clear_interrupts(gmux_data);
+       gmux_enable_interrupts(gmux_data);
+
+       if (status & GMUX_INTERRUPT_STATUS_POWER)
+               complete(&gmux_data->powerchange_done);
+}
+
+static int gmux_suspend(struct pnp_dev *pnp, pm_message_t state)
+{
+       struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
+       gmux_data->resume_client_id = gmux_active_client(gmux_data);
+       gmux_disable_interrupts(gmux_data);
+       return 0;
+}
+
+static int gmux_resume(struct pnp_dev *pnp)
+{
+       struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
+       gmux_enable_interrupts(gmux_data);
+       gmux_switchto(gmux_data->resume_client_id);
+       if (gmux_data->power_state == VGA_SWITCHEROO_OFF)
+               gmux_set_discrete_state(gmux_data, gmux_data->power_state);
+       return 0;
+}
+
 static int __devinit gmux_probe(struct pnp_dev *pnp,
                                const struct pnp_device_id *id)
 {
@@ -119,6 +418,11 @@ static int __devinit gmux_probe(struct pnp_dev *pnp,
        struct backlight_device *bdev;
        u8 ver_major, ver_minor, ver_release;
        int ret = -ENXIO;
+       acpi_status status;
+       unsigned long long gpe;
+
+       if (apple_gmux_data)
+               return -EBUSY;
 
        gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL);
        if (!gmux_data)
@@ -147,22 +451,29 @@ static int __devinit gmux_probe(struct pnp_dev *pnp,
        }
 
        /*
-        * On some machines the gmux is in ACPI even thought the machine
-        * doesn't really have a gmux. Check for invalid version information
-        * to detect this.
+        * Invalid version information may indicate either that the gmux
+        * device isn't present or that it's a new one that uses indexed
+        * io
         */
+
        ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
        ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
        ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
        if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
-               pr_info("gmux device not present\n");
-               ret = -ENODEV;
-               goto err_release;
+               if (gmux_is_indexed(gmux_data)) {
+                       mutex_init(&gmux_data->index_lock);
+                       gmux_data->indexed = true;
+               } else {
+                       pr_info("gmux device not present\n");
+                       ret = -ENODEV;
+                       goto err_release;
+               }
+               pr_info("Found indexed gmux\n");
+       } else {
+               pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor,
+                       ver_release);
        }
 
-       pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor,
-               ver_release);
-
        memset(&props, 0, sizeof(props));
        props.type = BACKLIGHT_PLATFORM;
        props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS);
@@ -194,13 +505,67 @@ static int __devinit gmux_probe(struct pnp_dev *pnp,
         * Disable the other backlight choices.
         */
        acpi_video_dmi_promote_vendor();
-#ifdef CONFIG_ACPI_VIDEO
+#if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE)
        acpi_video_unregister();
 #endif
        apple_bl_unregister();
 
+       gmux_data->power_state = VGA_SWITCHEROO_ON;
+
+       gmux_data->dhandle = DEVICE_ACPI_HANDLE(&pnp->dev);
+       if (!gmux_data->dhandle) {
+               pr_err("Cannot find acpi handle for pnp device %s\n",
+                      dev_name(&pnp->dev));
+               ret = -ENODEV;
+               goto err_notify;
+       }
+
+       status = acpi_evaluate_integer(gmux_data->dhandle, "GMGP", NULL, &gpe);
+       if (ACPI_SUCCESS(status)) {
+               gmux_data->gpe = (int)gpe;
+
+               status = acpi_install_notify_handler(gmux_data->dhandle,
+                                                    ACPI_DEVICE_NOTIFY,
+                                                    &gmux_notify_handler, pnp);
+               if (ACPI_FAILURE(status)) {
+                       pr_err("Install notify handler failed: %s\n",
+                              acpi_format_exception(status));
+                       ret = -ENODEV;
+                       goto err_notify;
+               }
+
+               status = acpi_enable_gpe(NULL, gmux_data->gpe);
+               if (ACPI_FAILURE(status)) {
+                       pr_err("Cannot enable gpe: %s\n",
+                              acpi_format_exception(status));
+                       goto err_enable_gpe;
+               }
+       } else {
+               pr_warn("No GPE found for gmux\n");
+               gmux_data->gpe = -1;
+       }
+
+       if (vga_switcheroo_register_handler(&gmux_handler)) {
+               ret = -ENODEV;
+               goto err_register_handler;
+       }
+
+       init_completion(&gmux_data->powerchange_done);
+       apple_gmux_data = gmux_data;
+       gmux_enable_interrupts(gmux_data);
+
        return 0;
 
+err_register_handler:
+       if (gmux_data->gpe >= 0)
+               acpi_disable_gpe(NULL, gmux_data->gpe);
+err_enable_gpe:
+       if (gmux_data->gpe >= 0)
+               acpi_remove_notify_handler(gmux_data->dhandle,
+                                          ACPI_DEVICE_NOTIFY,
+                                          &gmux_notify_handler);
+err_notify:
+       backlight_device_unregister(bdev);
 err_release:
        release_region(gmux_data->iostart, gmux_data->iolen);
 err_free:
@@ -212,12 +577,23 @@ static void __devexit gmux_remove(struct pnp_dev *pnp)
 {
        struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
 
+       vga_switcheroo_unregister_handler();
+       gmux_disable_interrupts(gmux_data);
+       if (gmux_data->gpe >= 0) {
+               acpi_disable_gpe(NULL, gmux_data->gpe);
+               acpi_remove_notify_handler(gmux_data->dhandle,
+                                          ACPI_DEVICE_NOTIFY,
+                                          &gmux_notify_handler);
+       }
+
        backlight_device_unregister(gmux_data->bdev);
+
        release_region(gmux_data->iostart, gmux_data->iolen);
+       apple_gmux_data = NULL;
        kfree(gmux_data);
 
        acpi_video_dmi_demote_vendor();
-#ifdef CONFIG_ACPI_VIDEO
+#if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE)
        acpi_video_register();
 #endif
        apple_bl_register();
@@ -233,6 +609,8 @@ static struct pnp_driver gmux_pnp_driver = {
        .probe          = gmux_probe,
        .remove         = __devexit_p(gmux_remove),
        .id_table       = gmux_device_ids,
+       .suspend        = gmux_suspend,
+       .resume         = gmux_resume
 };
 
 static int __init apple_gmux_init(void)
index c7a36f6b058048eb092717eff06a9e413a6a2546..2eb9fe8e8efd038c7bb1d25ad4fbde2961ca8e1a 100644 (file)
@@ -101,6 +101,7 @@ MODULE_LICENSE("GPL");
 #define ASUS_WMI_DEVID_WIRELESS_LED    0x00010002
 #define ASUS_WMI_DEVID_CWAP            0x00010003
 #define ASUS_WMI_DEVID_WLAN            0x00010011
+#define ASUS_WMI_DEVID_WLAN_LED                0x00010012
 #define ASUS_WMI_DEVID_BLUETOOTH       0x00010013
 #define ASUS_WMI_DEVID_GPS             0x00010015
 #define ASUS_WMI_DEVID_WIMAX           0x00010017
@@ -731,8 +732,21 @@ static int asus_rfkill_set(void *data, bool blocked)
 {
        struct asus_rfkill *priv = data;
        u32 ctrl_param = !blocked;
+       u32 dev_id = priv->dev_id;
 
-       return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL);
+       /*
+        * If the user bit is set, BIOS can't set and record the wlan status,
+        * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED
+        * while we query the wlan status through WMI(ASUS_WMI_DEVID_WLAN).
+        * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED
+        * while setting the wlan status through WMI.
+        * This is also the behavior that windows app will do.
+        */
+       if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
+            priv->asus->driver->wlan_ctrl_by_user)
+               dev_id = ASUS_WMI_DEVID_WLAN_LED;
+
+       return asus_wmi_set_devstate(dev_id, ctrl_param, NULL);
 }
 
 static void asus_rfkill_query(struct rfkill *rfkill, void *data)
@@ -1653,6 +1667,7 @@ static int asus_wmi_add(struct platform_device *pdev)
        struct asus_wmi *asus;
        acpi_status status;
        int err;
+       u32 result;
 
        asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
        if (!asus)
@@ -1711,6 +1726,10 @@ static int asus_wmi_add(struct platform_device *pdev)
        if (err)
                goto fail_debugfs;
 
+       asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
+       if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
+               asus->driver->wlan_ctrl_by_user = 1;
+
        return 0;
 
 fail_debugfs:
index 9c1da8b81bea50f9007eac48f82da8f0bb29a73d..4c9bd38bb0a26141c27ceca8749358cf60da1cfb 100644 (file)
@@ -46,6 +46,7 @@ struct quirk_entry {
 struct asus_wmi_driver {
        int                     brightness;
        int                     panel_power;
+       int                     wlan_ctrl_by_user;
 
        const char              *name;
        struct module           *owner;
index 2ca7dd1ab3e452e49eb0c25561274cea435acbcf..c87ff16873f9753ef589111763d743bc09ed1409 100644 (file)
@@ -350,6 +350,7 @@ static void cmpc_accel_idev_init_v4(struct input_dev *inputdev)
        inputdev->close = cmpc_accel_close_v4;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int cmpc_accel_suspend_v4(struct device *dev)
 {
        struct input_dev *inputdev;
@@ -384,6 +385,7 @@ static int cmpc_accel_resume_v4(struct device *dev)
 
        return 0;
 }
+#endif
 
 static int cmpc_accel_add_v4(struct acpi_device *acpi)
 {
@@ -723,8 +725,10 @@ static void cmpc_tablet_handler(struct acpi_device *dev, u32 event)
        struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
 
        if (event == 0x81) {
-               if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val)))
+               if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) {
                        input_report_switch(inputdev, SW_TABLET_MODE, !val);
+                       input_sync(inputdev);
+               }
        }
 }
 
@@ -737,8 +741,10 @@ static void cmpc_tablet_idev_init(struct input_dev *inputdev)
        set_bit(SW_TABLET_MODE, inputdev->swbit);
 
        acpi = to_acpi_device(inputdev->dev.parent);
-       if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val)))
+       if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) {
                input_report_switch(inputdev, SW_TABLET_MODE, !val);
+               input_sync(inputdev);
+       }
 }
 
 static int cmpc_tablet_add(struct acpi_device *acpi)
@@ -752,15 +758,19 @@ static int cmpc_tablet_remove(struct acpi_device *acpi, int type)
        return cmpc_remove_acpi_notify_device(acpi);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int cmpc_tablet_resume(struct device *dev)
 {
        struct input_dev *inputdev = dev_get_drvdata(dev);
 
        unsigned long long val = 0;
-       if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val)))
+       if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) {
                input_report_switch(inputdev, SW_TABLET_MODE, !val);
+               input_sync(inputdev);
+       }
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume);
 
index 4e96e8c0b60f83dfb04e835fe0ec4ed40fddb6a6..927c33af67ecc994b46ae2802a25f1cd5bfac5ed 100644 (file)
@@ -211,7 +211,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
                .ident = "Dell Inspiron 5420",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5420"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5420"),
                },
                .driver_data = &quirk_dell_vostro_v130,
        },
@@ -220,7 +220,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
                .ident = "Dell Inspiron 5520",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5520"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5520"),
                },
                .driver_data = &quirk_dell_vostro_v130,
        },
@@ -229,7 +229,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
                .ident = "Dell Inspiron 5720",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5720"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5720"),
                },
                .driver_data = &quirk_dell_vostro_v130,
        },
@@ -238,7 +238,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
                .ident = "Dell Inspiron 7420",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7420"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7420"),
                },
                .driver_data = &quirk_dell_vostro_v130,
        },
@@ -247,7 +247,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
                .ident = "Dell Inspiron 7520",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7520"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"),
                },
                .driver_data = &quirk_dell_vostro_v130,
        },
@@ -256,7 +256,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
                .ident = "Dell Inspiron 7720",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7720"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"),
                },
                .driver_data = &quirk_dell_vostro_v130,
        },
index d2e41735a47b2d6178ef290211e0d13373ece570..7acae3f85f3b180cfe57865e08bb4fbf08bde40d 100644 (file)
@@ -440,11 +440,13 @@ static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_fujitsu_resume(struct device *dev)
 {
        fujitsu_reset();
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume);
 
index d9ab6f64dcec0185148075dca8f4ef8fda1319bf..777c7e3dda51ccb73dd6939717d95904ae5753cc 100644 (file)
@@ -305,10 +305,12 @@ static int hdaps_probe(struct platform_device *dev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int hdaps_resume(struct device *dev)
 {
        return hdaps_device_init();
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume);
 
index f4d91154ad67cca5d260cc681c5f7464dea0e87c..6b9af989632b72a9f2c0b1641a5fdd5600844de0 100644 (file)
@@ -352,7 +352,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int lis3lv02d_suspend(struct device *dev)
 {
        /* make sure the device is off when we suspend */
index 17f6dfd8dbfb093a332d7d9d9ebd572df9b850e7..dae7abe1d711487ce3499232f809f28bc3983232 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/fb.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/i8042.h>
 
 #define IDEAPAD_RFKILL_DEV_NUM (3)
 
@@ -63,8 +64,11 @@ enum {
        VPCCMD_R_3G,
        VPCCMD_W_3G,
        VPCCMD_R_ODD, /* 0x21 */
-       VPCCMD_R_RF = 0x23,
+       VPCCMD_W_FAN,
+       VPCCMD_R_RF,
        VPCCMD_W_RF,
+       VPCCMD_R_FAN = 0x2B,
+       VPCCMD_R_SPECIAL_BUTTONS = 0x31,
        VPCCMD_W_BL_POWER = 0x33,
 };
 
@@ -356,14 +360,46 @@ static ssize_t store_ideapad_cam(struct device *dev,
                return -EINVAL;
        ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state);
        if (ret < 0)
-               return ret;
+               return -EIO;
        return count;
 }
 
 static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam);
 
+static ssize_t show_ideapad_fan(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       unsigned long result;
+
+       if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result))
+               return sprintf(buf, "-1\n");
+       return sprintf(buf, "%lu\n", result);
+}
+
+static ssize_t store_ideapad_fan(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t count)
+{
+       int ret, state;
+
+       if (!count)
+               return 0;
+       if (sscanf(buf, "%i", &state) != 1)
+               return -EINVAL;
+       if (state < 0 || state > 4 || state == 3)
+               return -EINVAL;
+       ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state);
+       if (ret < 0)
+               return -EIO;
+       return count;
+}
+
+static DEVICE_ATTR(fan_mode, 0644, show_ideapad_fan, store_ideapad_fan);
+
 static struct attribute *ideapad_attributes[] = {
        &dev_attr_camera_power.attr,
+       &dev_attr_fan_mode.attr,
        NULL
 };
 
@@ -377,7 +413,10 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
 
        if (attr == &dev_attr_camera_power.attr)
                supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg));
-       else
+       else if (attr == &dev_attr_fan_mode.attr) {
+               unsigned long value;
+               supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value);
+       } else
                supported = true;
 
        return supported ? attr->mode : 0;
@@ -518,9 +557,15 @@ static void ideapad_platform_exit(struct ideapad_private *priv)
  */
 static const struct key_entry ideapad_keymap[] = {
        { KE_KEY, 6,  { KEY_SWITCHVIDEOMODE } },
+       { KE_KEY, 7,  { KEY_CAMERA } },
+       { KE_KEY, 11, { KEY_F16 } },
        { KE_KEY, 13, { KEY_WLAN } },
        { KE_KEY, 16, { KEY_PROG1 } },
        { KE_KEY, 17, { KEY_PROG2 } },
+       { KE_KEY, 64, { KEY_PROG3 } },
+       { KE_KEY, 65, { KEY_PROG4 } },
+       { KE_KEY, 66, { KEY_TOUCHPAD_OFF } },
+       { KE_KEY, 67, { KEY_TOUCHPAD_ON } },
        { KE_END, 0 },
 };
 
@@ -587,6 +632,28 @@ static void ideapad_input_novokey(struct ideapad_private *priv)
                ideapad_input_report(priv, 16);
 }
 
+static void ideapad_check_special_buttons(struct ideapad_private *priv)
+{
+       unsigned long bit, value;
+
+       read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value);
+
+       for (bit = 0; bit < 16; bit++) {
+               if (test_bit(bit, &value)) {
+                       switch (bit) {
+                       case 6:
+                               /* Thermal Management button */
+                               ideapad_input_report(priv, 65);
+                               break;
+                       case 1:
+                               /* OneKey Theater button */
+                               ideapad_input_report(priv, 64);
+                               break;
+                       }
+               }
+       }
+}
+
 /*
  * backlight
  */
@@ -691,6 +758,24 @@ static const struct acpi_device_id ideapad_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
 
+static void ideapad_sync_touchpad_state(struct acpi_device *adevice)
+{
+       struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
+       unsigned long value;
+
+       /* Without reading from EC touchpad LED doesn't switch state */
+       if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) {
+               /* Some IdeaPads don't really turn off touchpad - they only
+                * switch the LED state. We (de)activate KBC AUX port to turn
+                * touchpad off and on. We send KEY_TOUCHPAD_OFF and
+                * KEY_TOUCHPAD_ON to not to get out of sync with LED */
+               unsigned char param;
+               i8042_command(&param, value ? I8042_CMD_AUX_ENABLE :
+                             I8042_CMD_AUX_DISABLE);
+               ideapad_input_report(priv, value ? 67 : 66);
+       }
+}
+
 static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
 {
        int ret, i;
@@ -727,6 +812,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
                        priv->rfk[i] = NULL;
        }
        ideapad_sync_rfk_state(priv);
+       ideapad_sync_touchpad_state(adevice);
 
        if (!acpi_video_backlight_support()) {
                ret = ideapad_backlight_init(priv);
@@ -785,9 +871,14 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
                                ideapad_sync_rfk_state(priv);
                                break;
                        case 13:
+                       case 11:
+                       case 7:
                        case 6:
                                ideapad_input_report(priv, vpc_bit);
                                break;
+                       case 5:
+                               ideapad_sync_touchpad_state(adevice);
+                               break;
                        case 4:
                                ideapad_backlight_notify_brightness(priv);
                                break;
@@ -797,6 +888,9 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
                        case 2:
                                ideapad_backlight_notify_power(priv);
                                break;
+                       case 0:
+                               ideapad_check_special_buttons(priv);
+                               break;
                        default:
                                pr_info("Unknown event: %lu\n", vpc_bit);
                        }
@@ -804,6 +898,15 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
        }
 }
 
+static int ideapad_acpi_resume(struct device *device)
+{
+       ideapad_sync_rfk_state(ideapad_priv);
+       ideapad_sync_touchpad_state(to_acpi_device(device));
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume);
+
 static struct acpi_driver ideapad_acpi_driver = {
        .name = "ideapad_acpi",
        .class = "IdeaPad",
@@ -811,6 +914,7 @@ static struct acpi_driver ideapad_acpi_driver = {
        .ops.add = ideapad_acpi_add,
        .ops.remove = ideapad_acpi_remove,
        .ops.notify = ideapad_acpi_notify,
+       .drv.pm = &ideapad_pm,
        .owner = THIS_MODULE,
 };
 
index f64441844317f513c6ec8db521fb0bad37afbda8..2111dbb7e1e380263b6118218b619089298a39a2 100644 (file)
@@ -85,7 +85,9 @@
 #define MSI_STANDARD_EC_TOUCHPAD_ADDRESS       0xe4
 #define MSI_STANDARD_EC_TOUCHPAD_MASK          (1 << 4)
 
+#ifdef CONFIG_PM_SLEEP
 static int msi_laptop_resume(struct device *device);
+#endif
 static SIMPLE_DEV_PM_OPS(msi_laptop_pm, NULL, msi_laptop_resume);
 
 #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f
@@ -753,6 +755,7 @@ err_bluetooth:
        return retval;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int msi_laptop_resume(struct device *device)
 {
        u8 data;
@@ -773,6 +776,7 @@ static int msi_laptop_resume(struct device *device)
 
        return 0;
 }
+#endif
 
 static int __init msi_laptop_input_setup(void)
 {
index 24480074bcf047c40b219dcf5b055ce829d865d7..8e8caa767d6aec521e65cd42475e3b2950c32907 100644 (file)
@@ -188,7 +188,9 @@ static const struct acpi_device_id pcc_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, pcc_device_ids);
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_pcc_hotkey_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume);
 
 static struct acpi_driver acpi_pcc_driver = {
@@ -540,6 +542,7 @@ static void acpi_pcc_destroy_input(struct pcc_acpi *pcc)
 
 /* kernel module interface */
 
+#ifdef CONFIG_PM_SLEEP
 static int acpi_pcc_hotkey_resume(struct device *dev)
 {
        struct pcc_acpi *pcc;
@@ -556,6 +559,7 @@ static int acpi_pcc_hotkey_resume(struct device *dev)
 
        return acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode);
 }
+#endif
 
 static int acpi_pcc_hotkey_add(struct acpi_device *device)
 {
index 9363969ad07adf65cefe1a6aa918ca47363ca907..daaddec68def7e1c7cb11e4fe6d54e4193943c55 100644 (file)
@@ -140,7 +140,10 @@ MODULE_PARM_DESC(kbd_backlight_timeout,
                 "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
                 "(default: 0)");
 
+#ifdef CONFIG_PM_SLEEP
 static void sony_nc_kbd_backlight_resume(void);
+static void sony_nc_thermal_resume(void);
+#endif
 static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
                unsigned int handle);
 static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd);
@@ -151,7 +154,6 @@ static void sony_nc_battery_care_cleanup(struct platform_device *pd);
 
 static int sony_nc_thermal_setup(struct platform_device *pd);
 static void sony_nc_thermal_cleanup(struct platform_device *pd);
-static void sony_nc_thermal_resume(void);
 
 static int sony_nc_lid_resume_setup(struct platform_device *pd);
 static void sony_nc_lid_resume_cleanup(struct platform_device *pd);
@@ -1431,6 +1433,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd)
        sony_nc_handles_cleanup(pd);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static void sony_nc_function_resume(void)
 {
        unsigned int i, result, bitmask, arg;
@@ -1508,6 +1511,7 @@ static int sony_nc_resume(struct device *dev)
 
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume);
 
@@ -1872,6 +1876,7 @@ static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
        }
 }
 
+#ifdef CONFIG_PM_SLEEP
 static void sony_nc_kbd_backlight_resume(void)
 {
        int ignore = 0;
@@ -1888,6 +1893,7 @@ static void sony_nc_kbd_backlight_resume(void)
                                (kbdbl_ctl->base + 0x200) |
                                (kbdbl_ctl->timeout << 0x10), &ignore);
 }
+#endif
 
 struct battery_care_control {
        struct device_attribute attrs[2];
@@ -2210,6 +2216,7 @@ static void sony_nc_thermal_cleanup(struct platform_device *pd)
        }
 }
 
+#ifdef CONFIG_PM_SLEEP
 static void sony_nc_thermal_resume(void)
 {
        unsigned int status = sony_nc_thermal_mode_get();
@@ -2217,6 +2224,7 @@ static void sony_nc_thermal_resume(void)
        if (status != th_handle->mode)
                sony_nc_thermal_mode_set(th_handle->mode);
 }
+#endif
 
 /* resume on LID open */
 struct snc_lid_resume_control {
@@ -4287,6 +4295,7 @@ err_free_resources:
        return result;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int sony_pic_suspend(struct device *dev)
 {
        if (sony_pic_disable(to_acpi_device(dev)))
@@ -4300,6 +4309,7 @@ static int sony_pic_resume(struct device *dev)
                        spic_dev.cur_ioport, spic_dev.cur_irq);
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume);
 
index e7f73287636cd9bdabb3f0b32104d4b7257e5e69..80e377949314ba37b3f00f09655290ed062349ed 100644 (file)
@@ -922,6 +922,7 @@ static struct input_dev *tpacpi_inputdev;
 static struct mutex tpacpi_inputdev_send_mutex;
 static LIST_HEAD(tpacpi_all_drivers);
 
+#ifdef CONFIG_PM_SLEEP
 static int tpacpi_suspend_handler(struct device *dev)
 {
        struct ibm_struct *ibm, *itmp;
@@ -949,6 +950,7 @@ static int tpacpi_resume_handler(struct device *dev)
 
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(tpacpi_pm,
                         tpacpi_suspend_handler, tpacpi_resume_handler);
@@ -8662,6 +8664,13 @@ static int __must_check __init get_thinkpad_model_data(
                tp->model_str = kstrdup(s, GFP_KERNEL);
                if (!tp->model_str)
                        return -ENOMEM;
+       } else {
+               s = dmi_get_system_info(DMI_BIOS_VENDOR);
+               if (s && !(strnicmp(s, "Lenovo", 6))) {
+                       tp->model_str = kstrdup(s, GFP_KERNEL);
+                       if (!tp->model_str)
+                               return -ENOMEM;
+               }
        }
 
        s = dmi_get_system_info(DMI_PRODUCT_NAME);
index c13ba5bac93f1c594f22ecb1b6e701586793a081..5f1256d5e9332cf45dbdd2031987ea41fe0212cf 100644 (file)
@@ -1296,6 +1296,7 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
        }
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int toshiba_acpi_suspend(struct device *device)
 {
        struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device));
@@ -1317,6 +1318,7 @@ static int toshiba_acpi_resume(struct device *device)
 
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm,
                         toshiba_acpi_suspend, toshiba_acpi_resume);
index 715a43cb5e3c49020c24a07c302ec3792fcce84a..5e5d6317d690095b9f95ff761b2c5d5d0cb5a7d4 100644 (file)
@@ -41,7 +41,9 @@ static const struct acpi_device_id bt_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, bt_device_ids);
 
+#ifdef CONFIG_PM_SLEEP
 static int toshiba_bt_resume(struct device *dev);
+#endif
 static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume);
 
 static struct acpi_driver toshiba_bt_rfkill_driver = {
@@ -90,10 +92,12 @@ static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event)
        toshiba_bluetooth_enable(device->handle);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int toshiba_bt_resume(struct device *dev)
 {
        return toshiba_bluetooth_enable(to_acpi_device(dev)->handle);
 }
+#endif
 
 static int toshiba_bt_rfkill_add(struct acpi_device *device)
 {
index 849c07c13bf6cae790c3e99dfb402f55b88a2a1f..38ba39d7ca7de5cebd5f45163f55035b4f303d6e 100644 (file)
@@ -77,10 +77,12 @@ static void ebook_switch_notify(struct acpi_device *device, u32 event)
        }
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int ebook_switch_resume(struct device *dev)
 {
        return ebook_send_state(to_acpi_device(dev));
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume);
 
index 8fc3808d7a3e8b08b2bc3a8eb53b899f9a41b953..90c5c7357a5041041f518f564849fa98240f50f4 100644 (file)
@@ -1,12 +1,31 @@
 menuconfig PWM
-       bool "PWM Support"
+       bool "Pulse-Width Modulation (PWM) Support"
        depends on !MACH_JZ4740 && !PUV3_PWM
        help
-         This enables PWM support through the generic PWM framework.
-         You only need to enable this, if you also want to enable
-         one or more of the PWM drivers below.
-
-         If unsure, say N.
+         Generic Pulse-Width Modulation (PWM) support.
+
+         In Pulse-Width Modulation, a variation of the width of pulses
+         in a rectangular pulse signal is used as a means to alter the
+         average power of the signal. Applications include efficient
+         power delivery and voltage regulation. In computer systems,
+         PWMs are commonly used to control fans or the brightness of
+         display backlights.
+
+         This framework provides a generic interface to PWM devices
+         within the Linux kernel. On the driver side it provides an API
+         to register and unregister a PWM chip, an abstraction of a PWM
+         controller, that supports one or more PWM devices. Client
+         drivers can request PWM devices and use the generic framework
+         to configure as well as enable and disable them.
+
+         This generic framework replaces the legacy PWM framework which
+         allows only a single driver implementing the required API. Not
+         all legacy implementations have been ported to the framework
+         yet. The framework provides an API that is backward compatible
+         with the legacy framework so that existing client drivers
+         continue to work as expected.
+
+         If unsure, say no.
 
 if PWM
 
index ecb76909e946542ee9beff407c8d2ed1e69ff56e..c6e05078d3adaff05708cc11ce76ea97763a375b 100644 (file)
@@ -129,8 +129,8 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
        return 0;
 }
 
-static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc,
-                                             const struct of_phandle_args *args)
+static struct pwm_device *
+of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
 {
        struct pwm_device *pwm;
 
@@ -149,7 +149,7 @@ static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc,
        return pwm;
 }
 
-void of_pwmchip_add(struct pwm_chip *chip)
+static void of_pwmchip_add(struct pwm_chip *chip)
 {
        if (!chip->dev || !chip->dev->of_node)
                return;
@@ -162,7 +162,7 @@ void of_pwmchip_add(struct pwm_chip *chip)
        of_node_get(chip->dev->of_node);
 }
 
-void of_pwmchip_remove(struct pwm_chip *chip)
+static void of_pwmchip_remove(struct pwm_chip *chip)
 {
        if (chip->dev && chip->dev->of_node)
                of_node_put(chip->dev->of_node);
@@ -527,7 +527,7 @@ void __init pwm_add_table(struct pwm_lookup *table, size_t num)
 struct pwm_device *pwm_get(struct device *dev, const char *con_id)
 {
        struct pwm_device *pwm = ERR_PTR(-EPROBE_DEFER);
-       const char *dev_id = dev ? dev_name(dev): NULL;
+       const char *dev_id = dev ? dev_name(dev) : NULL;
        struct pwm_chip *chip = NULL;
        unsigned int index = 0;
        unsigned int best = 0;
@@ -609,7 +609,7 @@ void pwm_put(struct pwm_device *pwm)
        mutex_lock(&pwm_lock);
 
        if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
-               pr_warning("PWM device already freed\n");
+               pr_warn("PWM device already freed\n");
                goto out;
        }
 
index d10386528c9ce4c684413f750960b23a12225fa8..e5187c0ade9fdde4a4cfd4e8ba55c8b2d337173a 100644 (file)
@@ -225,6 +225,7 @@ static int s3c_pwm_probe(struct platform_device *pdev)
 
        /* calculate base of control bits in TCON */
        s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+       s3c->chip.dev = &pdev->dev;
        s3c->chip.ops = &s3c_pwm_ops;
        s3c->chip.base = -1;
        s3c->chip.npwm = 1;
index 02ce18d5e49a7800e396d2e519692bc1937701bf..057465e0553c7d252b8be7eebf5507deb5a24127 100644 (file)
@@ -187,10 +187,8 @@ static int tegra_pwm_probe(struct platform_device *pdev)
        }
 
        pwm->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
-       if (!pwm->mmio_base) {
-               dev_err(&pdev->dev, "failed to ioremap() region\n");
+       if (!pwm->mmio_base)
                return -EADDRNOTAVAIL;
-       }
 
        platform_set_drvdata(pdev, pwm);
 
index 3c2ad284ee3ecce9a2ee80a140cdd2351b494530..0b66d0f259224f9e7ca679a2759a473708cd3be6 100644 (file)
@@ -192,10 +192,8 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev)
        }
 
        pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
-       if (!pc->mmio_base) {
-               dev_err(&pdev->dev, "failed to ioremap() registers\n");
+       if (!pc->mmio_base)
                return -EADDRNOTAVAIL;
-       }
 
        ret = pwmchip_add(&pc->chip);
        if (ret < 0) {
index 010d232cb0c8b3ab2f586f93aebae056a4d7daf1..c3756d1be19496fdf3dd163787b7e289e9ad70bd 100644 (file)
@@ -371,10 +371,8 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
        }
 
        pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
-       if (!pc->mmio_base) {
-               dev_err(&pdev->dev, "failed to ioremap() registers\n");
+       if (!pc->mmio_base)
                return  -EADDRNOTAVAIL;
-       }
 
        ret = pwmchip_add(&pc->chip);
        if (ret < 0) {
index 548021439f0cc2a71183496750a961d38d91b98d..ad14389b7144a29f142ed9b8e0c9d6df3b2793c0 100644 (file)
@@ -41,7 +41,7 @@ static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask)
                cpu_relax();
 
        if (unlikely(!loops))
-               pr_warning("Waiting for status bits 0x%x to clear timed out\n",
+               pr_warn("Waiting for status bits 0x%x to clear timed out\n",
                           bitmask);
 }
 
index 722246cf20ab2ed592a6a5ed5435b0f1320a5a44..5d44252b7342f3d72dd5060770f2b42ef3bb2e8f 100644 (file)
@@ -435,6 +435,9 @@ static void tsi721_db_dpc(struct work_struct *work)
                                " info %4.4x\n", DBELL_SID(idb.bytes),
                                DBELL_TID(idb.bytes), DBELL_INF(idb.bytes));
                }
+
+               wr_ptr = ioread32(priv->regs +
+                                 TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
        }
 
        iowrite32(rd_ptr & (IDB_QSIZE - 1),
@@ -445,6 +448,10 @@ static void tsi721_db_dpc(struct work_struct *work)
        regval |= TSI721_SR_CHINT_IDBQRCV;
        iowrite32(regval,
                priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
+
+       wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
+       if (wr_ptr != rd_ptr)
+               schedule_work(&priv->idb_work);
 }
 
 /**
@@ -2212,7 +2219,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
                                  const struct pci_device_id *id)
 {
        struct tsi721_device *priv;
-       int i, cap;
+       int cap;
        int err;
        u32 regval;
 
@@ -2232,12 +2239,15 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
        priv->pdev = pdev;
 
 #ifdef DEBUG
+       {
+       int i;
        for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
                dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n",
                        i, (unsigned long long)pci_resource_start(pdev, i),
                        (unsigned long)pci_resource_len(pdev, i),
                        pci_resource_flags(pdev, i));
        }
+       }
 #endif
        /*
         * Verify BAR configuration
index 182b553059c9c82a15f8ff164d64c5d37e708c52..c151fd5d8c974d978c25cf9ded8a9805b333b9af 100644 (file)
@@ -486,6 +486,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
                .id   = AB3100_BUCK,
                .ops  = &regulator_ops_variable_sleepable,
                .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages),
+               .volt_table = ldo_e_buck_typ_voltages,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_time = 1000,
index e9c2085f9dfbe0993c6931c573efb52a660f06a0..ce0fe72a428e811418aa8190c7f534ce1009d5a4 100644 (file)
@@ -64,14 +64,15 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector)
 static int anatop_get_voltage_sel(struct regulator_dev *reg)
 {
        struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
-       u32 val;
+       u32 val, mask;
 
        if (!anatop_reg->control_reg)
                return -ENOTSUPP;
 
        val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg);
-       val = (val & ((1 << anatop_reg->vol_bit_width) - 1)) >>
+       mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
                anatop_reg->vol_bit_shift;
+       val = (val & mask) >> anatop_reg->vol_bit_shift;
 
        return val - anatop_reg->min_bit_val;
 }
index f092588a078c65b3d3951a55a8ef861a44a50146..48385318175a83fe17208e099caa46c07a01d2f2 100644 (file)
@@ -3217,7 +3217,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 
        dev_set_drvdata(&rdev->dev, rdev);
 
-       if (config->ena_gpio) {
+       if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
                ret = gpio_request_one(config->ena_gpio,
                                       GPIOF_DIR_OUT | config->ena_gpio_flags,
                                       rdev_get_name(rdev));
index 34b67bee9323ce00a49b30bb0cf7d9256660b6f8..8b5944f2d7d1ddd36e82e92d786770e469743dfe 100644 (file)
@@ -57,16 +57,17 @@ static int gpio_regulator_get_value(struct regulator_dev *dev)
        return -EINVAL;
 }
 
-static int gpio_regulator_set_value(struct regulator_dev *dev,
-                                       int min, int max, unsigned *selector)
+static int gpio_regulator_set_voltage(struct regulator_dev *dev,
+                                       int min_uV, int max_uV,
+                                       unsigned *selector)
 {
        struct gpio_regulator_data *data = rdev_get_drvdata(dev);
        int ptr, target = 0, state, best_val = INT_MAX;
 
        for (ptr = 0; ptr < data->nr_states; ptr++)
                if (data->states[ptr].value < best_val &&
-                   data->states[ptr].value >= min &&
-                   data->states[ptr].value <= max) {
+                   data->states[ptr].value >= min_uV &&
+                   data->states[ptr].value <= max_uV) {
                        target = data->states[ptr].gpios;
                        best_val = data->states[ptr].value;
                        if (selector)
@@ -85,13 +86,6 @@ static int gpio_regulator_set_value(struct regulator_dev *dev,
        return 0;
 }
 
-static int gpio_regulator_set_voltage(struct regulator_dev *dev,
-                                       int min_uV, int max_uV,
-                                       unsigned *selector)
-{
-       return gpio_regulator_set_value(dev, min_uV, max_uV, selector);
-}
-
 static int gpio_regulator_list_voltage(struct regulator_dev *dev,
                                      unsigned selector)
 {
@@ -106,7 +100,27 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev,
 static int gpio_regulator_set_current_limit(struct regulator_dev *dev,
                                        int min_uA, int max_uA)
 {
-       return gpio_regulator_set_value(dev, min_uA, max_uA, NULL);
+       struct gpio_regulator_data *data = rdev_get_drvdata(dev);
+       int ptr, target = 0, state, best_val = 0;
+
+       for (ptr = 0; ptr < data->nr_states; ptr++)
+               if (data->states[ptr].value > best_val &&
+                   data->states[ptr].value >= min_uA &&
+                   data->states[ptr].value <= max_uA) {
+                       target = data->states[ptr].gpios;
+                       best_val = data->states[ptr].value;
+               }
+
+       if (best_val == 0)
+               return -EINVAL;
+
+       for (ptr = 0; ptr < data->nr_gpios; ptr++) {
+               state = (target & (1 << ptr)) >> ptr;
+               gpio_set_value(data->gpios[ptr].gpio, state);
+       }
+       data->state = target;
+
+       return 0;
 }
 
 static struct regulator_ops gpio_regulator_voltage_ops = {
index 17d19fbbc490156c8507301808863411a5f3135f..46c7e88f8381910004a4e46b0a3a722a1bcd7f28 100644 (file)
@@ -486,9 +486,12 @@ static int palmas_map_voltage_ldo(struct regulator_dev *rdev,
 {
        int ret, voltage;
 
-       ret = ((min_uV - 900000) / 50000) + 1;
-       if (ret < 0)
-               return ret;
+       if (min_uV == 0)
+               return 0;
+
+       if (min_uV < 900000)
+               min_uV = 900000;
+       ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1;
 
        /* Map back into a voltage to verify we're still in bounds */
        voltage = palmas_list_voltage_ldo(rdev, ret);
@@ -586,7 +589,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
 
        addr = palmas_regs_info[id].ctrl_addr;
 
-       ret = palmas_smps_read(palmas, addr, &reg);
+       ret = palmas_ldo_read(palmas, addr, &reg);
        if (ret)
                return ret;
 
@@ -596,7 +599,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
        if (reg_init->mode_sleep)
                reg |= PALMAS_LDO1_CTRL_MODE_SLEEP;
 
-       ret = palmas_smps_write(palmas, addr, reg);
+       ret = palmas_ldo_write(palmas, addr, reg);
        if (ret)
                return ret;
 
@@ -630,7 +633,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
 
        ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, &reg);
        if (ret)
-               goto err_unregister_regulator;
+               return ret;
 
        if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN)
                pmic->smps123 = 1;
@@ -676,7 +679,9 @@ static __devinit int palmas_probe(struct platform_device *pdev)
                case PALMAS_REG_SMPS10:
                        pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES;
                        pmic->desc[id].ops = &palmas_ops_smps10;
-                       pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL;
+                       pmic->desc[id].vsel_reg =
+                                       PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                       PALMAS_SMPS10_CTRL);
                        pmic->desc[id].vsel_mask = SMPS10_VSEL;
                        pmic->desc[id].enable_reg =
                                        PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
@@ -778,8 +783,10 @@ static __devinit int palmas_probe(struct platform_device *pdev)
                        reg_init = pdata->reg_init[id];
                        if (reg_init) {
                                ret = palmas_ldo_init(palmas, id, reg_init);
-                               if (ret)
+                               if (ret) {
+                                       regulator_unregister(pmic->rdev[id]);
                                        goto err_unregister_regulator;
+                               }
                        }
                }
        }
index e6da90ab5153dedd64ebd96137776f652af7d152..19241fc300505f46ff0179470a734238cb7c76fd 100644 (file)
@@ -240,14 +240,16 @@ static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
        TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
        TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
-       TPS6586X_LDO(SM_2, "sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
+       TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
 
        TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3,
                                        ENB, 3, VCC2, 6),
        TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3,
                                        END, 3, VCC1, 6),
-       TPS6586X_DVM(SM_0, "sm0", dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2),
-       TPS6586X_DVM(SM_1, "sm1", dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0),
+       TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1,
+                                       ENB, 1, VCC1, 2),
+       TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0,
+                                       ENB, 0, VCC1, 0),
 };
 
 /*
index 242fe90dc56502ad5c5e1cc0ced284561b0e6df9..77a71a5c17c338708ec112a874e59f15e6212257 100644 (file)
@@ -1037,7 +1037,7 @@ TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300);
 TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300);
 TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300);
 TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300);
-TWL4030_FIXED_LDO(VINTANA2, 0x3f, 1500, 11, 100, 0x08);
+TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08);
 TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08);
 TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08);
 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08);
@@ -1048,7 +1048,6 @@ TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0);
 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0);
 TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0);
 TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0);
-TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0);
 TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34);
 TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10);
 TWL6025_ADJUSTABLE_SMPS(VIO, 0x16);
@@ -1117,7 +1116,7 @@ static const struct of_device_id twl_of_match[] __devinitconst = {
        TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6),
        TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN),
        TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB),
-       TWLFIXED_OF_MATCH("ti,twl4030-vintana2", VINTANA2),
+       TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1),
        TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG),
        TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5),
        TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8),
index eb415bd7649418f1d91b5c45b98fe9411f5171d3..9592b936b71bca1987d19aceba0f6e8b20b165b9 100644 (file)
@@ -582,6 +582,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
 void rtc_update_irq(struct rtc_device *rtc,
                unsigned long num, unsigned long events)
 {
+       pm_stay_awake(rtc->dev.parent);
        schedule_work(&rtc->irqwork);
 }
 EXPORT_SYMBOL_GPL(rtc_update_irq);
@@ -844,6 +845,7 @@ void rtc_timer_do_work(struct work_struct *work)
 
        mutex_lock(&rtc->ops_lock);
 again:
+       pm_relax(rtc->dev.parent);
        __rtc_read_time(rtc, &tm);
        now = rtc_tm_to_ktime(tm);
        while ((next = timerqueue_getnext(&rtc->timerqueue))) {
index 132333d754085d6b06a9c096444a95b708e45893..4267789ca9959413e90df5ea053154e07481d3ce 100644 (file)
@@ -568,7 +568,6 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
                hpet_mask_rtc_irq_bit(RTC_AIE);
 
                CMOS_READ(RTC_INTR_FLAGS);
-               pm_wakeup_event(cmos_rtc.dev, 0);
        }
        spin_unlock(&rtc_lock);
 
index 836118795c0bdb4f0ad5874a3b3dc50dee5ffd69..13e4df63974fa27e7d7acf97c7b94e57ff9722ac 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/rtc.h>
 #include <linux/spi/spi.h>
 #include <linux/module.h>
+#include <linux/sysfs.h>
 
 #define DRV_VERSION "0.6"
 
@@ -292,6 +293,7 @@ static int __devinit pcf2123_probe(struct spi_device *spi)
        pdata->rtc = rtc;
 
        for (i = 0; i < 16; i++) {
+               sysfs_attr_init(&pdata->regs[i].attr.attr);
                sprintf(pdata->regs[i].name, "%1x", i);
                pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR;
                pdata->regs[i].attr.attr.name = pdata->regs[i].name;
index 77074ccd285071f345118079a4f7c3120e6b86a3..fd5c7af04ae5a7d7c1ba30a5822396e6780adc5f 100644 (file)
@@ -122,9 +122,12 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
        tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK);
        tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK);
        if (!pdata->rtc_24h) {
-               tm->tm_hour %= 12;
-               if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM)
+               if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) {
+                       tm->tm_hour -= 20;
+                       tm->tm_hour %= 12;
                        tm->tm_hour += 12;
+               } else
+                       tm->tm_hour %= 12;
        }
        tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK);
        tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK);
index 40a826a7295f7282ec8f05e2dcfd66d8f9601927..2fb2b9ea97ecc11d7e60af84d756b9eaad8dfbed 100644 (file)
@@ -3804,7 +3804,7 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
        case BIODASDSYMMIO:
                return dasd_symm_io(device, argp);
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 }
 
index cceae70279f6407d96f7249f02939de53405ea03..654c6921a6d462f5d9fc0f0b82e9813480b96670 100644 (file)
@@ -498,12 +498,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode,
                break;
        default:
                /* if the discipline has an ioctl method try it. */
-               if (base->discipline->ioctl) {
+               rc = -ENOTTY;
+               if (base->discipline->ioctl)
                        rc = base->discipline->ioctl(block, cmd, argp);
-                       if (rc == -ENOIOCTLCMD)
-                               rc = -EINVAL;
-               } else
-                       rc = -EINVAL;
        }
        dasd_put_device(base);
        return rc;
index 6a6f76bf6e3dad4fae79fedc125bb39b7678b79a..b1032931a1c41237766eaf6c38d7e5032e71e33d 100644 (file)
@@ -242,11 +242,13 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
        switch (sdias_evbuf.event_status) {
                case EVSTATE_ALL_STORED:
                        TRACE("all stored\n");
+                       break;
                case EVSTATE_PART_STORED:
                        TRACE("part stored: %i\n", sdias_evbuf.blk_cnt);
                        break;
                case EVSTATE_NO_DATA:
                        TRACE("no data\n");
+                       /* fall through */
                default:
                        pr_err("Error from SCLP while copying hsa. "
                               "Event status = %x\n",
index 2374468615ed57c147d9ba24489818268765ee70..32c26d795ed06d3a58c43bf3d295d8f75dcf676f 100644 (file)
@@ -324,8 +324,16 @@ int __init register_intc_controller(struct intc_desc *desc)
 
                res = irq_create_identity_mapping(d->domain, irq);
                if (unlikely(res)) {
-                       pr_err("can't get irq_desc for %d\n", irq);
-                       continue;
+                       if (res == -EEXIST) {
+                               res = irq_domain_associate(d->domain, irq, irq);
+                               if (unlikely(res)) {
+                                       pr_err("domain association failure\n");
+                                       continue;
+                               }
+                       } else {
+                               pr_err("can't identity map IRQ %d\n", irq);
+                               continue;
+                       }
                }
 
                intc_irq_xlate_set(irq, vect->enum_id, d);
@@ -345,8 +353,19 @@ int __init register_intc_controller(struct intc_desc *desc)
                         */
                        res = irq_create_identity_mapping(d->domain, irq2);
                        if (unlikely(res)) {
-                               pr_err("can't get irq_desc for %d\n", irq2);
-                               continue;
+                               if (res == -EEXIST) {
+                                       res = irq_domain_associate(d->domain,
+                                                                  irq, irq);
+                                       if (unlikely(res)) {
+                                               pr_err("domain association "
+                                                      "failure\n");
+                                               continue;
+                                       }
+                               } else {
+                                       pr_err("can't identity map IRQ %d\n",
+                                              irq);
+                                       continue;
+                               }
                        }
 
                        vect2->enum_id = 0;
index 6e25ef1bce91f98549e5b514c051fd065deb6fbc..a9f4049c6769316c368a716b0b6707d7082abd25 100644 (file)
@@ -47,6 +47,8 @@ struct bcm63xx_spi {
        /* Platform data */
        u32                     speed_hz;
        unsigned                fifo_size;
+       unsigned int            msg_type_shift;
+       unsigned int            msg_ctl_width;
 
        /* Data buffers */
        const unsigned char     *tx_ptr;
@@ -221,13 +223,20 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
        msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
 
        if (t->rx_buf && t->tx_buf)
-               msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT);
+               msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
        else if (t->rx_buf)
-               msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT);
+               msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
        else if (t->tx_buf)
-               msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT);
-
-       bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
+               msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
+
+       switch (bs->msg_ctl_width) {
+       case 8:
+               bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
+               break;
+       case 16:
+               bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
+               break;
+       }
 
        /* Issue the transfer */
        cmd = SPI_CMD_START_IMMEDIATE;
@@ -406,9 +415,21 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
        master->transfer_one_message = bcm63xx_spi_transfer_one;
        master->mode_bits = MODEBITS;
        bs->speed_hz = pdata->speed_hz;
+       bs->msg_type_shift = pdata->msg_type_shift;
+       bs->msg_ctl_width = pdata->msg_ctl_width;
        bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
        bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
 
+       switch (bs->msg_ctl_width) {
+       case 8:
+       case 16:
+               break;
+       default:
+               dev_err(dev, "unsupported MSG_CTL width: %d\n",
+                        bs->msg_ctl_width);
+               goto out_clk_disable;
+       }
+
        /* Initialize hardware */
        clk_enable(bs->clk);
        bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
@@ -438,7 +459,7 @@ out:
 
 static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)
 {
-       struct spi_master *master = platform_get_drvdata(pdev);
+       struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
        struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 
        spi_unregister_master(master);
@@ -452,6 +473,8 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, 0);
 
+       spi_master_put(master);
+
        return 0;
 }
 
index b2d4b9e4e0105d53dff9a3c747bd535b6732a6b6..764bfee75920f1779aedf9a0bc78d3280fd2045d 100644 (file)
@@ -533,7 +533,6 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)
        iounmap(mcfqspi->iobase);
        release_mem_region(res->start, resource_size(res));
        spi_unregister_master(master);
-       spi_master_put(master);
 
        return 0;
 }
@@ -541,7 +540,7 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int mcfqspi_suspend(struct device *dev)
 {
-       struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+       struct spi_master *master = dev_get_drvdata(dev);
        struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 
        spi_master_suspend(master);
@@ -553,7 +552,7 @@ static int mcfqspi_suspend(struct device *dev)
 
 static int mcfqspi_resume(struct device *dev)
 {
-       struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+       struct spi_master *master = dev_get_drvdata(dev);
        struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 
        spi_master_resume(master);
index bc4778175e343c6a9ebeceac09b0cc543c935bc2..b2fb141da37565de69139fee9743b153fb463699 100644 (file)
@@ -1228,18 +1228,16 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
 
        status = spi_register_master(master);
        if (status < 0)
-               goto err_spi_register;
+               goto disable_pm;
 
        return status;
 
-err_spi_register:
-       spi_master_put(master);
 disable_pm:
        pm_runtime_disable(&pdev->dev);
 dma_chnl_free:
        kfree(mcspi->dma_channels);
 free_master:
-       kfree(master);
+       spi_master_put(master);
        platform_set_drvdata(pdev, NULL);
        return status;
 }
index aab518ec2bbc234c983be65ec84372740c1e5344..6abbe23c39b4751a3da3fb4d940912771c0fbfbe 100644 (file)
@@ -2053,7 +2053,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
        printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n",
               adev->res.start, pl022->virtbase);
 
-       pm_runtime_enable(dev);
        pm_runtime_resume(dev);
 
        pl022->clk = clk_get(&adev->dev, NULL);
index 646a7657fe62fbb545f95fc771b406d0cad6e5f9..d1c8441f638c39e6ad18d3930cd90b22efe268e5 100644 (file)
@@ -826,7 +826,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
                                struct spi_device *spi)
 {
        struct s3c64xx_spi_csinfo *cs;
-       struct device_node *slave_np, *data_np;
+       struct device_node *slave_np, *data_np = NULL;
        u32 fb_delay = 0;
 
        slave_np = spi->dev.of_node;
@@ -1479,40 +1479,40 @@ static const struct dev_pm_ops s3c64xx_spi_pm = {
                           s3c64xx_spi_runtime_resume, NULL)
 };
 
-struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
+static struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
        .fifo_lvl_mask  = { 0x7f },
        .rx_lvl_offset  = 13,
        .tx_st_done     = 21,
        .high_speed     = true,
 };
 
-struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
+static struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
        .fifo_lvl_mask  = { 0x7f, 0x7F },
        .rx_lvl_offset  = 13,
        .tx_st_done     = 21,
 };
 
-struct s3c64xx_spi_port_config s5p64x0_spi_port_config = {
+static struct s3c64xx_spi_port_config s5p64x0_spi_port_config = {
        .fifo_lvl_mask  = { 0x1ff, 0x7F },
        .rx_lvl_offset  = 15,
        .tx_st_done     = 25,
 };
 
-struct s3c64xx_spi_port_config s5pc100_spi_port_config = {
+static struct s3c64xx_spi_port_config s5pc100_spi_port_config = {
        .fifo_lvl_mask  = { 0x7f, 0x7F },
        .rx_lvl_offset  = 13,
        .tx_st_done     = 21,
        .high_speed     = true,
 };
 
-struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
+static struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
        .fifo_lvl_mask  = { 0x1ff, 0x7F },
        .rx_lvl_offset  = 15,
        .tx_st_done     = 25,
        .high_speed     = true,
 };
 
-struct s3c64xx_spi_port_config exynos4_spi_port_config = {
+static struct s3c64xx_spi_port_config exynos4_spi_port_config = {
        .fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
        .rx_lvl_offset  = 15,
        .tx_st_done     = 25,
index c0fdb00783edbf8583e1e0e0a7f5ab32dbf56dda..2359151af7e107925edd58bbd96203a15057ca31 100644 (file)
@@ -168,7 +168,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                        dev->board_ptr = comedi_recognize(driv, it->board_name);
                        if (dev->board_ptr)
                                break;
-               } else if (strcmp(driv->driver_name, it->board_name))
+               } else if (strcmp(driv->driver_name, it->board_name) == 0)
                        break;
                module_put(driv->module);
        }
index 31986608eaf1e932f25f77bcde3685ef66a891a2..6b4d0d68e6372ea1c4d51ac0ebc71e7b78522875 100644 (file)
@@ -1349,9 +1349,6 @@ static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev,
                }
                if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH)
                        continue;
-               if (pci_is_enabled(pcidev))
-                       continue;
-
                if (strcmp(this_board->name, DRV_NAME) == 0) {
                        for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) {
                                if (pcidev->device == boardtypes[i].device_id) {
index da5ee69d2c9da856d2c46740288f72812ac41eef..dfde0f6328dd82b29403c54aba0b5a73d4f603e2 100644 (file)
@@ -301,8 +301,6 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev,
                }
                if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH)
                        continue;
-               if (pci_is_enabled(pcidev))
-                       continue;
                return pcidev;
        }
        dev_err(dev->class_dev,
index 97f06dc8e48d002e00d053f068dccdad69310bbe..2d4cb7f638b2a0eeb6df6c371367ba3ac084b9a4 100644 (file)
@@ -1064,8 +1064,6 @@ static struct pci_dev *pci_dio_find_pci_dev(struct comedi_device *dev,
                            slot != PCI_SLOT(pcidev->devfn))
                                continue;
                }
-               if (pci_is_enabled(pcidev))
-                       continue;
                for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) {
                        if (boardtypes[i].vendor_id != pcidev->vendor)
                                continue;
index ef28385c14825808a88181ec2e3ad8cee7cbca10..cad559a1a730775c1d3d1589b995f6381ac28cb7 100644 (file)
@@ -718,7 +718,8 @@ static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev,
                                continue;
                }
                if (pcidev->vendor != PCI_VENDOR_ID_IOTECH ||
-                   pcidev->device != 0x0409)
+                   pcidev->device != 0x0409 ||
+                   pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH)
                        continue;
 
                for (i = 0; i < ARRAY_SIZE(boardtypes); i++) {
@@ -739,6 +740,7 @@ static int daqboard2000_attach(struct comedi_device *dev,
 {
        struct pci_dev *pcidev;
        struct comedi_subdevice *s;
+       resource_size_t pci_base;
        void *aux_data;
        unsigned int aux_len;
        int result;
@@ -758,11 +760,12 @@ static int daqboard2000_attach(struct comedi_device *dev,
                        "failed to enable PCI device and request regions\n");
                return -EIO;
        }
-       dev->iobase = pci_resource_start(pcidev, 2);
+       dev->iobase = 1;        /* the "detach" needs this */
 
-       devpriv->plx =
-           ioremap(pci_resource_start(pcidev, 0), DAQBOARD2000_PLX_SIZE);
-       devpriv->daq = ioremap(dev->iobase, DAQBOARD2000_DAQ_SIZE);
+       pci_base = pci_resource_start(pcidev, 0);
+       devpriv->plx = ioremap(pci_base, DAQBOARD2000_PLX_SIZE);
+       pci_base = pci_resource_start(pcidev, 2);
+       devpriv->daq = ioremap(pci_base, DAQBOARD2000_DAQ_SIZE);
        if (!devpriv->plx || !devpriv->daq)
                return -ENOMEM;
 
@@ -799,8 +802,6 @@ static int daqboard2000_attach(struct comedi_device *dev,
           printk("Interrupt after is: %x\n", interrupt);
         */
 
-       dev->iobase = (unsigned long)devpriv->daq;
-
        dev->board_name = this_board->name;
 
        s = dev->subdevices + 0;
@@ -824,7 +825,7 @@ static int daqboard2000_attach(struct comedi_device *dev,
 
        s = dev->subdevices + 2;
        result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
-                                 (unsigned long)(dev->iobase + 0x40));
+                                 (unsigned long)(devpriv->daq + 0x40));
 
 out:
        return result;
index a6fe6c9be87eb1599e59f995245f0958095be5a5..3476cda0fff04e8e7df1f3f716f94a2406c799e5 100644 (file)
@@ -804,6 +804,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
        struct pci_dev *pcidev;
        struct comedi_subdevice *s;
+       resource_size_t pci_base;
        int ret = 0;
 
        dev_dbg(dev->class_dev, "dt3000:\n");
@@ -820,9 +821,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        ret = comedi_pci_enable(pcidev, "dt3000");
        if (ret < 0)
                return ret;
+       dev->iobase = 1;        /* the "detach" needs this */
 
-       dev->iobase = pci_resource_start(pcidev, 0);
-       devpriv->io_addr = ioremap(dev->iobase, DT3000_SIZE);
+       pci_base  = pci_resource_start(pcidev, 0);
+       devpriv->io_addr = ioremap(pci_base, DT3000_SIZE);
        if (!devpriv->io_addr)
                return -ENOMEM;
 
index 112fdc3e9c69dddcf64c322194b3d4a3d275b6bf..5aa8be1e7b9217cb6027d3652e134a3f17f1b300 100644 (file)
@@ -1619,9 +1619,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        struct rtdPrivate *devpriv;
        struct pci_dev *pcidev;
        struct comedi_subdevice *s;
+       resource_size_t pci_base;
        int ret;
-       resource_size_t physLas1;       /* data area */
-       resource_size_t physLcfg;       /* PLX9080 */
 #ifdef USE_DMA
        int index;
 #endif
@@ -1655,20 +1654,15 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                printk(KERN_INFO "Failed to enable PCI device and request regions.\n");
                return ret;
        }
-
-       /*
-        * Initialize base addresses
-        */
-       /* Get the physical address from PCI config */
-       dev->iobase = pci_resource_start(pcidev, LAS0_PCIINDEX);
-       physLas1 = pci_resource_start(pcidev, LAS1_PCIINDEX);
-       physLcfg = pci_resource_start(pcidev, LCFG_PCIINDEX);
-       /* Now have the kernel map this into memory */
-       /* ASSUME page aligned */
-       devpriv->las0 = ioremap_nocache(dev->iobase, LAS0_PCISIZE);
-       devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE);
-       devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE);
-
+       dev->iobase = 1;        /* the "detach" needs this */
+
+       /* Initialize the base addresses */
+       pci_base = pci_resource_start(pcidev, LAS0_PCIINDEX);
+       devpriv->las0 = ioremap_nocache(pci_base, LAS0_PCISIZE);
+       pci_base = pci_resource_start(pcidev, LAS1_PCIINDEX);
+       devpriv->las1 = ioremap_nocache(pci_base, LAS1_PCISIZE);
+       pci_base = pci_resource_start(pcidev, LCFG_PCIINDEX);
+       devpriv->lcfg = ioremap_nocache(pci_base, LCFG_PCISIZE);
        if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
                return -ENOMEM;
 
index 848c7ec06976dfdebb68fdea580e6fc1333ede33..11ee83681da7744fc7efdf2cd62063ed0c514311 100644 (file)
@@ -102,6 +102,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
 #define BULK_TIMEOUT 1000
 
 /* constants for "firmware" upload and download */
+#define FIRMWARE "usbdux_firmware.bin"
 #define USBDUXSUB_FIRMWARE 0xA0
 #define VENDOR_DIR_IN  0xC0
 #define VENDOR_DIR_OUT 0x40
@@ -2791,7 +2792,7 @@ static int usbdux_usb_probe(struct usb_interface *uinterf,
 
        ret = request_firmware_nowait(THIS_MODULE,
                                      FW_ACTION_HOTPLUG,
-                                     "usbdux_firmware.bin",
+                                     FIRMWARE,
                                      &udev->dev,
                                      GFP_KERNEL,
                                      usbduxsub + index,
@@ -2850,3 +2851,4 @@ module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE);
index d9911588c10a9f2ecad8cd528a795270071e54f1..8eb41257c6ceca4dd9be11e997f95853dafdcdf2 100644 (file)
@@ -57,6 +57,7 @@
 /*
  * constants for "firmware" upload and download
  */
+#define FIRMWARE               "usbduxfast_firmware.bin"
 #define USBDUXFASTSUB_FIRMWARE 0xA0
 #define VENDOR_DIR_IN          0xC0
 #define VENDOR_DIR_OUT         0x40
@@ -1706,7 +1707,7 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf,
 
        ret = request_firmware_nowait(THIS_MODULE,
                                      FW_ACTION_HOTPLUG,
-                                     "usbduxfast_firmware.bin",
+                                     FIRMWARE,
                                      &udev->dev,
                                      GFP_KERNEL,
                                      usbduxfastsub + index,
@@ -1774,3 +1775,4 @@ module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE);
index 543e604791e2719c16378a05ef8ad31a9ce7208b..f54ab8c2fcfd3604935fac8dd76f18b0f19bd034 100644 (file)
@@ -63,6 +63,7 @@ Status: testing
 #define BULK_TIMEOUT 1000
 
 /* constants for "firmware" upload and download */
+#define FIRMWARE "usbduxsigma_firmware.bin"
 #define USBDUXSUB_FIRMWARE 0xA0
 #define VENDOR_DIR_IN  0xC0
 #define VENDOR_DIR_OUT 0x40
@@ -2780,7 +2781,7 @@ static int usbduxsigma_usb_probe(struct usb_interface *uinterf,
 
        ret = request_firmware_nowait(THIS_MODULE,
                                      FW_ACTION_HOTPLUG,
-                                     "usbduxsigma_firmware.bin",
+                                     FIRMWARE,
                                      &udev->dev,
                                      GFP_KERNEL,
                                      usbduxsub + index,
@@ -2845,3 +2846,4 @@ module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE);
index cee8d48d2af91337006f8b852deddf8614d1adaa..ad2a1096e920c4008a7314f10691aadf4fddfcd9 100644 (file)
@@ -1,6 +1,6 @@
 config CSR_WIFI
        tristate "CSR wireless driver"
-       depends on MMC && CFG80211_WEXT
+       depends on MMC && CFG80211_WEXT && INET
        select WIRELESS_EXT
        select WEXT_PRIV
        help
index 22c3923d55eb34fc31c1313a570498d31dcb95a1..095837285f4fb25732b8986f3d6d25458a9a11a2 100644 (file)
@@ -754,7 +754,7 @@ static ssize_t ad7192_set(struct device *dev,
                else
                        st->mode &= ~AD7192_MODE_ACX;
 
-               ad7192_write_reg(st, AD7192_REG_GPOCON, 3, st->mode);
+               ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode);
                break;
        default:
                ret = -EINVAL;
@@ -798,6 +798,11 @@ static const struct attribute_group ad7195_attribute_group = {
        .attrs = ad7195_attributes,
 };
 
+static unsigned int ad7192_get_temp_scale(bool unipolar)
+{
+       return unipolar ? 2815 * 2 : 2815;
+}
+
 static int ad7192_read_raw(struct iio_dev *indio_dev,
                           struct iio_chan_spec const *chan,
                           int *val,
@@ -824,19 +829,6 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
                *val = (smpl >> chan->scan_type.shift) &
                        ((1 << (chan->scan_type.realbits)) - 1);
 
-               switch (chan->type) {
-               case IIO_VOLTAGE:
-                       if (!unipolar)
-                               *val -= (1 << (chan->scan_type.realbits - 1));
-                       break;
-               case IIO_TEMP:
-                       *val -= 0x800000;
-                       *val /= 2815; /* temp Kelvin */
-                       *val -= 273; /* temp Celsius */
-                       break;
-               default:
-                       return -EINVAL;
-               }
                return IIO_VAL_INT;
 
        case IIO_CHAN_INFO_SCALE:
@@ -848,11 +840,21 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
                        mutex_unlock(&indio_dev->mlock);
                        return IIO_VAL_INT_PLUS_NANO;
                case IIO_TEMP:
-                       *val =  1000;
-                       return IIO_VAL_INT;
+                       *val = 0;
+                       *val2 = 1000000000 / ad7192_get_temp_scale(unipolar);
+                       return IIO_VAL_INT_PLUS_NANO;
                default:
                        return -EINVAL;
                }
+       case IIO_CHAN_INFO_OFFSET:
+               if (!unipolar)
+                       *val = -(1 << (chan->scan_type.realbits - 1));
+               else
+                       *val = 0;
+               /* Kelvin to Celsius */
+               if (chan->type == IIO_TEMP)
+                       *val -= 273 * ad7192_get_temp_scale(unipolar);
+               return IIO_VAL_INT;
        }
 
        return -EINVAL;
@@ -890,7 +892,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
                                }
                                ret = 0;
                        }
-
+               break;
        default:
                ret = -EINVAL;
        }
@@ -942,20 +944,22 @@ static const struct iio_info ad7195_info = {
          .channel = _chan,                                             \
          .channel2 = _chan2,                                           \
          .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |                 \
-         IIO_CHAN_INFO_SCALE_SHARED_BIT,                               \
+         IIO_CHAN_INFO_SCALE_SHARED_BIT |                              \
+         IIO_CHAN_INFO_OFFSET_SHARED_BIT,                              \
          .address = _address,                                          \
          .scan_index = _si,                                            \
-         .scan_type =  IIO_ST('s', 24, 32, 0)}
+         .scan_type =  IIO_ST('u', 24, 32, 0)}
 
 #define AD7192_CHAN(_chan, _address, _si)                              \
        { .type = IIO_VOLTAGE,                                          \
          .indexed = 1,                                                 \
          .channel = _chan,                                             \
          .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |                 \
-         IIO_CHAN_INFO_SCALE_SHARED_BIT,                               \
+         IIO_CHAN_INFO_SCALE_SHARED_BIT |                              \
+         IIO_CHAN_INFO_OFFSET_SHARED_BIT,                              \
          .address = _address,                                          \
          .scan_index = _si,                                            \
-         .scan_type =  IIO_ST('s', 24, 32, 0)}
+         .scan_type =  IIO_ST('u', 24, 32, 0)}
 
 #define AD7192_CHAN_TEMP(_chan, _address, _si)                         \
        { .type = IIO_TEMP,                                             \
@@ -965,7 +969,7 @@ static const struct iio_info ad7195_info = {
          IIO_CHAN_INFO_SCALE_SEPARATE_BIT,                             \
          .address = _address,                                          \
          .scan_index = _si,                                            \
-         .scan_type =  IIO_ST('s', 24, 32, 0)}
+         .scan_type =  IIO_ST('u', 24, 32, 0)}
 
 static struct iio_chan_spec ad7192_channels[] = {
        AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0),
index fd1d855ff57a1c5e2b3786afbc67f5303767a76e..506016f01593c6bdd7a68279f19fa1363b2d21f8 100644 (file)
@@ -76,7 +76,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7298_state *st = iio_priv(indio_dev);
        struct iio_buffer *ring = indio_dev->buffer;
-       s64 time_ns;
+       s64 time_ns = 0;
        __u16 buf[16];
        int b_sent, i;
 
index 1ece2ac8de56965ea0af82c378244da50bdfdece..19ee49c95de49725e4dfdb62c0e4805a9215cce4 100644 (file)
@@ -131,9 +131,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
                        .indexed = 1,
                        .channel = 0,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_type = {
-                               .sign = 's',
+                               .sign = 'u',
                                .realbits = 24,
                                .storagebits = 32,
                                .shift = 8,
@@ -146,9 +147,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
                        .indexed = 1,
                        .channel = 0,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_type = {
-                               .sign = 's',
+                               .sign = 'u',
                                .realbits = 20,
                                .storagebits = 32,
                                .shift = 12,
index 76fdd7145fc5d855544c977560dfc3803baa7b95..112e2b7b5bc4a5b1c459081ec23f624b3eed5f9f 100644 (file)
@@ -563,8 +563,9 @@ static ssize_t ad7793_show_scale_available(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, in-in_scale_available,
-                            S_IRUGO, ad7793_show_scale_available, NULL, 0);
+static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
+               in_voltage-voltage_scale_available, S_IRUGO,
+               ad7793_show_scale_available, NULL, 0);
 
 static struct attribute *ad7793_attributes[] = {
        &iio_dev_attr_sampling_frequency.dev_attr.attr,
@@ -604,9 +605,6 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
                *val = (smpl >> chan->scan_type.shift) &
                        ((1 << (chan->scan_type.realbits)) - 1);
 
-               if (!unipolar)
-                       *val -= (1 << (chan->scan_type.realbits - 1));
-
                return IIO_VAL_INT;
 
        case IIO_CHAN_INFO_SCALE:
@@ -620,25 +618,38 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
                                return IIO_VAL_INT_PLUS_NANO;
                        } else {
                                /* 1170mV / 2^23 * 6 */
-                               scale_uv = (1170ULL * 100000000ULL * 6ULL)
-                                       >> (chan->scan_type.realbits -
-                                           (unipolar ? 0 : 1));
+                               scale_uv = (1170ULL * 100000000ULL * 6ULL);
                        }
                        break;
                case IIO_TEMP:
-                       /* Always uses unity gain and internal ref */
-                       scale_uv = (2500ULL * 100000000ULL)
-                               >> (chan->scan_type.realbits -
-                               (unipolar ? 0 : 1));
+                               /* 1170mV / 0.81 mV/C / 2^23 */
+                               scale_uv = 1444444444444ULL;
                        break;
                default:
                        return -EINVAL;
                }
 
-               *val2 = do_div(scale_uv, 100000000) * 10;
-               *val =  scale_uv;
-
+               scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1));
+               *val = 0;
+               *val2 = scale_uv;
                return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_OFFSET:
+               if (!unipolar)
+                       *val = -(1 << (chan->scan_type.realbits - 1));
+               else
+                       *val = 0;
+
+               /* Kelvin to Celsius */
+               if (chan->type == IIO_TEMP) {
+                       unsigned long long offset;
+                       unsigned int shift;
+
+                       shift = chan->scan_type.realbits - (unipolar ? 0 : 1);
+                       offset = 273ULL << shift;
+                       do_div(offset, 1444);
+                       *val -= offset;
+               }
+               return IIO_VAL_INT;
        }
        return -EINVAL;
 }
@@ -676,7 +687,7 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
                                }
                                ret = 0;
                        }
-
+               break;
        default:
                ret = -EINVAL;
        }
@@ -720,9 +731,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 0,
                        .address = AD7793_CH_AIN1P_AIN1M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 0,
-                       .scan_type = IIO_ST('s', 24, 32, 0)
+                       .scan_type = IIO_ST('u', 24, 32, 0)
                },
                .channel[1] = {
                        .type = IIO_VOLTAGE,
@@ -732,9 +744,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 1,
                        .address = AD7793_CH_AIN2P_AIN2M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 1,
-                       .scan_type = IIO_ST('s', 24, 32, 0)
+                       .scan_type = IIO_ST('u', 24, 32, 0)
                },
                .channel[2] = {
                        .type = IIO_VOLTAGE,
@@ -744,9 +757,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 2,
                        .address = AD7793_CH_AIN3P_AIN3M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 2,
-                       .scan_type = IIO_ST('s', 24, 32, 0)
+                       .scan_type = IIO_ST('u', 24, 32, 0)
                },
                .channel[3] = {
                        .type = IIO_VOLTAGE,
@@ -757,9 +771,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 2,
                        .address = AD7793_CH_AIN1M_AIN1M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 3,
-                       .scan_type = IIO_ST('s', 24, 32, 0)
+                       .scan_type = IIO_ST('u', 24, 32, 0)
                },
                .channel[4] = {
                        .type = IIO_TEMP,
@@ -769,7 +784,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
                        IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
                        .scan_index = 4,
-                       .scan_type = IIO_ST('s', 24, 32, 0),
+                       .scan_type = IIO_ST('u', 24, 32, 0),
                },
                .channel[5] = {
                        .type = IIO_VOLTAGE,
@@ -778,9 +793,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel = 4,
                        .address = AD7793_CH_AVDD_MONITOR,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+                       IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 5,
-                       .scan_type = IIO_ST('s', 24, 32, 0),
+                       .scan_type = IIO_ST('u', 24, 32, 0),
                },
                .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6),
        },
@@ -793,9 +809,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 0,
                        .address = AD7793_CH_AIN1P_AIN1M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 0,
-                       .scan_type = IIO_ST('s', 16, 32, 0)
+                       .scan_type = IIO_ST('u', 16, 32, 0)
                },
                .channel[1] = {
                        .type = IIO_VOLTAGE,
@@ -805,9 +822,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 1,
                        .address = AD7793_CH_AIN2P_AIN2M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 1,
-                       .scan_type = IIO_ST('s', 16, 32, 0)
+                       .scan_type = IIO_ST('u', 16, 32, 0)
                },
                .channel[2] = {
                        .type = IIO_VOLTAGE,
@@ -817,9 +835,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 2,
                        .address = AD7793_CH_AIN3P_AIN3M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 2,
-                       .scan_type = IIO_ST('s', 16, 32, 0)
+                       .scan_type = IIO_ST('u', 16, 32, 0)
                },
                .channel[3] = {
                        .type = IIO_VOLTAGE,
@@ -830,9 +849,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel2 = 2,
                        .address = AD7793_CH_AIN1M_AIN1M,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT,
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 3,
-                       .scan_type = IIO_ST('s', 16, 32, 0)
+                       .scan_type = IIO_ST('u', 16, 32, 0)
                },
                .channel[4] = {
                        .type = IIO_TEMP,
@@ -842,7 +862,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
                        IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
                        .scan_index = 4,
-                       .scan_type = IIO_ST('s', 16, 32, 0),
+                       .scan_type = IIO_ST('u', 16, 32, 0),
                },
                .channel[5] = {
                        .type = IIO_VOLTAGE,
@@ -851,9 +871,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
                        .channel = 4,
                        .address = AD7793_CH_AVDD_MONITOR,
                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+                       IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT,
                        .scan_index = 5,
-                       .scan_type = IIO_ST('s', 16, 32, 0),
+                       .scan_type = IIO_ST('u', 16, 32, 0),
                },
                .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6),
        },
@@ -901,7 +922,7 @@ static int __devinit ad7793_probe(struct spi_device *spi)
        else if (voltage_uv)
                st->int_vref_mv = voltage_uv / 1000;
        else
-               st->int_vref_mv = 2500; /* Build-in ref */
+               st->int_vref_mv = 1170; /* Build-in ref */
 
        spi_set_drvdata(spi, indio_dev);
        st->spi = spi;
index b06fd5b723fa5cb693fd860c43e9232395c57bad..d536756549e684479ac067e5b2caea8832245e9e 100644 (file)
@@ -189,7 +189,7 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode");
 // Static vars definitions
 //
 
-static struct usb_device_id vt6656_table[] __devinitdata = {
+static struct usb_device_id vt6656_table[] = {
        {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
        {}
 };
index ef360547ececf262841ad46068028fb7fd40f4d2..0ca857ac473e91e3171c0963f85a4be214b64947 100644 (file)
@@ -25,7 +25,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION("0.1");
 
-static const struct usb_device_id wb35_table[] __devinitconst = {
+static const struct usb_device_id wb35_table[] = {
        { USB_DEVICE(0x0416, 0x0035) },
        { USB_DEVICE(0x18E8, 0x6201) },
        { USB_DEVICE(0x18E8, 0x6206) },
index 6e32ff6f2fa0ce4ead43073d87bedc77d3ffee2c..5552fa7426bc9b317da906dec2e395bbf854ae78 100644 (file)
@@ -673,8 +673,15 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)
        struct scsi_device *sd = pdv->pdv_sd;
        int result;
        struct pscsi_plugin_task *pt = cmd->priv;
-       unsigned char *cdb = &pt->pscsi_cdb[0];
+       unsigned char *cdb;
+       /*
+        * Special case for REPORT_LUNs handling where pscsi_plugin_task has
+        * not been allocated because TCM is handling the emulation directly.
+        */
+       if (!pt)
+               return 0;
 
+       cdb = &pt->pscsi_cdb[0];
        result = pt->pscsi_result;
        /*
         * Hack to make sure that Write-Protect modepage is set if R/O mode is
index 0eaae23d12b576547fa51f25ed8f05579f6ec646..4de3186dc44e99672d3666a24ec145e058183691 100644 (file)
@@ -1165,8 +1165,6 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
                        " 0x%02x\n", cmd->se_tfo->get_fabric_name(),
                                cmd->data_length, size, cmd->t_task_cdb[0]);
 
-               cmd->cmd_spdtl = size;
-
                if (cmd->data_direction == DMA_TO_DEVICE) {
                        pr_err("Rejecting underflow/overflow"
                                        " WRITE data\n");
@@ -2294,9 +2292,9 @@ transport_generic_get_mem(struct se_cmd *cmd)
        return 0;
 
 out:
-       while (i >= 0) {
-               __free_page(sg_page(&cmd->t_data_sg[i]));
+       while (i > 0) {
                i--;
+               __free_page(sg_page(&cmd->t_data_sg[i]));
        }
        kfree(cmd->t_data_sg);
        cmd->t_data_sg = NULL;
@@ -2323,9 +2321,12 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
                if (ret < 0)
                        goto out_fail;
        }
-
-       /* Workaround for handling zero-length control CDBs */
-       if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->data_length) {
+       /*
+        * If this command doesn't have any payload and we don't have to call
+        * into the fabric for data transfers, go ahead and complete it right
+        * away.
+        */
+       if (!cmd->data_length) {
                spin_lock_irq(&cmd->t_state_lock);
                cmd->t_state = TRANSPORT_COMPLETE;
                cmd->transport_state |= CMD_T_ACTIVE;
index c5eb3c33c3dbed83db4b647c07619e44f320659f..eea69358ced3a5c8eec138eb403b2347905c801e 100644 (file)
@@ -131,6 +131,7 @@ extern struct list_head ft_lport_list;
 extern struct mutex ft_lport_lock;
 extern struct fc4_prov ft_prov;
 extern struct target_fabric_configfs *ft_configfs;
+extern unsigned int ft_debug_logging;
 
 /*
  * Fabric methods.
index b9cb5006177e22166732032468bf8d0a733299f8..823e6922249d07e3122973ebdb370cd4994704a0 100644 (file)
@@ -48,7 +48,7 @@
 /*
  * Dump cmd state for debugging.
  */
-void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
+static void _ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
 {
        struct fc_exch *ep;
        struct fc_seq *sp;
@@ -80,6 +80,12 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
        }
 }
 
+void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
+{
+       if (unlikely(ft_debug_logging))
+               _ft_dump_cmd(cmd, caller);
+}
+
 static void ft_free_cmd(struct ft_cmd *cmd)
 {
        struct fc_frame *fp;
index 87901fa74dd7e1acb136cbdf0607aa4b8eeeb652..3c9e5b57caabea23567192e2d2f85843ca6bc70f 100644 (file)
@@ -456,7 +456,9 @@ static void ft_prlo(struct fc_rport_priv *rdata)
        struct ft_tport *tport;
 
        mutex_lock(&ft_lport_lock);
-       tport = rcu_dereference(rdata->local_port->prov[FC_TYPE_FCP]);
+       tport = rcu_dereference_protected(rdata->local_port->prov[FC_TYPE_FCP],
+                                         lockdep_is_held(&ft_lport_lock));
+
        if (!tport) {
                mutex_unlock(&ft_lport_lock);
                return;
index 070b442c1f81abb08ffee6cd69e3ffe0ab87b209..4720b4ba096a5d7b2efc6cca8aca82dd75c127e2 100644 (file)
@@ -160,10 +160,12 @@ config SERIAL_KS8695_CONSOLE
 
 config SERIAL_CLPS711X
        tristate "CLPS711X serial port support"
-       depends on ARM && ARCH_CLPS711X
+       depends on ARCH_CLPS711X
        select SERIAL_CORE
+       default y
        help
-         ::: To be written :::
+         This enables the driver for the on-chip UARTs of the Cirrus
+         Logic EP711x/EP721x/EP731x processors.
 
 config SERIAL_CLPS711X_CONSOLE
        bool "Support for console on CLPS711X serial port"
@@ -173,9 +175,7 @@ config SERIAL_CLPS711X_CONSOLE
          Even if you say Y here, the currently visible virtual console
          (/dev/tty0) will still be used as the system console by default, but
          you can alter that using a kernel command line option such as
-         "console=ttyCL1". (Try "man bootparam" or see the documentation of
-         your boot loader (lilo or loadlin) about how to pass options to the
-         kernel at boot time.)
+         "console=ttyCL1".
 
 config SERIAL_SAMSUNG
        tristate "Samsung SoC serial support"
index 144cd3987d4cb5c6c108d0488a41a0e1ba8eca73..3ad079ffd049cbce0441d730e28f27bbfe4aeb4b 100644 (file)
@@ -1331,7 +1331,7 @@ static const struct spi_device_id ifx_id_table[] = {
 MODULE_DEVICE_TABLE(spi, ifx_id_table);
 
 /* spi operations */
-static const struct spi_driver ifx_spi_driver = {
+static struct spi_driver ifx_spi_driver = {
        .driver = {
                .name = DRVNAME,
                .pm = &ifx_spi_pm,
index 2e341b81ff891b632e5cbee6d2337aba0f10cfe8..3a667eed63d6086c017c8abcc83a597850ec4966 100644 (file)
@@ -73,6 +73,7 @@
 #define AUART_CTRL0_CLKGATE                    (1 << 30)
 
 #define AUART_CTRL2_CTSEN                      (1 << 15)
+#define AUART_CTRL2_RTSEN                      (1 << 14)
 #define AUART_CTRL2_RTS                                (1 << 11)
 #define AUART_CTRL2_RXE                                (1 << 9)
 #define AUART_CTRL2_TXE                                (1 << 8)
@@ -259,9 +260,12 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)
 
        u32 ctrl = readl(u->membase + AUART_CTRL2);
 
-       ctrl &= ~AUART_CTRL2_RTS;
-       if (mctrl & TIOCM_RTS)
-               ctrl |= AUART_CTRL2_RTS;
+       ctrl &= ~AUART_CTRL2_RTSEN;
+       if (mctrl & TIOCM_RTS) {
+               if (u->state->port.flags & ASYNC_CTS_FLOW)
+                       ctrl |= AUART_CTRL2_RTSEN;
+       }
+
        s->ctrl = mctrl;
        writel(ctrl, u->membase + AUART_CTRL2);
 }
@@ -359,9 +363,9 @@ static void mxs_auart_settermios(struct uart_port *u,
 
        /* figure out the hardware flow control settings */
        if (cflag & CRTSCTS)
-               ctrl2 |= AUART_CTRL2_CTSEN;
+               ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN;
        else
-               ctrl2 &= ~AUART_CTRL2_CTSEN;
+               ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN);
 
        /* set baud rate */
        baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
index 654755a990dfc30cac559567e260b17978bbc54b..333c8d012b0e32c9e40881fd1defff6cc52b8b10 100644 (file)
@@ -1348,10 +1348,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser)
 static int pmz_poll_get_char(struct uart_port *port)
 {
        struct uart_pmac_port *uap = (struct uart_pmac_port *)port;
+       int tries = 2;
 
-       while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0)
-               udelay(5);
-       return read_zsdata(uap);
+       while (tries) {
+               if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0)
+                       return read_zsdata(uap);
+               if (tries--)
+                       udelay(5);
+       }
+
+       return NO_POLL_CHAR;
 }
 
 static void pmz_poll_put_char(struct uart_port *port, unsigned char c)
index a7773a3e02b11cedabb884a74b11ef366a4e342e..7065df6036ca27ceb96d5acecc93128b73f96460 100644 (file)
@@ -13,7 +13,7 @@ config USB_ARCH_HAS_OHCI
        default y if PXA3xx
        default y if ARCH_EP93XX
        default y if ARCH_AT91
-       default y if ARCH_PNX4008 && I2C
+       default y if ARCH_PNX4008
        default y if MFD_TC6393XB
        default y if ARCH_W90X900
        default y if ARCH_DAVINCI_DA8XX
index 8337fb5d988de6cc68c7e06aa44341d09cd67c62..47e499c9c0b62734fa52adc44033e1b0d4bbda48 100644 (file)
@@ -1,9 +1,9 @@
 config USB_CHIPIDEA
        tristate "ChipIdea Highspeed Dual Role Controller"
-       depends on USB
+       depends on USB || USB_GADGET
        help
-          Say Y here if your system has a dual role high speed USB
-          controller based on ChipIdea silicon IP. Currently, only the
+         Say Y here if your system has a dual role high speed USB
+         controller based on ChipIdea silicon IP. Currently, only the
          peripheral mode is supported.
 
          When compiled dynamically, the module will be called ci-hdrc.ko.
@@ -12,7 +12,7 @@ if USB_CHIPIDEA
 
 config USB_CHIPIDEA_UDC
        bool "ChipIdea device controller"
-       depends on USB_GADGET
+       depends on USB_GADGET=y || USB_GADGET=USB_CHIPIDEA
        select USB_GADGET_DUALSPEED
        help
          Say Y here to enable device controller functionality of the
@@ -20,6 +20,7 @@ config USB_CHIPIDEA_UDC
 
 config USB_CHIPIDEA_HOST
        bool "ChipIdea host controller"
+       depends on USB=y || USB=USB_CHIPIDEA
        select USB_EHCI_ROOT_HUB_TT
        help
          Say Y here to enable host controller functionality of the
index 56d6bf66848894b76564ba452e00d6cf37f13416..f763ed7ba91ea08a4c0dd0166558ccb6683447d5 100644 (file)
@@ -1104,7 +1104,8 @@ skip_normal_probe:
        }
 
 
-       if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
+       if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 ||
+           control_interface->cur_altsetting->desc.bNumEndpoints == 0)
                return -EINVAL;
 
        epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
index ee0ebacf8227df070dc4a40daf8cd873007ca296..89dcf155d57e9e75fec8919e120fe6fcaa4b0136 100644 (file)
@@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void)
        writel(FLAG_CF, &ehci_regs->configured_flag);
 
        /* Wait until the controller is no longer halted */
-       loop = 10;
+       loop = 1000;
        do {
                status = readl(&ehci_regs->status);
                if (!(status & STS_HALT))
index 90e82e288eb9f25b6aad4842db1a001f174a0515..0e52309261543208f50a0ecd71e2d158ac256415 100644 (file)
@@ -669,6 +669,8 @@ static int eth_stop(struct net_device *net)
        spin_lock_irqsave(&dev->lock, flags);
        if (dev->port_usb) {
                struct gether   *link = dev->port_usb;
+               const struct usb_endpoint_descriptor *in;
+               const struct usb_endpoint_descriptor *out;
 
                if (link->close)
                        link->close(link);
@@ -682,10 +684,14 @@ static int eth_stop(struct net_device *net)
                 * their own pace; the network stack can handle old packets.
                 * For the moment we leave this here, since it works.
                 */
+               in = link->in_ep->desc;
+               out = link->out_ep->desc;
                usb_ep_disable(link->in_ep);
                usb_ep_disable(link->out_ep);
                if (netif_carrier_ok(net)) {
                        DBG(dev, "host still using in/out endpoints\n");
+                       link->in_ep->desc = in;
+                       link->out_ep->desc = out;
                        usb_ep_enable(link->in_ep);
                        usb_ep_enable(link->out_ep);
                }
index bb55eb4a7d485b806e69ba0c5141912f04bd6791..d7fe287d067803e484d56efdf53060546634ea1e 100644 (file)
 #define        EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT             8
 #define        EHCI_INSNREG05_ULPI_WRDATA_SHIFT                0
 
-/* Errata i693 */
-static struct clk      *utmi_p1_fck;
-static struct clk      *utmi_p2_fck;
-static struct clk      *xclk60mhsp1_ck;
-static struct clk      *xclk60mhsp2_ck;
-static struct clk      *usbhost_p1_fck;
-static struct clk      *usbhost_p2_fck;
-static struct clk      *init_60m_fclk;
-
 /*-------------------------------------------------------------------------*/
 
 static const struct hc_driver ehci_omap_hc_driver;
@@ -80,40 +71,6 @@ static inline u32 ehci_read(void __iomem *base, u32 reg)
        return __raw_readl(base + reg);
 }
 
-/* Erratum i693 workaround sequence */
-static void omap_ehci_erratum_i693(struct ehci_hcd *ehci)
-{
-       int ret = 0;
-
-       /* Switch to the internal 60 MHz clock */
-       ret = clk_set_parent(utmi_p1_fck, init_60m_fclk);
-       if (ret != 0)
-               ehci_err(ehci, "init_60m_fclk set parent"
-                       "failed error:%d\n", ret);
-
-       ret = clk_set_parent(utmi_p2_fck, init_60m_fclk);
-       if (ret != 0)
-               ehci_err(ehci, "init_60m_fclk set parent"
-                       "failed error:%d\n", ret);
-
-       clk_enable(usbhost_p1_fck);
-       clk_enable(usbhost_p2_fck);
-
-       /* Wait 1ms and switch back to the external clock */
-       mdelay(1);
-       ret = clk_set_parent(utmi_p1_fck, xclk60mhsp1_ck);
-       if (ret != 0)
-               ehci_err(ehci, "xclk60mhsp1_ck set parent"
-                       "failed error:%d\n", ret);
-
-       ret = clk_set_parent(utmi_p2_fck, xclk60mhsp2_ck);
-       if (ret != 0)
-               ehci_err(ehci, "xclk60mhsp2_ck set parent"
-                       "failed error:%d\n", ret);
-
-       clk_disable(usbhost_p1_fck);
-       clk_disable(usbhost_p2_fck);
-}
 
 static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port)
 {
@@ -195,50 +152,6 @@ static int omap_ehci_init(struct usb_hcd *hcd)
        return rc;
 }
 
-static int omap_ehci_hub_control(
-       struct usb_hcd  *hcd,
-       u16             typeReq,
-       u16             wValue,
-       u16             wIndex,
-       char            *buf,
-       u16             wLength
-)
-{
-       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-       u32 __iomem *status_reg = &ehci->regs->port_status[
-                               (wIndex & 0xff) - 1];
-       u32             temp;
-       unsigned long   flags;
-       int             retval = 0;
-
-       spin_lock_irqsave(&ehci->lock, flags);
-
-       if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
-               temp = ehci_readl(ehci, status_reg);
-               if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
-                       retval = -EPIPE;
-                       goto done;
-               }
-
-               temp &= ~PORT_WKCONN_E;
-               temp |= PORT_WKDISC_E | PORT_WKOC_E;
-               ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
-
-               omap_ehci_erratum_i693(ehci);
-
-               set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
-               goto done;
-       }
-
-       spin_unlock_irqrestore(&ehci->lock, flags);
-
-       /* Handle the hub control events here */
-       return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
-done:
-       spin_unlock_irqrestore(&ehci->lock, flags);
-       return retval;
-}
-
 static void disable_put_regulator(
                struct ehci_hcd_omap_platform_data *pdata)
 {
@@ -351,79 +264,9 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
                goto err_pm_runtime;
        }
 
-       /* get clocks */
-       utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
-       if (IS_ERR(utmi_p1_fck)) {
-               ret = PTR_ERR(utmi_p1_fck);
-               dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
-               goto err_add_hcd;
-       }
-
-       xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
-       if (IS_ERR(xclk60mhsp1_ck)) {
-               ret = PTR_ERR(xclk60mhsp1_ck);
-               dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
-               goto err_utmi_p1_fck;
-       }
-
-       utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
-       if (IS_ERR(utmi_p2_fck)) {
-               ret = PTR_ERR(utmi_p2_fck);
-               dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
-               goto err_xclk60mhsp1_ck;
-       }
-
-       xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
-       if (IS_ERR(xclk60mhsp2_ck)) {
-               ret = PTR_ERR(xclk60mhsp2_ck);
-               dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
-               goto err_utmi_p2_fck;
-       }
-
-       usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
-       if (IS_ERR(usbhost_p1_fck)) {
-               ret = PTR_ERR(usbhost_p1_fck);
-               dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
-               goto err_xclk60mhsp2_ck;
-       }
-
-       usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
-       if (IS_ERR(usbhost_p2_fck)) {
-               ret = PTR_ERR(usbhost_p2_fck);
-               dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
-               goto err_usbhost_p1_fck;
-       }
-
-       init_60m_fclk = clk_get(dev, "init_60m_fclk");
-       if (IS_ERR(init_60m_fclk)) {
-               ret = PTR_ERR(init_60m_fclk);
-               dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-               goto err_usbhost_p2_fck;
-       }
 
        return 0;
 
-err_usbhost_p2_fck:
-       clk_put(usbhost_p2_fck);
-
-err_usbhost_p1_fck:
-       clk_put(usbhost_p1_fck);
-
-err_xclk60mhsp2_ck:
-       clk_put(xclk60mhsp2_ck);
-
-err_utmi_p2_fck:
-       clk_put(utmi_p2_fck);
-
-err_xclk60mhsp1_ck:
-       clk_put(xclk60mhsp1_ck);
-
-err_utmi_p1_fck:
-       clk_put(utmi_p1_fck);
-
-err_add_hcd:
-       usb_remove_hcd(hcd);
-
 err_pm_runtime:
        disable_put_regulator(pdata);
        pm_runtime_put_sync(dev);
@@ -454,14 +297,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
        iounmap(hcd->regs);
        usb_put_hcd(hcd);
 
-       clk_put(utmi_p1_fck);
-       clk_put(utmi_p2_fck);
-       clk_put(xclk60mhsp1_ck);
-       clk_put(xclk60mhsp2_ck);
-       clk_put(usbhost_p1_fck);
-       clk_put(usbhost_p2_fck);
-       clk_put(init_60m_fclk);
-
        pm_runtime_put_sync(dev);
        pm_runtime_disable(dev);
 
@@ -532,7 +367,7 @@ static const struct hc_driver ehci_omap_hc_driver = {
         * root hub support
         */
        .hub_status_data        = ehci_hub_status_data,
-       .hub_control            = omap_ehci_hub_control,
+       .hub_control            = ehci_hub_control,
        .bus_suspend            = ehci_bus_suspend,
        .bus_resume             = ehci_bus_resume,
 
index 58c96bd50d22853d10a8ac423b39acf0e375eeb7..0c9e43cfaff547128aa87f948e986f58500de089 100644 (file)
@@ -40,7 +40,7 @@ static int ehci_sead3_setup(struct usb_hcd *hcd)
        ehci->need_io_watchdog = 0;
 
        /* Set burst length to 16 words. */
-       ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]);
+       ehci_writel(ehci, 0x1010, &ehci->regs->reserved1[1]);
 
        return ret;
 }
index 950e95efa381bce88d7c6c148ac90609755ee83b..26dedb30ad0be75199dbaf81b3c18ec6aa3e961f 100644 (file)
@@ -799,11 +799,12 @@ static int tegra_ehci_remove(struct platform_device *pdev)
 #endif
 
        usb_remove_hcd(hcd);
-       usb_put_hcd(hcd);
 
        tegra_usb_phy_close(tegra->phy);
        iounmap(hcd->regs);
 
+       usb_put_hcd(hcd);
+
        clk_disable_unprepare(tegra->clk);
        clk_put(tegra->clk);
 
index 2ed112d3e1595d45c5d6a8ab4053c883310124d1..256326322cfd8b96dd5ee686c0f1a769be52a074 100644 (file)
@@ -543,12 +543,12 @@ static void postproc_ep(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep)
                            usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid,
                            short_ok ? "" : "not_",
                            PTD_GET_COUNT(ptd), ep->maxpacket, len);
+                       /* save the data underrun error code for later and
+                        * proceed with the status stage
+                        */
+                       urb->actual_length += PTD_GET_COUNT(ptd);
                        if (usb_pipecontrol(urb->pipe)) {
                                ep->nextpid = USB_PID_ACK;
-                               /* save the data underrun error code for later and
-                                * proceed with the status stage
-                                */
-                               urb->actual_length += PTD_GET_COUNT(ptd);
                                BUG_ON(urb->actual_length > urb->transfer_buffer_length);
 
                                if (urb->status == -EINPROGRESS)
index e7d75d295988c3fabc64c36fdf6d1db23f70b7d0..f8b2d91851f7cbfd509aa35b98119acdc544e948 100644 (file)
@@ -403,8 +403,6 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
-       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
-
        usb_remove_hcd(hcd);
        if (!IS_ERR_OR_NULL(hcd->phy)) {
                (void) otg_set_host(hcd->phy->otg, 0);
index df0828cb2aa328ecf06cb37cb1a6981fa41d52f3..c5e9e4a76f148d4eed0c4785cf46fb38d143a074 100644 (file)
@@ -800,6 +800,13 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
 }
 EXPORT_SYMBOL_GPL(usb_enable_xhci_ports);
 
+void usb_disable_xhci_ports(struct pci_dev *xhci_pdev)
+{
+       pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, 0x0);
+       pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, 0x0);
+}
+EXPORT_SYMBOL_GPL(usb_disable_xhci_ports);
+
 /**
  * PCI Quirks for xHCI.
  *
index b1002a8ef96f58fc46039d6c37b4bcca18d056cb..ef004a5de20f176c27801f83bd9ae2456570e6b1 100644 (file)
@@ -10,6 +10,7 @@ void usb_amd_quirk_pll_disable(void);
 void usb_amd_quirk_pll_enable(void);
 bool usb_is_intel_switchable_xhci(struct pci_dev *pdev);
 void usb_enable_xhci_ports(struct pci_dev *xhci_pdev);
+void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
 #else
 static inline void usb_amd_quirk_pll_disable(void) {}
 static inline void usb_amd_quirk_pll_enable(void) {}
index 18b231b0c5d373afbec7efde87faed879ca26889..9bfd4ca1153c32cd51d3468608948a31a3a08953 100644 (file)
@@ -94,11 +94,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                xhci->quirks |= XHCI_EP_LIMIT_QUIRK;
                xhci->limit_active_eps = 64;
                xhci->quirks |= XHCI_SW_BW_CHECKING;
+               /*
+                * PPT desktop boards DH77EB and DH77DF will power back on after
+                * a few seconds of being shutdown.  The fix for this is to
+                * switch the ports from xHCI to EHCI on shutdown.  We can't use
+                * DMI information to find those particular boards (since each
+                * vendor will change the board name), so we have to key off all
+                * PPT chipsets.
+                */
+               xhci->quirks |= XHCI_SPURIOUS_REBOOT;
        }
        if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
                        pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
                xhci->quirks |= XHCI_RESET_ON_RESUME;
                xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
+               xhci->quirks |= XHCI_TRUST_TX_LENGTH;
        }
        if (pdev->vendor == PCI_VENDOR_ID_VIA)
                xhci->quirks |= XHCI_RESET_ON_RESUME;
index 8275645889da4ce779c08c88ac4ea06473f222e0..643c2f3f3e738e1785447fd2d8c27559e0fb0d24 100644 (file)
@@ -145,29 +145,37 @@ static void next_trb(struct xhci_hcd *xhci,
  */
 static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
 {
-       union xhci_trb *next;
        unsigned long long addr;
 
        ring->deq_updates++;
 
-       /* If this is not event ring, there is one more usable TRB */
+       /*
+        * If this is not event ring, and the dequeue pointer
+        * is not on a link TRB, there is one more usable TRB
+        */
        if (ring->type != TYPE_EVENT &&
                        !last_trb(xhci, ring, ring->deq_seg, ring->dequeue))
                ring->num_trbs_free++;
-       next = ++(ring->dequeue);
 
-       /* Update the dequeue pointer further if that was a link TRB or we're at
-        * the end of an event ring segment (which doesn't have link TRBS)
-        */
-       while (last_trb(xhci, ring, ring->deq_seg, next)) {
-               if (ring->type == TYPE_EVENT && last_trb_on_last_seg(xhci,
-                               ring, ring->deq_seg, next)) {
-                       ring->cycle_state = (ring->cycle_state ? 0 : 1);
+       do {
+               /*
+                * Update the dequeue pointer further if that was a link TRB or
+                * we're at the end of an event ring segment (which doesn't have
+                * link TRBS)
+                */
+               if (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) {
+                       if (ring->type == TYPE_EVENT &&
+                                       last_trb_on_last_seg(xhci, ring,
+                                               ring->deq_seg, ring->dequeue)) {
+                               ring->cycle_state = (ring->cycle_state ? 0 : 1);
+                       }
+                       ring->deq_seg = ring->deq_seg->next;
+                       ring->dequeue = ring->deq_seg->trbs;
+               } else {
+                       ring->dequeue++;
                }
-               ring->deq_seg = ring->deq_seg->next;
-               ring->dequeue = ring->deq_seg->trbs;
-               next = ring->dequeue;
-       }
+       } while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue));
+
        addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue);
 }
 
@@ -2073,8 +2081,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
                        trb_comp_code = COMP_SHORT_TX;
                else
-                       xhci_warn(xhci, "WARN Successful completion on short TX: "
-                                       "needs XHCI_TRUST_TX_LENGTH quirk?\n");
+                       xhci_warn_ratelimited(xhci,
+                                       "WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk?\n");
        case COMP_SHORT_TX:
                break;
        case COMP_STOP:
index 7648b2d4b268182b4e9097db1bab61b97b86a0d4..c59d5b5b6c7d227a8005ca520e8b9badad5207b1 100644 (file)
@@ -166,7 +166,7 @@ int xhci_reset(struct xhci_hcd *xhci)
        xhci_writel(xhci, command, &xhci->op_regs->command);
 
        ret = handshake(xhci, &xhci->op_regs->command,
-                       CMD_RESET, 0, 250 * 1000);
+                       CMD_RESET, 0, 10 * 1000 * 1000);
        if (ret)
                return ret;
 
@@ -175,7 +175,8 @@ int xhci_reset(struct xhci_hcd *xhci)
         * xHCI cannot write to any doorbells or operational registers other
         * than status until the "Controller Not Ready" flag is cleared.
         */
-       ret = handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
+       ret = handshake(xhci, &xhci->op_regs->status,
+                       STS_CNR, 0, 10 * 1000 * 1000);
 
        for (i = 0; i < 2; ++i) {
                xhci->bus_state[i].port_c_suspend = 0;
@@ -658,6 +659,9 @@ void xhci_shutdown(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
+       if (xhci->quirks && XHCI_SPURIOUS_REBOOT)
+               usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
+
        spin_lock_irq(&xhci->lock);
        xhci_halt(xhci);
        spin_unlock_irq(&xhci->lock);
index 55c0785810c99fb5286e29d39cd4d7ff2b98addb..c713256297acd073e7589f2fdfd936390fb8bbd0 100644 (file)
@@ -1494,6 +1494,7 @@ struct xhci_hcd {
 #define XHCI_TRUST_TX_LENGTH   (1 << 10)
 #define XHCI_LPM_SUPPORT       (1 << 11)
 #define XHCI_INTEL_HOST                (1 << 12)
+#define XHCI_SPURIOUS_REBOOT   (1 << 13)
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
        /* There are two roothubs to keep track of bus suspend info for */
@@ -1537,6 +1538,8 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
        dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
 #define xhci_warn(xhci, fmt, args...) \
        dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
+#define xhci_warn_ratelimited(xhci, fmt, args...) \
+       dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
 
 /* TODO: copied from ehci.h - can be refactored? */
 /* xHCI spec says all registers are little endian */
index ff08015b230c8064b81be97e8946b0c8bf91b108..ae794b90766ba627c94712f52a899ba244f95479 100644 (file)
@@ -232,7 +232,7 @@ wraperr:
        return err;
 }
 
-static const struct usb_device_id id_table[] __devinitconst = {
+static const struct usb_device_id id_table[] = {
        { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) },
        { }                                             /* Terminating entry */
 };
index ef0c3f9f0947a8718d5d5362ba9025df84a696fa..6259f0d99324c58e30d21c7510e186b60e61514a 100644 (file)
@@ -8,7 +8,7 @@ config USB_MUSB_HDRC
        tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
        depends on USB && USB_GADGET
        select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
-       select NOP_USB_XCEIV if (SOC_OMAPTI81XX || SOC_OMAPAM33XX)
+       select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX)
        select TWL4030_USB if MACH_OMAP_3430SDP
        select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
        select USB_OTG_UTILS
@@ -57,7 +57,7 @@ config USB_MUSB_AM35X
 
 config USB_MUSB_DSPS
        tristate "TI DSPS platforms"
-       depends on SOC_OMAPTI81XX || SOC_OMAPAM33XX
+       depends on SOC_TI81XX || SOC_AM33XX
 
 config USB_MUSB_BLACKFIN
        tristate "Blackfin"
index 217808d9fbe1991298da67295404d50cd71e593a..494772fc9e23ad123b7fb726fe1e0de24807b849 100644 (file)
@@ -479,9 +479,9 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
                ret = -ENODEV;
                goto err0;
        }
-       strcpy((u8 *)res->name, "mc");
        res->parent = NULL;
        resources[1] = *res;
+       resources[1].name = "mc";
 
        /* allocate the child platform device */
        musb = platform_device_alloc("musb-hdrc", -1);
@@ -566,27 +566,28 @@ static int __devinit dsps_probe(struct platform_device *pdev)
        }
        platform_set_drvdata(pdev, glue);
 
-       /* create the child platform device for first instances of musb */
-       ret = dsps_create_musb_pdev(glue, 0);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "failed to create child pdev\n");
-               goto err2;
-       }
-
        /* enable the usbss clocks */
        pm_runtime_enable(&pdev->dev);
 
        ret = pm_runtime_get_sync(&pdev->dev);
        if (ret < 0) {
                dev_err(&pdev->dev, "pm_runtime_get_sync FAILED");
+               goto err2;
+       }
+
+       /* create the child platform device for first instances of musb */
+       ret = dsps_create_musb_pdev(glue, 0);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "failed to create child pdev\n");
                goto err3;
        }
 
        return 0;
 
 err3:
-       pm_runtime_disable(&pdev->dev);
+       pm_runtime_put(&pdev->dev);
 err2:
+       pm_runtime_disable(&pdev->dev);
        kfree(glue->wrp);
 err1:
        kfree(glue);
index 8c9bb1ad30698b58f8949d7cdc0ca048492f5d62..681da06170c29273045b9602f9b63a873cacf8c0 100644 (file)
@@ -603,12 +603,12 @@ static int usbhsc_resume(struct device *dev)
        struct usbhs_priv *priv = dev_get_drvdata(dev);
        struct platform_device *pdev = usbhs_priv_to_pdev(priv);
 
-       usbhs_platform_call(priv, phy_reset, pdev);
-
        if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
                usbhsc_power_ctrl(priv, 1);
 
-       usbhsc_hotplug(priv);
+       usbhs_platform_call(priv, phy_reset, pdev);
+
+       usbhsc_drvcllbck_notify_hotplug(pdev);
 
        return 0;
 }
index 1834cf50888cbc8a6832e5250a8ccd8dbdddaee5..9b69a132329474052486e0483649b6c64a746a4f 100644 (file)
@@ -1266,6 +1266,12 @@ static int usbhsh_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
        return ret;
 }
 
+static int usbhsh_bus_nop(struct usb_hcd *hcd)
+{
+       /* nothing to do */
+       return 0;
+}
+
 static struct hc_driver usbhsh_driver = {
        .description =          usbhsh_hcd_name,
        .hcd_priv_size =        sizeof(struct usbhsh_hpriv),
@@ -1290,6 +1296,8 @@ static struct hc_driver usbhsh_driver = {
         */
        .hub_status_data =      usbhsh_hub_status_data,
        .hub_control =          usbhsh_hub_control,
+       .bus_suspend =          usbhsh_bus_nop,
+       .bus_resume =           usbhsh_bus_nop,
 };
 
 /*
index f398d1e34474c34084b43dac6702a6378f71a970..c15f2e7cefc77e4782dfb39fcedc54e5b0bc6329 100644 (file)
@@ -61,18 +61,23 @@ static int usb_serial_device_probe(struct device *dev)
                goto exit;
        }
 
+       /* make sure suspend/resume doesn't race against port_probe */
+       retval = usb_autopm_get_interface(port->serial->interface);
+       if (retval)
+               goto exit;
+
        driver = port->serial->type;
        if (driver->port_probe) {
                retval = driver->port_probe(port);
                if (retval)
-                       goto exit;
+                       goto exit_with_autopm;
        }
 
        retval = device_create_file(dev, &dev_attr_port_number);
        if (retval) {
                if (driver->port_remove)
                        retval = driver->port_remove(port);
-               goto exit;
+               goto exit_with_autopm;
        }
 
        minor = port->number;
@@ -81,6 +86,8 @@ static int usb_serial_device_probe(struct device *dev)
                 "%s converter now attached to ttyUSB%d\n",
                 driver->description, minor);
 
+exit_with_autopm:
+       usb_autopm_put_interface(port->serial->interface);
 exit:
        return retval;
 }
@@ -96,6 +103,9 @@ static int usb_serial_device_remove(struct device *dev)
        if (!port)
                return -ENODEV;
 
+       /* make sure suspend/resume doesn't race against port_remove */
+       usb_autopm_get_interface(port->serial->interface);
+
        device_remove_file(&port->dev, &dev_attr_port_number);
 
        driver = port->serial->type;
@@ -107,6 +117,7 @@ static int usb_serial_device_remove(struct device *dev)
        dev_info(dev, "%s converter now disconnected from ttyUSB%d\n",
                 driver->description, minor);
 
+       usb_autopm_put_interface(port->serial->interface);
        return retval;
 }
 
index bc912e5a3bebddf3073fe17e015b6195be3708be..5620db6469e586f85ea8eacfa79798b1b4a676d8 100644 (file)
@@ -811,6 +811,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },
        { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) },
        { USB_DEVICE(PI_VID, PI_E861_PID) },
+       { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) },
        { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
        { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
index 5661c7e2d4151cbb8f2335c4572f83fc3deccff8..5dd96ca6c380a0971921d198e12399e1902663db 100644 (file)
 #define PI_VID              0x1a72  /* Vendor ID */
 #define PI_E861_PID         0x1008  /* E-861 piezo controller USB connection */
 
+/*
+ * Kondo Kagaku Co.Ltd.
+ * http://www.kondo-robot.com/EN
+ */
+#define KONDO_VID              0x165c
+#define KONDO_USB_SERIAL_PID   0x0002
+
 /*
  * Bayer Ascensia Contour blood glucose meter USB-converter cable.
  * http://winglucofacts.com/cables/
index 5811d34b6c6bc514fb8474cc9662ad9521471a72..2cb30c535839db429c0165a76be26afdf84063cb 100644 (file)
@@ -227,7 +227,6 @@ static void ipw_release(struct usb_serial *serial)
 {
        struct usb_wwan_intf_private *data = usb_get_serial_data(serial);
 
-       usb_wwan_release(serial);
        usb_set_serial_data(serial, NULL);
        kfree(data);
 }
@@ -309,12 +308,12 @@ static struct usb_serial_driver ipw_device = {
        .description =          "IPWireless converter",
        .id_table =             id_table,
        .num_ports =            1,
-       .disconnect =           usb_wwan_disconnect,
        .open =                 ipw_open,
        .close =                ipw_close,
        .probe =                ipw_probe,
        .attach =               usb_wwan_startup,
        .release =              ipw_release,
+       .port_remove =          usb_wwan_port_remove,
        .dtr_rts =              ipw_dtr_rts,
        .write =                usb_wwan_write,
 };
index 57eca244842431fa100f742424c9dbc6310c4156..2f6da1e89bfa5606772103ce70f70087a9bfab42 100644 (file)
@@ -82,8 +82,7 @@
  * Defines used for sending commands to port
  */
 
-#define WAIT_FOR_EVER   (HZ * 0)       /* timeout urb is wait for ever */
-#define MOS_WDR_TIMEOUT (HZ * 5)       /* default urb timeout */
+#define MOS_WDR_TIMEOUT                5000    /* default urb timeout */
 
 #define MOS_PORT1       0x0200
 #define MOS_PORT2       0x0300
@@ -1232,9 +1231,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty)
                return 0;
 
        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
-       for (i = 0; i < NUM_URBS; ++i)
-               if (mos7840_port->busy[i])
-                       chars += URB_TRANSFER_BUFFER_SIZE;
+       for (i = 0; i < NUM_URBS; ++i) {
+               if (mos7840_port->busy[i]) {
+                       struct urb *urb = mos7840_port->write_urb_pool[i];
+                       chars += urb->transfer_buffer_length;
+               }
+       }
        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
        dbg("%s - returns %d", __func__, chars);
        return chars;
@@ -1344,7 +1346,7 @@ static void mos7840_close(struct usb_serial_port *port)
 static void mos7840_block_until_chase_response(struct tty_struct *tty,
                                        struct moschip_port *mos7840_port)
 {
-       int timeout = 1 * HZ;
+       int timeout = msecs_to_jiffies(1000);
        int wait = 10;
        int count;
 
@@ -2672,7 +2674,7 @@ static int mos7840_startup(struct usb_serial *serial)
 
        /* setting configuration feature to one */
        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ);
+                       (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT);
        return 0;
 error:
        for (/* nothing */; i >= 0; i--) {
index 08ff9b862049197566454d1052d6c46160efbab6..cc40f47ecea13ff2041389d5aa7d5526159e58d8 100644 (file)
@@ -80,85 +80,9 @@ static void option_instat_callback(struct urb *urb);
 #define OPTION_PRODUCT_GTM380_MODEM            0x7201
 
 #define HUAWEI_VENDOR_ID                       0x12D1
-#define HUAWEI_PRODUCT_E600                    0x1001
-#define HUAWEI_PRODUCT_E220                    0x1003
-#define HUAWEI_PRODUCT_E220BIS                 0x1004
-#define HUAWEI_PRODUCT_E1401                   0x1401
-#define HUAWEI_PRODUCT_E1402                   0x1402
-#define HUAWEI_PRODUCT_E1403                   0x1403
-#define HUAWEI_PRODUCT_E1404                   0x1404
-#define HUAWEI_PRODUCT_E1405                   0x1405
-#define HUAWEI_PRODUCT_E1406                   0x1406
-#define HUAWEI_PRODUCT_E1407                   0x1407
-#define HUAWEI_PRODUCT_E1408                   0x1408
-#define HUAWEI_PRODUCT_E1409                   0x1409
-#define HUAWEI_PRODUCT_E140A                   0x140A
-#define HUAWEI_PRODUCT_E140B                   0x140B
-#define HUAWEI_PRODUCT_E140C                   0x140C
-#define HUAWEI_PRODUCT_E140D                   0x140D
-#define HUAWEI_PRODUCT_E140E                   0x140E
-#define HUAWEI_PRODUCT_E140F                   0x140F
-#define HUAWEI_PRODUCT_E1410                   0x1410
-#define HUAWEI_PRODUCT_E1411                   0x1411
-#define HUAWEI_PRODUCT_E1412                   0x1412
-#define HUAWEI_PRODUCT_E1413                   0x1413
-#define HUAWEI_PRODUCT_E1414                   0x1414
-#define HUAWEI_PRODUCT_E1415                   0x1415
-#define HUAWEI_PRODUCT_E1416                   0x1416
-#define HUAWEI_PRODUCT_E1417                   0x1417
-#define HUAWEI_PRODUCT_E1418                   0x1418
-#define HUAWEI_PRODUCT_E1419                   0x1419
-#define HUAWEI_PRODUCT_E141A                   0x141A
-#define HUAWEI_PRODUCT_E141B                   0x141B
-#define HUAWEI_PRODUCT_E141C                   0x141C
-#define HUAWEI_PRODUCT_E141D                   0x141D
-#define HUAWEI_PRODUCT_E141E                   0x141E
-#define HUAWEI_PRODUCT_E141F                   0x141F
-#define HUAWEI_PRODUCT_E1420                   0x1420
-#define HUAWEI_PRODUCT_E1421                   0x1421
-#define HUAWEI_PRODUCT_E1422                   0x1422
-#define HUAWEI_PRODUCT_E1423                   0x1423
-#define HUAWEI_PRODUCT_E1424                   0x1424
-#define HUAWEI_PRODUCT_E1425                   0x1425
-#define HUAWEI_PRODUCT_E1426                   0x1426
-#define HUAWEI_PRODUCT_E1427                   0x1427
-#define HUAWEI_PRODUCT_E1428                   0x1428
-#define HUAWEI_PRODUCT_E1429                   0x1429
-#define HUAWEI_PRODUCT_E142A                   0x142A
-#define HUAWEI_PRODUCT_E142B                   0x142B
-#define HUAWEI_PRODUCT_E142C                   0x142C
-#define HUAWEI_PRODUCT_E142D                   0x142D
-#define HUAWEI_PRODUCT_E142E                   0x142E
-#define HUAWEI_PRODUCT_E142F                   0x142F
-#define HUAWEI_PRODUCT_E1430                   0x1430
-#define HUAWEI_PRODUCT_E1431                   0x1431
-#define HUAWEI_PRODUCT_E1432                   0x1432
-#define HUAWEI_PRODUCT_E1433                   0x1433
-#define HUAWEI_PRODUCT_E1434                   0x1434
-#define HUAWEI_PRODUCT_E1435                   0x1435
-#define HUAWEI_PRODUCT_E1436                   0x1436
-#define HUAWEI_PRODUCT_E1437                   0x1437
-#define HUAWEI_PRODUCT_E1438                   0x1438
-#define HUAWEI_PRODUCT_E1439                   0x1439
-#define HUAWEI_PRODUCT_E143A                   0x143A
-#define HUAWEI_PRODUCT_E143B                   0x143B
-#define HUAWEI_PRODUCT_E143C                   0x143C
-#define HUAWEI_PRODUCT_E143D                   0x143D
-#define HUAWEI_PRODUCT_E143E                   0x143E
-#define HUAWEI_PRODUCT_E143F                   0x143F
 #define HUAWEI_PRODUCT_K4505                   0x1464
 #define HUAWEI_PRODUCT_K3765                   0x1465
-#define HUAWEI_PRODUCT_E14AC                   0x14AC
-#define HUAWEI_PRODUCT_K3806                   0x14AE
 #define HUAWEI_PRODUCT_K4605                   0x14C6
-#define HUAWEI_PRODUCT_K5005                   0x14C8
-#define HUAWEI_PRODUCT_K3770                   0x14C9
-#define HUAWEI_PRODUCT_K3771                   0x14CA
-#define HUAWEI_PRODUCT_K4510                   0x14CB
-#define HUAWEI_PRODUCT_K4511                   0x14CC
-#define HUAWEI_PRODUCT_ETS1220                 0x1803
-#define HUAWEI_PRODUCT_E353                    0x1506
-#define HUAWEI_PRODUCT_E173S                   0x1C05
 
 #define QUANTA_VENDOR_ID                       0x0408
 #define QUANTA_PRODUCT_Q101                    0xEA02
@@ -615,104 +539,123 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) },
        { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) },
        { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) },
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) },  /* E398 3G Modem */
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) },  /* E398 3G PC UI Interface */
-       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) },  /* E398 3G Application Interface */
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x03) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x04) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x05) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x06) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0F) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x10) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x12) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x13) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x14) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x15) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x17) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x18) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x19) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1C) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x31) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x32) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x33) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x34) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x35) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x36) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3F) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x48) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x49) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4C) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x61) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x62) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x63) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x64) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x65) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x66) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7C) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x01) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x02) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x03) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x04) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x05) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x06) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0F) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x10) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x12) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x13) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x14) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x15) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x17) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x18) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x19) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1C) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x31) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x32) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x33) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x34) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x35) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x36) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3F) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x48) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x49) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4C) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x61) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x62) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x63) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x64) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x65) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x66) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) },
+
+
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
@@ -943,6 +886,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff),
+         .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) },
@@ -1297,8 +1242,8 @@ static struct usb_serial_driver option_1port_device = {
        .tiocmset          = usb_wwan_tiocmset,
        .ioctl             = usb_wwan_ioctl,
        .attach            = usb_wwan_startup,
-       .disconnect        = usb_wwan_disconnect,
        .release           = option_release,
+       .port_remove       = usb_wwan_port_remove,
        .read_int_callback = option_instat_callback,
 #ifdef CONFIG_PM
        .suspend           = usb_wwan_suspend,
@@ -1414,8 +1359,6 @@ static void option_release(struct usb_serial *serial)
        struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
        struct option_private *priv = intfdata->private;
 
-       usb_wwan_release(serial);
-
        kfree(priv);
        kfree(intfdata);
 }
index 8d103019d6aa529511a82070a3864ef87af44c22..bfd50779f0c9f9bf93d2f795322912caa3978f7b 100644 (file)
@@ -199,43 +199,49 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 
        /* default to enabling interface */
        altsetting = 0;
-       switch (ifnum) {
-               /* Composite mode; don't bind to the QMI/net interface as that
-                * gets handled by other drivers.
-                */
 
+       /* Composite mode; don't bind to the QMI/net interface as that
+        * gets handled by other drivers.
+        */
+
+       if (is_gobi1k) {
                /* Gobi 1K USB layout:
                 * 0: serial port (doesn't respond)
                 * 1: serial port (doesn't respond)
                 * 2: AT-capable modem port
                 * 3: QMI/net
-                *
-                * Gobi 2K+ USB layout:
+                */
+               if (ifnum == 2)
+                       dev_dbg(dev, "Modem port found\n");
+               else
+                       altsetting = -1;
+       } else {
+               /* Gobi 2K+ USB layout:
                 * 0: QMI/net
                 * 1: DM/DIAG (use libqcdm from ModemManager for communication)
                 * 2: AT-capable modem port
                 * 3: NMEA
                 */
-
-       case 1:
-               if (is_gobi1k)
+               switch (ifnum) {
+               case 0:
+                       /* Don't claim the QMI/net interface */
                        altsetting = -1;
-               else
+                       break;
+               case 1:
                        dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n");
-               break;
-       case 2:
-               dev_dbg(dev, "Modem port found\n");
-               break;
-       case 3:
-               if (is_gobi1k)
-                       altsetting = -1;
-               else
+                       break;
+               case 2:
+                       dev_dbg(dev, "Modem port found\n");
+                       break;
+               case 3:
                        /*
                         * NMEA (serial line 9600 8N1)
                         * # echo "\$GPS_START" > /dev/ttyUSBx
                         * # echo "\$GPS_STOP"  > /dev/ttyUSBx
                         */
                        dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n");
+                       break;
+               }
        }
 
 done:
@@ -262,8 +268,7 @@ static void qc_release(struct usb_serial *serial)
 {
        struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
 
-       /* Call usb_wwan release & free the private data allocated in qcprobe */
-       usb_wwan_release(serial);
+       /* Free the private data allocated in qcprobe */
        usb_set_serial_data(serial, NULL);
        kfree(priv);
 }
@@ -283,8 +288,8 @@ static struct usb_serial_driver qcdevice = {
        .write_room          = usb_wwan_write_room,
        .chars_in_buffer     = usb_wwan_chars_in_buffer,
        .attach              = usb_wwan_startup,
-       .disconnect          = usb_wwan_disconnect,
        .release             = qc_release,
+       .port_remove         = usb_wwan_port_remove,
 #ifdef CONFIG_PM
        .suspend             = usb_wwan_suspend,
        .resume              = usb_wwan_resume,
index c47b6ec030634f9af420987e06c33727042b4f05..1f034d2397c6c6ea3888e79aa6cd2ddb6d73202b 100644 (file)
@@ -9,8 +9,7 @@ extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on);
 extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port);
 extern void usb_wwan_close(struct usb_serial_port *port);
 extern int usb_wwan_startup(struct usb_serial *serial);
-extern void usb_wwan_disconnect(struct usb_serial *serial);
-extern void usb_wwan_release(struct usb_serial *serial);
+extern int usb_wwan_port_remove(struct usb_serial_port *port);
 extern int usb_wwan_write_room(struct tty_struct *tty);
 extern void usb_wwan_set_termios(struct tty_struct *tty,
                                 struct usb_serial_port *port,
index f35971dff4a5782d6c0cca563f53558043359674..6855d5ed033115473cf02e3a6f3ee73d1d5bace8 100644 (file)
@@ -565,62 +565,52 @@ bail_out_error:
 }
 EXPORT_SYMBOL(usb_wwan_startup);
 
-static void stop_read_write_urbs(struct usb_serial *serial)
+int usb_wwan_port_remove(struct usb_serial_port *port)
 {
-       int i, j;
-       struct usb_serial_port *port;
+       int i;
        struct usb_wwan_port_private *portdata;
 
-       /* Stop reading/writing urbs */
-       for (i = 0; i < serial->num_ports; ++i) {
-               port = serial->port[i];
-               portdata = usb_get_serial_port_data(port);
-               for (j = 0; j < N_IN_URB; j++)
-                       usb_kill_urb(portdata->in_urbs[j]);
-               for (j = 0; j < N_OUT_URB; j++)
-                       usb_kill_urb(portdata->out_urbs[j]);
+       portdata = usb_get_serial_port_data(port);
+       usb_set_serial_port_data(port, NULL);
+
+       /* Stop reading/writing urbs and free them */
+       for (i = 0; i < N_IN_URB; i++) {
+               usb_kill_urb(portdata->in_urbs[i]);
+               usb_free_urb(portdata->in_urbs[i]);
+               free_page((unsigned long)portdata->in_buffer[i]);
+       }
+       for (i = 0; i < N_OUT_URB; i++) {
+               usb_kill_urb(portdata->out_urbs[i]);
+               usb_free_urb(portdata->out_urbs[i]);
+               kfree(portdata->out_buffer[i]);
        }
-}
 
-void usb_wwan_disconnect(struct usb_serial *serial)
-{
-       stop_read_write_urbs(serial);
+       /* Now free port private data */
+       kfree(portdata);
+       return 0;
 }
-EXPORT_SYMBOL(usb_wwan_disconnect);
+EXPORT_SYMBOL(usb_wwan_port_remove);
 
-void usb_wwan_release(struct usb_serial *serial)
+#ifdef CONFIG_PM
+static void stop_read_write_urbs(struct usb_serial *serial)
 {
        int i, j;
        struct usb_serial_port *port;
        struct usb_wwan_port_private *portdata;
 
-       /* Now free them */
+       /* Stop reading/writing urbs */
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                portdata = usb_get_serial_port_data(port);
-
-               for (j = 0; j < N_IN_URB; j++) {
-                       usb_free_urb(portdata->in_urbs[j]);
-                       free_page((unsigned long)
-                                 portdata->in_buffer[j]);
-                       portdata->in_urbs[j] = NULL;
-               }
-               for (j = 0; j < N_OUT_URB; j++) {
-                       usb_free_urb(portdata->out_urbs[j]);
-                       kfree(portdata->out_buffer[j]);
-                       portdata->out_urbs[j] = NULL;
-               }
-       }
-
-       /* Now free per port private data */
-       for (i = 0; i < serial->num_ports; i++) {
-               port = serial->port[i];
-               kfree(usb_get_serial_port_data(port));
+               if (!portdata)
+                       continue;
+               for (j = 0; j < N_IN_URB; j++)
+                       usb_kill_urb(portdata->in_urbs[j]);
+               for (j = 0; j < N_OUT_URB; j++)
+                       usb_kill_urb(portdata->out_urbs[j]);
        }
 }
-EXPORT_SYMBOL(usb_wwan_release);
 
-#ifdef CONFIG_PM
 int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
 {
        struct usb_wwan_intf_private *intfdata = serial->private;
@@ -712,7 +702,7 @@ int usb_wwan_resume(struct usb_serial *serial)
 
                /* skip closed ports */
                spin_lock_irq(&intfdata->susp_lock);
-               if (!portdata->opened) {
+               if (!portdata || !portdata->opened) {
                        spin_unlock_irq(&intfdata->susp_lock);
                        continue;
                }
index 9591e2b509d794e93e596fe8f2c1da8c11691205..17830c9c7cc623b7b26cdac7568aca508f7251e7 100644 (file)
@@ -264,6 +264,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
        return group;
 }
 
+/* called with vfio.group_lock held */
 static void vfio_group_release(struct kref *kref)
 {
        struct vfio_group *group = container_of(kref, struct vfio_group, kref);
@@ -287,13 +288,7 @@ static void vfio_group_release(struct kref *kref)
 
 static void vfio_group_put(struct vfio_group *group)
 {
-       mutex_lock(&vfio.group_lock);
-       /*
-        * Release needs to unlock to unregister the notifier, so only
-        * unlock if not released.
-        */
-       if (!kref_put(&group->kref, vfio_group_release))
-               mutex_unlock(&vfio.group_lock);
+       kref_put_mutex(&group->kref, vfio_group_release, &vfio.group_lock);
 }
 
 /* Assume group_lock or group reference is held */
@@ -401,7 +396,6 @@ static void vfio_device_release(struct kref *kref)
                                                  struct vfio_device, kref);
        struct vfio_group *group = device->group;
 
-       mutex_lock(&group->device_lock);
        list_del(&device->group_next);
        mutex_unlock(&group->device_lock);
 
@@ -416,8 +410,9 @@ static void vfio_device_release(struct kref *kref)
 /* Device reference always implies a group reference */
 static void vfio_device_put(struct vfio_device *device)
 {
-       kref_put(&device->kref, vfio_device_release);
-       vfio_group_put(device->group);
+       struct vfio_group *group = device->group;
+       kref_put_mutex(&device->kref, vfio_device_release, &group->device_lock);
+       vfio_group_put(group);
 }
 
 static void vfio_device_get(struct vfio_device *device)
@@ -1116,10 +1111,10 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
                 */
                filep->f_mode |= (FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
 
-               fd_install(ret, filep);
-
                vfio_device_get(device);
                atomic_inc(&group->container_users);
+
+               fd_install(ret, filep);
                break;
        }
        mutex_unlock(&group->device_lock);
index e4e2fd1b51076dfbc8ffc73920ac148d830c4d4f..202bba6c997cce61eb116fc74db8e842454ce1f4 100644 (file)
@@ -9,3 +9,6 @@ config VHOST_NET
          To compile this driver as a module, choose M here: the module will
          be called vhost_net.
 
+if STAGING
+source "drivers/vhost/Kconfig.tcm"
+endif
diff --git a/drivers/vhost/Kconfig.tcm b/drivers/vhost/Kconfig.tcm
new file mode 100644 (file)
index 0000000..a9c6f76
--- /dev/null
@@ -0,0 +1,6 @@
+config TCM_VHOST
+       tristate "TCM_VHOST fabric module (EXPERIMENTAL)"
+       depends on TARGET_CORE && EVENTFD && EXPERIMENTAL && m
+       default n
+       ---help---
+       Say M here to enable the TCM_VHOST fabric module for use with virtio-scsi guests
index 72dd02050bb986cf6d426828f64ea521aaff3284..a27b053bc9ab12d546c9f17bee106a916eb5e236 100644 (file)
@@ -1,2 +1,4 @@
 obj-$(CONFIG_VHOST_NET) += vhost_net.o
 vhost_net-y := vhost.o net.o
+
+obj-$(CONFIG_TCM_VHOST) += tcm_vhost.o
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
new file mode 100644 (file)
index 0000000..ed8e2e6
--- /dev/null
@@ -0,0 +1,1649 @@
+/*******************************************************************************
+ * Vhost kernel TCM fabric driver for virtio SCSI initiators
+ *
+ * (C) Copyright 2010-2012 RisingTide Systems LLC.
+ * (C) Copyright 2010-2012 IBM Corp.
+ *
+ * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
+ *
+ * Authors: Nicholas A. Bellinger <nab@risingtidesystems.com>
+ *          Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ ****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <generated/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/configfs.h>
+#include <linux/ctype.h>
+#include <linux/compat.h>
+#include <linux/eventfd.h>
+#include <linux/vhost.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <asm/unaligned.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_tcq.h>
+#include <target/target_core_base.h>
+#include <target/target_core_fabric.h>
+#include <target/target_core_fabric_configfs.h>
+#include <target/target_core_configfs.h>
+#include <target/configfs_macros.h>
+#include <linux/vhost.h>
+#include <linux/virtio_net.h> /* TODO vhost.h currently depends on this */
+#include <linux/virtio_scsi.h>
+
+#include "vhost.c"
+#include "vhost.h"
+#include "tcm_vhost.h"
+
+enum {
+       VHOST_SCSI_VQ_CTL = 0,
+       VHOST_SCSI_VQ_EVT = 1,
+       VHOST_SCSI_VQ_IO = 2,
+};
+
+struct vhost_scsi {
+       struct tcm_vhost_tpg *vs_tpg;   /* Protected by vhost_scsi->dev.mutex */
+       struct vhost_dev dev;
+       struct vhost_virtqueue vqs[3];
+
+       struct vhost_work vs_completion_work; /* cmd completion work item */
+       struct list_head vs_completion_list;  /* cmd completion queue */
+       spinlock_t vs_completion_lock;        /* protects s_completion_list */
+};
+
+/* Local pointer to allocated TCM configfs fabric module */
+static struct target_fabric_configfs *tcm_vhost_fabric_configfs;
+
+static struct workqueue_struct *tcm_vhost_workqueue;
+
+/* Global spinlock to protect tcm_vhost TPG list for vhost IOCTL access */
+static DEFINE_MUTEX(tcm_vhost_mutex);
+static LIST_HEAD(tcm_vhost_list);
+
+static int tcm_vhost_check_true(struct se_portal_group *se_tpg)
+{
+       return 1;
+}
+
+static int tcm_vhost_check_false(struct se_portal_group *se_tpg)
+{
+       return 0;
+}
+
+static char *tcm_vhost_get_fabric_name(void)
+{
+       return "vhost";
+}
+
+static u8 tcm_vhost_get_fabric_proto_ident(struct se_portal_group *se_tpg)
+{
+       struct tcm_vhost_tpg *tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       struct tcm_vhost_tport *tport = tpg->tport;
+
+       switch (tport->tport_proto_id) {
+       case SCSI_PROTOCOL_SAS:
+               return sas_get_fabric_proto_ident(se_tpg);
+       case SCSI_PROTOCOL_FCP:
+               return fc_get_fabric_proto_ident(se_tpg);
+       case SCSI_PROTOCOL_ISCSI:
+               return iscsi_get_fabric_proto_ident(se_tpg);
+       default:
+               pr_err("Unknown tport_proto_id: 0x%02x, using"
+                       " SAS emulation\n", tport->tport_proto_id);
+               break;
+       }
+
+       return sas_get_fabric_proto_ident(se_tpg);
+}
+
+static char *tcm_vhost_get_fabric_wwn(struct se_portal_group *se_tpg)
+{
+       struct tcm_vhost_tpg *tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       struct tcm_vhost_tport *tport = tpg->tport;
+
+       return &tport->tport_name[0];
+}
+
+static u16 tcm_vhost_get_tag(struct se_portal_group *se_tpg)
+{
+       struct tcm_vhost_tpg *tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       return tpg->tport_tpgt;
+}
+
+static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg)
+{
+       return 1;
+}
+
+static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg,
+       struct se_node_acl *se_nacl,
+       struct t10_pr_registration *pr_reg,
+       int *format_code,
+       unsigned char *buf)
+{
+       struct tcm_vhost_tpg *tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       struct tcm_vhost_tport *tport = tpg->tport;
+
+       switch (tport->tport_proto_id) {
+       case SCSI_PROTOCOL_SAS:
+               return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
+                                       format_code, buf);
+       case SCSI_PROTOCOL_FCP:
+               return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
+                                       format_code, buf);
+       case SCSI_PROTOCOL_ISCSI:
+               return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
+                                       format_code, buf);
+       default:
+               pr_err("Unknown tport_proto_id: 0x%02x, using"
+                       " SAS emulation\n", tport->tport_proto_id);
+               break;
+       }
+
+       return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
+                       format_code, buf);
+}
+
+static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg,
+       struct se_node_acl *se_nacl,
+       struct t10_pr_registration *pr_reg,
+       int *format_code)
+{
+       struct tcm_vhost_tpg *tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       struct tcm_vhost_tport *tport = tpg->tport;
+
+       switch (tport->tport_proto_id) {
+       case SCSI_PROTOCOL_SAS:
+               return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
+                                       format_code);
+       case SCSI_PROTOCOL_FCP:
+               return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
+                                       format_code);
+       case SCSI_PROTOCOL_ISCSI:
+               return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
+                                       format_code);
+       default:
+               pr_err("Unknown tport_proto_id: 0x%02x, using"
+                       " SAS emulation\n", tport->tport_proto_id);
+               break;
+       }
+
+       return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
+                       format_code);
+}
+
+static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
+       const char *buf,
+       u32 *out_tid_len,
+       char **port_nexus_ptr)
+{
+       struct tcm_vhost_tpg *tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       struct tcm_vhost_tport *tport = tpg->tport;
+
+       switch (tport->tport_proto_id) {
+       case SCSI_PROTOCOL_SAS:
+               return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
+                                       port_nexus_ptr);
+       case SCSI_PROTOCOL_FCP:
+               return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
+                                       port_nexus_ptr);
+       case SCSI_PROTOCOL_ISCSI:
+               return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
+                                       port_nexus_ptr);
+       default:
+               pr_err("Unknown tport_proto_id: 0x%02x, using"
+                       " SAS emulation\n", tport->tport_proto_id);
+               break;
+       }
+
+       return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
+                       port_nexus_ptr);
+}
+
+static struct se_node_acl *tcm_vhost_alloc_fabric_acl(
+       struct se_portal_group *se_tpg)
+{
+       struct tcm_vhost_nacl *nacl;
+
+       nacl = kzalloc(sizeof(struct tcm_vhost_nacl), GFP_KERNEL);
+       if (!nacl) {
+               pr_err("Unable to alocate struct tcm_vhost_nacl\n");
+               return NULL;
+       }
+
+       return &nacl->se_node_acl;
+}
+
+static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg,
+       struct se_node_acl *se_nacl)
+{
+       struct tcm_vhost_nacl *nacl = container_of(se_nacl,
+                       struct tcm_vhost_nacl, se_node_acl);
+       kfree(nacl);
+}
+
+static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg)
+{
+       return 1;
+}
+
+static void tcm_vhost_release_cmd(struct se_cmd *se_cmd)
+{
+       return;
+}
+
+static int tcm_vhost_shutdown_session(struct se_session *se_sess)
+{
+       return 0;
+}
+
+static void tcm_vhost_close_session(struct se_session *se_sess)
+{
+       return;
+}
+
+static u32 tcm_vhost_sess_get_index(struct se_session *se_sess)
+{
+       return 0;
+}
+
+static int tcm_vhost_write_pending(struct se_cmd *se_cmd)
+{
+       /* Go ahead and process the write immediately */
+       target_execute_cmd(se_cmd);
+       return 0;
+}
+
+static int tcm_vhost_write_pending_status(struct se_cmd *se_cmd)
+{
+       return 0;
+}
+
+static void tcm_vhost_set_default_node_attrs(struct se_node_acl *nacl)
+{
+       return;
+}
+
+static u32 tcm_vhost_get_task_tag(struct se_cmd *se_cmd)
+{
+       return 0;
+}
+
+static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd)
+{
+       return 0;
+}
+
+static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd)
+{
+       struct vhost_scsi *vs = tv_cmd->tvc_vhost;
+
+       spin_lock_bh(&vs->vs_completion_lock);
+       list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list);
+       spin_unlock_bh(&vs->vs_completion_lock);
+
+       vhost_work_queue(&vs->dev, &vs->vs_completion_work);
+}
+
+static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd)
+{
+       struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
+                               struct tcm_vhost_cmd, tvc_se_cmd);
+       vhost_scsi_complete_cmd(tv_cmd);
+       return 0;
+}
+
+static int tcm_vhost_queue_status(struct se_cmd *se_cmd)
+{
+       struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
+                               struct tcm_vhost_cmd, tvc_se_cmd);
+       vhost_scsi_complete_cmd(tv_cmd);
+       return 0;
+}
+
+static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd)
+{
+       return 0;
+}
+
+static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd,
+       u32 sense_length)
+{
+       return 0;
+}
+
+static u16 tcm_vhost_get_fabric_sense_len(void)
+{
+       return 0;
+}
+
+static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
+{
+       struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
+
+       /* TODO locking against target/backend threads? */
+       transport_generic_free_cmd(se_cmd, 1);
+
+       if (tv_cmd->tvc_sgl_count) {
+               u32 i;
+               for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
+                       put_page(sg_page(&tv_cmd->tvc_sgl[i]));
+
+               kfree(tv_cmd->tvc_sgl);
+       }
+
+       kfree(tv_cmd);
+}
+
+/* Dequeue a command from the completion list */
+static struct tcm_vhost_cmd *vhost_scsi_get_cmd_from_completion(
+       struct vhost_scsi *vs)
+{
+       struct tcm_vhost_cmd *tv_cmd = NULL;
+
+       spin_lock_bh(&vs->vs_completion_lock);
+       if (list_empty(&vs->vs_completion_list)) {
+               spin_unlock_bh(&vs->vs_completion_lock);
+               return NULL;
+       }
+
+       list_for_each_entry(tv_cmd, &vs->vs_completion_list,
+                           tvc_completion_list) {
+               list_del(&tv_cmd->tvc_completion_list);
+               break;
+       }
+       spin_unlock_bh(&vs->vs_completion_lock);
+       return tv_cmd;
+}
+
+/* Fill in status and signal that we are done processing this command
+ *
+ * This is scheduled in the vhost work queue so we are called with the owner
+ * process mm and can access the vring.
+ */
+static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
+{
+       struct vhost_scsi *vs = container_of(work, struct vhost_scsi,
+                                       vs_completion_work);
+       struct tcm_vhost_cmd *tv_cmd;
+
+       while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs))) {
+               struct virtio_scsi_cmd_resp v_rsp;
+               struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
+               int ret;
+
+               pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__,
+                       tv_cmd, se_cmd->residual_count, se_cmd->scsi_status);
+
+               memset(&v_rsp, 0, sizeof(v_rsp));
+               v_rsp.resid = se_cmd->residual_count;
+               /* TODO is status_qualifier field needed? */
+               v_rsp.status = se_cmd->scsi_status;
+               v_rsp.sense_len = se_cmd->scsi_sense_length;
+               memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf,
+                      v_rsp.sense_len);
+               ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
+               if (likely(ret == 0))
+                       vhost_add_used(&vs->vqs[2], tv_cmd->tvc_vq_desc, 0);
+               else
+                       pr_err("Faulted on virtio_scsi_cmd_resp\n");
+
+               vhost_scsi_free_cmd(tv_cmd);
+       }
+
+       vhost_signal(&vs->dev, &vs->vqs[2]);
+}
+
+static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
+       struct tcm_vhost_tpg *tv_tpg,
+       struct virtio_scsi_cmd_req *v_req,
+       u32 exp_data_len,
+       int data_direction)
+{
+       struct tcm_vhost_cmd *tv_cmd;
+       struct tcm_vhost_nexus *tv_nexus;
+       struct se_portal_group *se_tpg = &tv_tpg->se_tpg;
+       struct se_session *se_sess;
+       struct se_cmd *se_cmd;
+       int sam_task_attr;
+
+       tv_nexus = tv_tpg->tpg_nexus;
+       if (!tv_nexus) {
+               pr_err("Unable to locate active struct tcm_vhost_nexus\n");
+               return ERR_PTR(-EIO);
+       }
+       se_sess = tv_nexus->tvn_se_sess;
+
+       tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC);
+       if (!tv_cmd) {
+               pr_err("Unable to allocate struct tcm_vhost_cmd\n");
+               return ERR_PTR(-ENOMEM);
+       }
+       INIT_LIST_HEAD(&tv_cmd->tvc_completion_list);
+       tv_cmd->tvc_tag = v_req->tag;
+
+       se_cmd = &tv_cmd->tvc_se_cmd;
+       /*
+        * Locate the SAM Task Attr from virtio_scsi_cmd_req
+        */
+       sam_task_attr = v_req->task_attr;
+       /*
+        * Initialize struct se_cmd descriptor from TCM infrastructure
+        */
+       transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len,
+                               data_direction, sam_task_attr,
+                               &tv_cmd->tvc_sense_buf[0]);
+
+#if 0  /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */
+       if (bidi)
+               se_cmd->se_cmd_flags |= SCF_BIDI;
+#endif
+       return tv_cmd;
+}
+
+/*
+ * Map a user memory range into a scatterlist
+ *
+ * Returns the number of scatterlist entries used or -errno on error.
+ */
+static int vhost_scsi_map_to_sgl(struct scatterlist *sgl,
+       unsigned int sgl_count, void __user *ptr, size_t len, int write)
+{
+       struct scatterlist *sg = sgl;
+       unsigned int npages = 0;
+       int ret;
+
+       while (len > 0) {
+               struct page *page;
+               unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK;
+               unsigned int nbytes = min_t(unsigned int,
+                               PAGE_SIZE - offset, len);
+
+               if (npages == sgl_count) {
+                       ret = -ENOBUFS;
+                       goto err;
+               }
+
+               ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page);
+               BUG_ON(ret == 0); /* we should either get our page or fail */
+               if (ret < 0)
+                       goto err;
+
+               sg_set_page(sg, page, nbytes, offset);
+               ptr += nbytes;
+               len -= nbytes;
+               sg++;
+               npages++;
+       }
+       return npages;
+
+err:
+       /* Put pages that we hold */
+       for (sg = sgl; sg != &sgl[npages]; sg++)
+               put_page(sg_page(sg));
+       return ret;
+}
+
+static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd,
+       struct iovec *iov, unsigned int niov, int write)
+{
+       int ret;
+       unsigned int i;
+       u32 sgl_count;
+       struct scatterlist *sg;
+
+       /*
+        * Find out how long sglist needs to be
+        */
+       sgl_count = 0;
+       for (i = 0; i < niov; i++) {
+               sgl_count += (((uintptr_t)iov[i].iov_base + iov[i].iov_len +
+                               PAGE_SIZE - 1) >> PAGE_SHIFT) -
+                               ((uintptr_t)iov[i].iov_base >> PAGE_SHIFT);
+       }
+       /* TODO overflow checking */
+
+       sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC);
+       if (!sg)
+               return -ENOMEM;
+       pr_debug("%s sg %p sgl_count %u is_err %d\n", __func__,
+              sg, sgl_count, !sg);
+       sg_init_table(sg, sgl_count);
+
+       tv_cmd->tvc_sgl = sg;
+       tv_cmd->tvc_sgl_count = sgl_count;
+
+       pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count);
+       for (i = 0; i < niov; i++) {
+               ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base,
+                                       iov[i].iov_len, write);
+               if (ret < 0) {
+                       for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
+                               put_page(sg_page(&tv_cmd->tvc_sgl[i]));
+                       kfree(tv_cmd->tvc_sgl);
+                       tv_cmd->tvc_sgl = NULL;
+                       tv_cmd->tvc_sgl_count = 0;
+                       return ret;
+               }
+
+               sg += ret;
+               sgl_count -= ret;
+       }
+       return 0;
+}
+
+static void tcm_vhost_submission_work(struct work_struct *work)
+{
+       struct tcm_vhost_cmd *tv_cmd =
+               container_of(work, struct tcm_vhost_cmd, work);
+       struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
+       struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL;
+       int rc, sg_no_bidi = 0;
+       /*
+        * Locate the struct se_lun pointer based on v_req->lun, and
+        * attach it to struct se_cmd
+        */
+       rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun);
+       if (rc < 0) {
+               pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun);
+               transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd,
+                       tv_cmd->tvc_se_cmd.scsi_sense_reason, 0);
+               transport_generic_free_cmd(se_cmd, 0);
+               return;
+       }
+
+       rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb);
+       if (rc == -ENOMEM) {
+               transport_send_check_condition_and_sense(se_cmd,
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
+               transport_generic_free_cmd(se_cmd, 0);
+               return;
+       } else if (rc < 0) {
+               if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
+                       tcm_vhost_queue_status(se_cmd);
+               else
+                       transport_send_check_condition_and_sense(se_cmd,
+                                       se_cmd->scsi_sense_reason, 0);
+               transport_generic_free_cmd(se_cmd, 0);
+               return;
+       }
+
+       if (tv_cmd->tvc_sgl_count) {
+               sg_ptr = tv_cmd->tvc_sgl;
+               /*
+                * For BIDI commands, pass in the extra READ buffer
+                * to transport_generic_map_mem_to_cmd() below..
+                */
+/* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */
+#if 0
+               if (se_cmd->se_cmd_flags & SCF_BIDI) {
+                       sg_bidi_ptr = NULL;
+                       sg_no_bidi = 0;
+               }
+#endif
+       } else {
+               sg_ptr = NULL;
+       }
+
+       rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr,
+                               tv_cmd->tvc_sgl_count, sg_bidi_ptr,
+                               sg_no_bidi);
+       if (rc < 0) {
+               transport_send_check_condition_and_sense(se_cmd,
+                               se_cmd->scsi_sense_reason, 0);
+               transport_generic_free_cmd(se_cmd, 0);
+               return;
+       }
+       transport_handle_cdb_direct(se_cmd);
+}
+
+static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
+{
+       struct vhost_virtqueue *vq = &vs->vqs[2];
+       struct virtio_scsi_cmd_req v_req;
+       struct tcm_vhost_tpg *tv_tpg;
+       struct tcm_vhost_cmd *tv_cmd;
+       u32 exp_data_len, data_first, data_num, data_direction;
+       unsigned out, in, i;
+       int head, ret;
+
+       /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */
+       tv_tpg = vs->vs_tpg;
+       if (unlikely(!tv_tpg)) {
+               pr_err("%s endpoint not set\n", __func__);
+               return;
+       }
+
+       mutex_lock(&vq->mutex);
+       vhost_disable_notify(&vs->dev, vq);
+
+       for (;;) {
+               head = vhost_get_vq_desc(&vs->dev, vq, vq->iov,
+                                       ARRAY_SIZE(vq->iov), &out, &in,
+                                       NULL, NULL);
+               pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n",
+                                       head, out, in);
+               /* On error, stop handling until the next kick. */
+               if (unlikely(head < 0))
+                       break;
+               /* Nothing new?  Wait for eventfd to tell us they refilled. */
+               if (head == vq->num) {
+                       if (unlikely(vhost_enable_notify(&vs->dev, vq))) {
+                               vhost_disable_notify(&vs->dev, vq);
+                               continue;
+                       }
+                       break;
+               }
+
+/* FIXME: BIDI operation */
+               if (out == 1 && in == 1) {
+                       data_direction = DMA_NONE;
+                       data_first = 0;
+                       data_num = 0;
+               } else if (out == 1 && in > 1) {
+                       data_direction = DMA_FROM_DEVICE;
+                       data_first = out + 1;
+                       data_num = in - 1;
+               } else if (out > 1 && in == 1) {
+                       data_direction = DMA_TO_DEVICE;
+                       data_first = 1;
+                       data_num = out - 1;
+               } else {
+                       vq_err(vq, "Invalid buffer layout out: %u in: %u\n",
+                                       out, in);
+                       break;
+               }
+
+               /*
+                * Check for a sane resp buffer so we can report errors to
+                * the guest.
+                */
+               if (unlikely(vq->iov[out].iov_len !=
+                                       sizeof(struct virtio_scsi_cmd_resp))) {
+                       vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu"
+                               " bytes\n", vq->iov[out].iov_len);
+                       break;
+               }
+
+               if (unlikely(vq->iov[0].iov_len != sizeof(v_req))) {
+                       vq_err(vq, "Expecting virtio_scsi_cmd_req, got %zu"
+                               " bytes\n", vq->iov[0].iov_len);
+                       break;
+               }
+               pr_debug("Calling __copy_from_user: vq->iov[0].iov_base: %p,"
+                       " len: %zu\n", vq->iov[0].iov_base, sizeof(v_req));
+               ret = __copy_from_user(&v_req, vq->iov[0].iov_base,
+                               sizeof(v_req));
+               if (unlikely(ret)) {
+                       vq_err(vq, "Faulted on virtio_scsi_cmd_req\n");
+                       break;
+               }
+
+               exp_data_len = 0;
+               for (i = 0; i < data_num; i++)
+                       exp_data_len += vq->iov[data_first + i].iov_len;
+
+               tv_cmd = vhost_scsi_allocate_cmd(tv_tpg, &v_req,
+                                       exp_data_len, data_direction);
+               if (IS_ERR(tv_cmd)) {
+                       vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n",
+                                       PTR_ERR(tv_cmd));
+                       break;
+               }
+               pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction"
+                       ": %d\n", tv_cmd, exp_data_len, data_direction);
+
+               tv_cmd->tvc_vhost = vs;
+
+               if (unlikely(vq->iov[out].iov_len !=
+                               sizeof(struct virtio_scsi_cmd_resp))) {
+                       vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu"
+                               " bytes, out: %d, in: %d\n",
+                               vq->iov[out].iov_len, out, in);
+                       break;
+               }
+
+               tv_cmd->tvc_resp = vq->iov[out].iov_base;
+
+               /*
+                * Copy in the recieved CDB descriptor into tv_cmd->tvc_cdb
+                * that will be used by tcm_vhost_new_cmd_map() and down into
+                * target_setup_cmd_from_cdb()
+                */
+               memcpy(tv_cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE);
+               /*
+                * Check that the recieved CDB size does not exceeded our
+                * hardcoded max for tcm_vhost
+                */
+               /* TODO what if cdb was too small for varlen cdb header? */
+               if (unlikely(scsi_command_size(tv_cmd->tvc_cdb) >
+                                       TCM_VHOST_MAX_CDB_SIZE)) {
+                       vq_err(vq, "Received SCSI CDB with command_size: %d that"
+                               " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
+                               scsi_command_size(tv_cmd->tvc_cdb),
+                               TCM_VHOST_MAX_CDB_SIZE);
+                       break; /* TODO */
+               }
+               tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF;
+
+               pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",
+                       tv_cmd->tvc_cdb[0], tv_cmd->tvc_lun);
+
+               if (data_direction != DMA_NONE) {
+                       ret = vhost_scsi_map_iov_to_sgl(tv_cmd,
+                                       &vq->iov[data_first], data_num,
+                                       data_direction == DMA_TO_DEVICE);
+                       if (unlikely(ret)) {
+                               vq_err(vq, "Failed to map iov to sgl\n");
+                               break; /* TODO */
+                       }
+               }
+
+               /*
+                * Save the descriptor from vhost_get_vq_desc() to be used to
+                * complete the virtio-scsi request in TCM callback context via
+                * tcm_vhost_queue_data_in() and tcm_vhost_queue_status()
+                */
+               tv_cmd->tvc_vq_desc = head;
+               /*
+                * Dispatch tv_cmd descriptor for cmwq execution in process
+                * context provided by tcm_vhost_workqueue.  This also ensures
+                * tv_cmd is executed on the same kworker CPU as this vhost
+                * thread to gain positive L2 cache locality effects..
+                */
+               INIT_WORK(&tv_cmd->work, tcm_vhost_submission_work);
+               queue_work(tcm_vhost_workqueue, &tv_cmd->work);
+       }
+
+       mutex_unlock(&vq->mutex);
+}
+
+static void vhost_scsi_ctl_handle_kick(struct vhost_work *work)
+{
+       pr_debug("%s: The handling func for control queue.\n", __func__);
+}
+
+static void vhost_scsi_evt_handle_kick(struct vhost_work *work)
+{
+       pr_debug("%s: The handling func for event queue.\n", __func__);
+}
+
+static void vhost_scsi_handle_kick(struct vhost_work *work)
+{
+       struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
+                                               poll.work);
+       struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev);
+
+       vhost_scsi_handle_vq(vs);
+}
+
+/*
+ * Called from vhost_scsi_ioctl() context to walk the list of available
+ * tcm_vhost_tpg with an active struct tcm_vhost_nexus
+ */
+static int vhost_scsi_set_endpoint(
+       struct vhost_scsi *vs,
+       struct vhost_scsi_target *t)
+{
+       struct tcm_vhost_tport *tv_tport;
+       struct tcm_vhost_tpg *tv_tpg;
+       int index;
+
+       mutex_lock(&vs->dev.mutex);
+       /* Verify that ring has been setup correctly. */
+       for (index = 0; index < vs->dev.nvqs; ++index) {
+               /* Verify that ring has been setup correctly. */
+               if (!vhost_vq_access_ok(&vs->vqs[index])) {
+                       mutex_unlock(&vs->dev.mutex);
+                       return -EFAULT;
+               }
+       }
+       mutex_unlock(&vs->dev.mutex);
+
+       mutex_lock(&tcm_vhost_mutex);
+       list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) {
+               mutex_lock(&tv_tpg->tv_tpg_mutex);
+               if (!tv_tpg->tpg_nexus) {
+                       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+                       continue;
+               }
+               if (tv_tpg->tv_tpg_vhost_count != 0) {
+                       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+                       continue;
+               }
+               tv_tport = tv_tpg->tport;
+
+               if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) &&
+                   (tv_tpg->tport_tpgt == t->vhost_tpgt)) {
+                       tv_tpg->tv_tpg_vhost_count++;
+                       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+                       mutex_unlock(&tcm_vhost_mutex);
+
+                       mutex_lock(&vs->dev.mutex);
+                       if (vs->vs_tpg) {
+                               mutex_unlock(&vs->dev.mutex);
+                               mutex_lock(&tv_tpg->tv_tpg_mutex);
+                               tv_tpg->tv_tpg_vhost_count--;
+                               mutex_unlock(&tv_tpg->tv_tpg_mutex);
+                               return -EEXIST;
+                       }
+
+                       vs->vs_tpg = tv_tpg;
+                       smp_mb__after_atomic_inc();
+                       mutex_unlock(&vs->dev.mutex);
+                       return 0;
+               }
+               mutex_unlock(&tv_tpg->tv_tpg_mutex);
+       }
+       mutex_unlock(&tcm_vhost_mutex);
+       return -EINVAL;
+}
+
+static int vhost_scsi_clear_endpoint(
+       struct vhost_scsi *vs,
+       struct vhost_scsi_target *t)
+{
+       struct tcm_vhost_tport *tv_tport;
+       struct tcm_vhost_tpg *tv_tpg;
+       int index, ret;
+
+       mutex_lock(&vs->dev.mutex);
+       /* Verify that ring has been setup correctly. */
+       for (index = 0; index < vs->dev.nvqs; ++index) {
+               if (!vhost_vq_access_ok(&vs->vqs[index])) {
+                       ret = -EFAULT;
+                       goto err;
+               }
+       }
+
+       if (!vs->vs_tpg) {
+               ret = -ENODEV;
+               goto err;
+       }
+       tv_tpg = vs->vs_tpg;
+       tv_tport = tv_tpg->tport;
+
+       if (strcmp(tv_tport->tport_name, t->vhost_wwpn) ||
+           (tv_tpg->tport_tpgt != t->vhost_tpgt)) {
+               pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu"
+                       " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n",
+                       tv_tport->tport_name, tv_tpg->tport_tpgt,
+                       t->vhost_wwpn, t->vhost_tpgt);
+               ret = -EINVAL;
+               goto err;
+       }
+       tv_tpg->tv_tpg_vhost_count--;
+       vs->vs_tpg = NULL;
+       mutex_unlock(&vs->dev.mutex);
+
+       return 0;
+
+err:
+       mutex_unlock(&vs->dev.mutex);
+       return ret;
+}
+
+static int vhost_scsi_open(struct inode *inode, struct file *f)
+{
+       struct vhost_scsi *s;
+       int r;
+
+       s = kzalloc(sizeof(*s), GFP_KERNEL);
+       if (!s)
+               return -ENOMEM;
+
+       vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work);
+       INIT_LIST_HEAD(&s->vs_completion_list);
+       spin_lock_init(&s->vs_completion_lock);
+
+       s->vqs[VHOST_SCSI_VQ_CTL].handle_kick = vhost_scsi_ctl_handle_kick;
+       s->vqs[VHOST_SCSI_VQ_EVT].handle_kick = vhost_scsi_evt_handle_kick;
+       s->vqs[VHOST_SCSI_VQ_IO].handle_kick = vhost_scsi_handle_kick;
+       r = vhost_dev_init(&s->dev, s->vqs, 3);
+       if (r < 0) {
+               kfree(s);
+               return r;
+       }
+
+       f->private_data = s;
+       return 0;
+}
+
+static int vhost_scsi_release(struct inode *inode, struct file *f)
+{
+       struct vhost_scsi *s = f->private_data;
+
+       if (s->vs_tpg && s->vs_tpg->tport) {
+               struct vhost_scsi_target backend;
+
+               memcpy(backend.vhost_wwpn, s->vs_tpg->tport->tport_name,
+                               sizeof(backend.vhost_wwpn));
+               backend.vhost_tpgt = s->vs_tpg->tport_tpgt;
+               vhost_scsi_clear_endpoint(s, &backend);
+       }
+
+       vhost_dev_cleanup(&s->dev, false);
+       kfree(s);
+       return 0;
+}
+
+static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index)
+{
+       vhost_poll_flush(&vs->dev.vqs[index].poll);
+}
+
+static void vhost_scsi_flush(struct vhost_scsi *vs)
+{
+       vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_CTL);
+       vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_EVT);
+       vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_IO);
+}
+
+static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
+{
+       if (features & ~VHOST_FEATURES)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&vs->dev.mutex);
+       if ((features & (1 << VHOST_F_LOG_ALL)) &&
+           !vhost_log_access_ok(&vs->dev)) {
+               mutex_unlock(&vs->dev.mutex);
+               return -EFAULT;
+       }
+       vs->dev.acked_features = features;
+       smp_wmb();
+       vhost_scsi_flush(vs);
+       mutex_unlock(&vs->dev.mutex);
+       return 0;
+}
+
+static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl,
+                               unsigned long arg)
+{
+       struct vhost_scsi *vs = f->private_data;
+       struct vhost_scsi_target backend;
+       void __user *argp = (void __user *)arg;
+       u64 __user *featurep = argp;
+       u64 features;
+       int r, abi_version = VHOST_SCSI_ABI_VERSION;
+
+       switch (ioctl) {
+       case VHOST_SCSI_SET_ENDPOINT:
+               if (copy_from_user(&backend, argp, sizeof backend))
+                       return -EFAULT;
+               if (backend.reserved != 0)
+                       return -EOPNOTSUPP;
+
+               return vhost_scsi_set_endpoint(vs, &backend);
+       case VHOST_SCSI_CLEAR_ENDPOINT:
+               if (copy_from_user(&backend, argp, sizeof backend))
+                       return -EFAULT;
+               if (backend.reserved != 0)
+                       return -EOPNOTSUPP;
+
+               return vhost_scsi_clear_endpoint(vs, &backend);
+       case VHOST_SCSI_GET_ABI_VERSION:
+               if (copy_to_user(argp, &abi_version, sizeof abi_version))
+                       return -EFAULT;
+               return 0;
+       case VHOST_GET_FEATURES:
+               features = VHOST_FEATURES;
+               if (copy_to_user(featurep, &features, sizeof features))
+                       return -EFAULT;
+               return 0;
+       case VHOST_SET_FEATURES:
+               if (copy_from_user(&features, featurep, sizeof features))
+                       return -EFAULT;
+               return vhost_scsi_set_features(vs, features);
+       default:
+               mutex_lock(&vs->dev.mutex);
+               r = vhost_dev_ioctl(&vs->dev, ioctl, arg);
+               mutex_unlock(&vs->dev.mutex);
+               return r;
+       }
+}
+
+#ifdef CONFIG_COMPAT
+static long vhost_scsi_compat_ioctl(struct file *f, unsigned int ioctl,
+                               unsigned long arg)
+{
+       return vhost_scsi_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
+}
+#endif
+
+static const struct file_operations vhost_scsi_fops = {
+       .owner          = THIS_MODULE,
+       .release        = vhost_scsi_release,
+       .unlocked_ioctl = vhost_scsi_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = vhost_scsi_compat_ioctl,
+#endif
+       .open           = vhost_scsi_open,
+       .llseek         = noop_llseek,
+};
+
+static struct miscdevice vhost_scsi_misc = {
+       MISC_DYNAMIC_MINOR,
+       "vhost-scsi",
+       &vhost_scsi_fops,
+};
+
+static int __init vhost_scsi_register(void)
+{
+       return misc_register(&vhost_scsi_misc);
+}
+
+static int vhost_scsi_deregister(void)
+{
+       return misc_deregister(&vhost_scsi_misc);
+}
+
+static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport)
+{
+       switch (tport->tport_proto_id) {
+       case SCSI_PROTOCOL_SAS:
+               return "SAS";
+       case SCSI_PROTOCOL_FCP:
+               return "FCP";
+       case SCSI_PROTOCOL_ISCSI:
+               return "iSCSI";
+       default:
+               break;
+       }
+
+       return "Unknown";
+}
+
+static int tcm_vhost_port_link(struct se_portal_group *se_tpg,
+       struct se_lun *lun)
+{
+       struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+
+       mutex_lock(&tv_tpg->tv_tpg_mutex);
+       tv_tpg->tv_tpg_port_count++;
+       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+
+       return 0;
+}
+
+static void tcm_vhost_port_unlink(struct se_portal_group *se_tpg,
+       struct se_lun *se_lun)
+{
+       struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+
+       mutex_lock(&tv_tpg->tv_tpg_mutex);
+       tv_tpg->tv_tpg_port_count--;
+       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+}
+
+static struct se_node_acl *tcm_vhost_make_nodeacl(
+       struct se_portal_group *se_tpg,
+       struct config_group *group,
+       const char *name)
+{
+       struct se_node_acl *se_nacl, *se_nacl_new;
+       struct tcm_vhost_nacl *nacl;
+       u64 wwpn = 0;
+       u32 nexus_depth;
+
+       /* tcm_vhost_parse_wwn(name, &wwpn, 1) < 0)
+               return ERR_PTR(-EINVAL); */
+       se_nacl_new = tcm_vhost_alloc_fabric_acl(se_tpg);
+       if (!se_nacl_new)
+               return ERR_PTR(-ENOMEM);
+
+       nexus_depth = 1;
+       /*
+        * se_nacl_new may be released by core_tpg_add_initiator_node_acl()
+        * when converting a NodeACL from demo mode -> explict
+        */
+       se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,
+                               name, nexus_depth);
+       if (IS_ERR(se_nacl)) {
+               tcm_vhost_release_fabric_acl(se_tpg, se_nacl_new);
+               return se_nacl;
+       }
+       /*
+        * Locate our struct tcm_vhost_nacl and set the FC Nport WWPN
+        */
+       nacl = container_of(se_nacl, struct tcm_vhost_nacl, se_node_acl);
+       nacl->iport_wwpn = wwpn;
+
+       return se_nacl;
+}
+
+static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl)
+{
+       struct tcm_vhost_nacl *nacl = container_of(se_acl,
+                               struct tcm_vhost_nacl, se_node_acl);
+       core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1);
+       kfree(nacl);
+}
+
+static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg,
+       const char *name)
+{
+       struct se_portal_group *se_tpg;
+       struct tcm_vhost_nexus *tv_nexus;
+
+       mutex_lock(&tv_tpg->tv_tpg_mutex);
+       if (tv_tpg->tpg_nexus) {
+               mutex_unlock(&tv_tpg->tv_tpg_mutex);
+               pr_debug("tv_tpg->tpg_nexus already exists\n");
+               return -EEXIST;
+       }
+       se_tpg = &tv_tpg->se_tpg;
+
+       tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL);
+       if (!tv_nexus) {
+               mutex_unlock(&tv_tpg->tv_tpg_mutex);
+               pr_err("Unable to allocate struct tcm_vhost_nexus\n");
+               return -ENOMEM;
+       }
+       /*
+        *  Initialize the struct se_session pointer
+        */
+       tv_nexus->tvn_se_sess = transport_init_session();
+       if (IS_ERR(tv_nexus->tvn_se_sess)) {
+               mutex_unlock(&tv_tpg->tv_tpg_mutex);
+               kfree(tv_nexus);
+               return -ENOMEM;
+       }
+       /*
+        * Since we are running in 'demo mode' this call with generate a
+        * struct se_node_acl for the tcm_vhost struct se_portal_group with
+        * the SCSI Initiator port name of the passed configfs group 'name'.
+        */
+       tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
+                               se_tpg, (unsigned char *)name);
+       if (!tv_nexus->tvn_se_sess->se_node_acl) {
+               mutex_unlock(&tv_tpg->tv_tpg_mutex);
+               pr_debug("core_tpg_check_initiator_node_acl() failed"
+                               " for %s\n", name);
+               transport_free_session(tv_nexus->tvn_se_sess);
+               kfree(tv_nexus);
+               return -ENOMEM;
+       }
+       /*
+        * Now register the TCM vhost virtual I_T Nexus as active with the
+        * call to __transport_register_session()
+        */
+       __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
+                       tv_nexus->tvn_se_sess, tv_nexus);
+       tv_tpg->tpg_nexus = tv_nexus;
+
+       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+       return 0;
+}
+
+static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg)
+{
+       struct se_session *se_sess;
+       struct tcm_vhost_nexus *tv_nexus;
+
+       mutex_lock(&tpg->tv_tpg_mutex);
+       tv_nexus = tpg->tpg_nexus;
+       if (!tv_nexus) {
+               mutex_unlock(&tpg->tv_tpg_mutex);
+               return -ENODEV;
+       }
+
+       se_sess = tv_nexus->tvn_se_sess;
+       if (!se_sess) {
+               mutex_unlock(&tpg->tv_tpg_mutex);
+               return -ENODEV;
+       }
+
+       if (tpg->tv_tpg_port_count != 0) {
+               mutex_unlock(&tpg->tv_tpg_mutex);
+               pr_err("Unable to remove TCM_vhost I_T Nexus with"
+                       " active TPG port count: %d\n",
+                       tpg->tv_tpg_port_count);
+               return -EBUSY;
+       }
+
+       if (tpg->tv_tpg_vhost_count != 0) {
+               mutex_unlock(&tpg->tv_tpg_mutex);
+               pr_err("Unable to remove TCM_vhost I_T Nexus with"
+                       " active TPG vhost count: %d\n",
+                       tpg->tv_tpg_vhost_count);
+               return -EBUSY;
+       }
+
+       pr_debug("TCM_vhost_ConfigFS: Removing I_T Nexus to emulated"
+               " %s Initiator Port: %s\n", tcm_vhost_dump_proto_id(tpg->tport),
+               tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
+       /*
+        * Release the SCSI I_T Nexus to the emulated vhost Target Port
+        */
+       transport_deregister_session(tv_nexus->tvn_se_sess);
+       tpg->tpg_nexus = NULL;
+       mutex_unlock(&tpg->tv_tpg_mutex);
+
+       kfree(tv_nexus);
+       return 0;
+}
+
+static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg,
+       char *page)
+{
+       struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       struct tcm_vhost_nexus *tv_nexus;
+       ssize_t ret;
+
+       mutex_lock(&tv_tpg->tv_tpg_mutex);
+       tv_nexus = tv_tpg->tpg_nexus;
+       if (!tv_nexus) {
+               mutex_unlock(&tv_tpg->tv_tpg_mutex);
+               return -ENODEV;
+       }
+       ret = snprintf(page, PAGE_SIZE, "%s\n",
+                       tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
+       mutex_unlock(&tv_tpg->tv_tpg_mutex);
+
+       return ret;
+}
+
+static ssize_t tcm_vhost_tpg_store_nexus(struct se_portal_group *se_tpg,
+       const char *page,
+       size_t count)
+{
+       struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+       struct tcm_vhost_tport *tport_wwn = tv_tpg->tport;
+       unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr;
+       int ret;
+       /*
+        * Shutdown the active I_T nexus if 'NULL' is passed..
+        */
+       if (!strncmp(page, "NULL", 4)) {
+               ret = tcm_vhost_drop_nexus(tv_tpg);
+               return (!ret) ? count : ret;
+       }
+       /*
+        * Otherwise make sure the passed virtual Initiator port WWN matches
+        * the fabric protocol_id set in tcm_vhost_make_tport(), and call
+        * tcm_vhost_make_nexus().
+        */
+       if (strlen(page) >= TCM_VHOST_NAMELEN) {
+               pr_err("Emulated NAA Sas Address: %s, exceeds"
+                               " max: %d\n", page, TCM_VHOST_NAMELEN);
+               return -EINVAL;
+       }
+       snprintf(&i_port[0], TCM_VHOST_NAMELEN, "%s", page);
+
+       ptr = strstr(i_port, "naa.");
+       if (ptr) {
+               if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) {
+                       pr_err("Passed SAS Initiator Port %s does not"
+                               " match target port protoid: %s\n", i_port,
+                               tcm_vhost_dump_proto_id(tport_wwn));
+                       return -EINVAL;
+               }
+               port_ptr = &i_port[0];
+               goto check_newline;
+       }
+       ptr = strstr(i_port, "fc.");
+       if (ptr) {
+               if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) {
+                       pr_err("Passed FCP Initiator Port %s does not"
+                               " match target port protoid: %s\n", i_port,
+                               tcm_vhost_dump_proto_id(tport_wwn));
+                       return -EINVAL;
+               }
+               port_ptr = &i_port[3]; /* Skip over "fc." */
+               goto check_newline;
+       }
+       ptr = strstr(i_port, "iqn.");
+       if (ptr) {
+               if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) {
+                       pr_err("Passed iSCSI Initiator Port %s does not"
+                               " match target port protoid: %s\n", i_port,
+                               tcm_vhost_dump_proto_id(tport_wwn));
+                       return -EINVAL;
+               }
+               port_ptr = &i_port[0];
+               goto check_newline;
+       }
+       pr_err("Unable to locate prefix for emulated Initiator Port:"
+                       " %s\n", i_port);
+       return -EINVAL;
+       /*
+        * Clear any trailing newline for the NAA WWN
+        */
+check_newline:
+       if (i_port[strlen(i_port)-1] == '\n')
+               i_port[strlen(i_port)-1] = '\0';
+
+       ret = tcm_vhost_make_nexus(tv_tpg, port_ptr);
+       if (ret < 0)
+               return ret;
+
+       return count;
+}
+
+TF_TPG_BASE_ATTR(tcm_vhost, nexus, S_IRUGO | S_IWUSR);
+
+static struct configfs_attribute *tcm_vhost_tpg_attrs[] = {
+       &tcm_vhost_tpg_nexus.attr,
+       NULL,
+};
+
+static struct se_portal_group *tcm_vhost_make_tpg(struct se_wwn *wwn,
+       struct config_group *group,
+       const char *name)
+{
+       struct tcm_vhost_tport *tport = container_of(wwn,
+                       struct tcm_vhost_tport, tport_wwn);
+
+       struct tcm_vhost_tpg *tpg;
+       unsigned long tpgt;
+       int ret;
+
+       if (strstr(name, "tpgt_") != name)
+               return ERR_PTR(-EINVAL);
+       if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)
+               return ERR_PTR(-EINVAL);
+
+       tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL);
+       if (!tpg) {
+               pr_err("Unable to allocate struct tcm_vhost_tpg");
+               return ERR_PTR(-ENOMEM);
+       }
+       mutex_init(&tpg->tv_tpg_mutex);
+       INIT_LIST_HEAD(&tpg->tv_tpg_list);
+       tpg->tport = tport;
+       tpg->tport_tpgt = tpgt;
+
+       ret = core_tpg_register(&tcm_vhost_fabric_configfs->tf_ops, wwn,
+                               &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL);
+       if (ret < 0) {
+               kfree(tpg);
+               return NULL;
+       }
+       mutex_lock(&tcm_vhost_mutex);
+       list_add_tail(&tpg->tv_tpg_list, &tcm_vhost_list);
+       mutex_unlock(&tcm_vhost_mutex);
+
+       return &tpg->se_tpg;
+}
+
+static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg)
+{
+       struct tcm_vhost_tpg *tpg = container_of(se_tpg,
+                               struct tcm_vhost_tpg, se_tpg);
+
+       mutex_lock(&tcm_vhost_mutex);
+       list_del(&tpg->tv_tpg_list);
+       mutex_unlock(&tcm_vhost_mutex);
+       /*
+        * Release the virtual I_T Nexus for this vhost TPG
+        */
+       tcm_vhost_drop_nexus(tpg);
+       /*
+        * Deregister the se_tpg from TCM..
+        */
+       core_tpg_deregister(se_tpg);
+       kfree(tpg);
+}
+
+static struct se_wwn *tcm_vhost_make_tport(struct target_fabric_configfs *tf,
+       struct config_group *group,
+       const char *name)
+{
+       struct tcm_vhost_tport *tport;
+       char *ptr;
+       u64 wwpn = 0;
+       int off = 0;
+
+       /* if (tcm_vhost_parse_wwn(name, &wwpn, 1) < 0)
+               return ERR_PTR(-EINVAL); */
+
+       tport = kzalloc(sizeof(struct tcm_vhost_tport), GFP_KERNEL);
+       if (!tport) {
+               pr_err("Unable to allocate struct tcm_vhost_tport");
+               return ERR_PTR(-ENOMEM);
+       }
+       tport->tport_wwpn = wwpn;
+       /*
+        * Determine the emulated Protocol Identifier and Target Port Name
+        * based on the incoming configfs directory name.
+        */
+       ptr = strstr(name, "naa.");
+       if (ptr) {
+               tport->tport_proto_id = SCSI_PROTOCOL_SAS;
+               goto check_len;
+       }
+       ptr = strstr(name, "fc.");
+       if (ptr) {
+               tport->tport_proto_id = SCSI_PROTOCOL_FCP;
+               off = 3; /* Skip over "fc." */
+               goto check_len;
+       }
+       ptr = strstr(name, "iqn.");
+       if (ptr) {
+               tport->tport_proto_id = SCSI_PROTOCOL_ISCSI;
+               goto check_len;
+       }
+
+       pr_err("Unable to locate prefix for emulated Target Port:"
+                       " %s\n", name);
+       kfree(tport);
+       return ERR_PTR(-EINVAL);
+
+check_len:
+       if (strlen(name) >= TCM_VHOST_NAMELEN) {
+               pr_err("Emulated %s Address: %s, exceeds"
+                       " max: %d\n", name, tcm_vhost_dump_proto_id(tport),
+                       TCM_VHOST_NAMELEN);
+               kfree(tport);
+               return ERR_PTR(-EINVAL);
+       }
+       snprintf(&tport->tport_name[0], TCM_VHOST_NAMELEN, "%s", &name[off]);
+
+       pr_debug("TCM_VHost_ConfigFS: Allocated emulated Target"
+               " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), name);
+
+       return &tport->tport_wwn;
+}
+
+static void tcm_vhost_drop_tport(struct se_wwn *wwn)
+{
+       struct tcm_vhost_tport *tport = container_of(wwn,
+                               struct tcm_vhost_tport, tport_wwn);
+
+       pr_debug("TCM_VHost_ConfigFS: Deallocating emulated Target"
+               " %s Address: %s\n", tcm_vhost_dump_proto_id(tport),
+               tport->tport_name);
+
+       kfree(tport);
+}
+
+static ssize_t tcm_vhost_wwn_show_attr_version(
+       struct target_fabric_configfs *tf,
+       char *page)
+{
+       return sprintf(page, "TCM_VHOST fabric module %s on %s/%s"
+               "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname,
+               utsname()->machine);
+}
+
+TF_WWN_ATTR_RO(tcm_vhost, version);
+
+static struct configfs_attribute *tcm_vhost_wwn_attrs[] = {
+       &tcm_vhost_wwn_version.attr,
+       NULL,
+};
+
+static struct target_core_fabric_ops tcm_vhost_ops = {
+       .get_fabric_name                = tcm_vhost_get_fabric_name,
+       .get_fabric_proto_ident         = tcm_vhost_get_fabric_proto_ident,
+       .tpg_get_wwn                    = tcm_vhost_get_fabric_wwn,
+       .tpg_get_tag                    = tcm_vhost_get_tag,
+       .tpg_get_default_depth          = tcm_vhost_get_default_depth,
+       .tpg_get_pr_transport_id        = tcm_vhost_get_pr_transport_id,
+       .tpg_get_pr_transport_id_len    = tcm_vhost_get_pr_transport_id_len,
+       .tpg_parse_pr_out_transport_id  = tcm_vhost_parse_pr_out_transport_id,
+       .tpg_check_demo_mode            = tcm_vhost_check_true,
+       .tpg_check_demo_mode_cache      = tcm_vhost_check_true,
+       .tpg_check_demo_mode_write_protect = tcm_vhost_check_false,
+       .tpg_check_prod_mode_write_protect = tcm_vhost_check_false,
+       .tpg_alloc_fabric_acl           = tcm_vhost_alloc_fabric_acl,
+       .tpg_release_fabric_acl         = tcm_vhost_release_fabric_acl,
+       .tpg_get_inst_index             = tcm_vhost_tpg_get_inst_index,
+       .release_cmd                    = tcm_vhost_release_cmd,
+       .shutdown_session               = tcm_vhost_shutdown_session,
+       .close_session                  = tcm_vhost_close_session,
+       .sess_get_index                 = tcm_vhost_sess_get_index,
+       .sess_get_initiator_sid         = NULL,
+       .write_pending                  = tcm_vhost_write_pending,
+       .write_pending_status           = tcm_vhost_write_pending_status,
+       .set_default_node_attributes    = tcm_vhost_set_default_node_attrs,
+       .get_task_tag                   = tcm_vhost_get_task_tag,
+       .get_cmd_state                  = tcm_vhost_get_cmd_state,
+       .queue_data_in                  = tcm_vhost_queue_data_in,
+       .queue_status                   = tcm_vhost_queue_status,
+       .queue_tm_rsp                   = tcm_vhost_queue_tm_rsp,
+       .get_fabric_sense_len           = tcm_vhost_get_fabric_sense_len,
+       .set_fabric_sense_len           = tcm_vhost_set_fabric_sense_len,
+       /*
+        * Setup callers for generic logic in target_core_fabric_configfs.c
+        */
+       .fabric_make_wwn                = tcm_vhost_make_tport,
+       .fabric_drop_wwn                = tcm_vhost_drop_tport,
+       .fabric_make_tpg                = tcm_vhost_make_tpg,
+       .fabric_drop_tpg                = tcm_vhost_drop_tpg,
+       .fabric_post_link               = tcm_vhost_port_link,
+       .fabric_pre_unlink              = tcm_vhost_port_unlink,
+       .fabric_make_np                 = NULL,
+       .fabric_drop_np                 = NULL,
+       .fabric_make_nodeacl            = tcm_vhost_make_nodeacl,
+       .fabric_drop_nodeacl            = tcm_vhost_drop_nodeacl,
+};
+
+static int tcm_vhost_register_configfs(void)
+{
+       struct target_fabric_configfs *fabric;
+       int ret;
+
+       pr_debug("TCM_VHOST fabric module %s on %s/%s"
+               " on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname,
+               utsname()->machine);
+       /*
+        * Register the top level struct config_item_type with TCM core
+        */
+       fabric = target_fabric_configfs_init(THIS_MODULE, "vhost");
+       if (IS_ERR(fabric)) {
+               pr_err("target_fabric_configfs_init() failed\n");
+               return PTR_ERR(fabric);
+       }
+       /*
+        * Setup fabric->tf_ops from our local tcm_vhost_ops
+        */
+       fabric->tf_ops = tcm_vhost_ops;
+       /*
+        * Setup default attribute lists for various fabric->tf_cit_tmpl
+        */
+       TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_vhost_wwn_attrs;
+       TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_vhost_tpg_attrs;
+       TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
+       TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
+       TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
+       TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;
+       TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;
+       TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;
+       TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;
+       /*
+        * Register the fabric for use within TCM
+        */
+       ret = target_fabric_configfs_register(fabric);
+       if (ret < 0) {
+               pr_err("target_fabric_configfs_register() failed"
+                               " for TCM_VHOST\n");
+               return ret;
+       }
+       /*
+        * Setup our local pointer to *fabric
+        */
+       tcm_vhost_fabric_configfs = fabric;
+       pr_debug("TCM_VHOST[0] - Set fabric -> tcm_vhost_fabric_configfs\n");
+       return 0;
+};
+
+static void tcm_vhost_deregister_configfs(void)
+{
+       if (!tcm_vhost_fabric_configfs)
+               return;
+
+       target_fabric_configfs_deregister(tcm_vhost_fabric_configfs);
+       tcm_vhost_fabric_configfs = NULL;
+       pr_debug("TCM_VHOST[0] - Cleared tcm_vhost_fabric_configfs\n");
+};
+
+static int __init tcm_vhost_init(void)
+{
+       int ret = -ENOMEM;
+       /*
+        * Use our own dedicated workqueue for submitting I/O into
+        * target core to avoid contention within system_wq.
+        */
+       tcm_vhost_workqueue = alloc_workqueue("tcm_vhost", 0, 0);
+       if (!tcm_vhost_workqueue)
+               goto out;
+
+       ret = vhost_scsi_register();
+       if (ret < 0)
+               goto out_destroy_workqueue;
+
+       ret = tcm_vhost_register_configfs();
+       if (ret < 0)
+               goto out_vhost_scsi_deregister;
+
+       return 0;
+
+out_vhost_scsi_deregister:
+       vhost_scsi_deregister();
+out_destroy_workqueue:
+       destroy_workqueue(tcm_vhost_workqueue);
+out:
+       return ret;
+};
+
+static void tcm_vhost_exit(void)
+{
+       tcm_vhost_deregister_configfs();
+       vhost_scsi_deregister();
+       destroy_workqueue(tcm_vhost_workqueue);
+};
+
+MODULE_DESCRIPTION("TCM_VHOST series fabric driver");
+MODULE_LICENSE("GPL");
+module_init(tcm_vhost_init);
+module_exit(tcm_vhost_exit);
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h
new file mode 100644 (file)
index 0000000..d9e9355
--- /dev/null
@@ -0,0 +1,103 @@
+#define TCM_VHOST_VERSION  "v0.1"
+#define TCM_VHOST_NAMELEN 256
+#define TCM_VHOST_MAX_CDB_SIZE 32
+
+struct tcm_vhost_cmd {
+       /* Descriptor from vhost_get_vq_desc() for virt_queue segment */
+       int tvc_vq_desc;
+       /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */
+       u64 tvc_tag;
+       /* The number of scatterlists associated with this cmd */
+       u32 tvc_sgl_count;
+       /* Saved unpacked SCSI LUN for tcm_vhost_submission_work() */
+       u32 tvc_lun;
+       /* Pointer to the SGL formatted memory from virtio-scsi */
+       struct scatterlist *tvc_sgl;
+       /* Pointer to response */
+       struct virtio_scsi_cmd_resp __user *tvc_resp;
+       /* Pointer to vhost_scsi for our device */
+       struct vhost_scsi *tvc_vhost;
+       /* The TCM I/O descriptor that is accessed via container_of() */
+       struct se_cmd tvc_se_cmd;
+       /* work item used for cmwq dispatch to tcm_vhost_submission_work() */
+       struct work_struct work;
+       /* Copy of the incoming SCSI command descriptor block (CDB) */
+       unsigned char tvc_cdb[TCM_VHOST_MAX_CDB_SIZE];
+       /* Sense buffer that will be mapped into outgoing status */
+       unsigned char tvc_sense_buf[TRANSPORT_SENSE_BUFFER];
+       /* Completed commands list, serviced from vhost worker thread */
+       struct list_head tvc_completion_list;
+};
+
+struct tcm_vhost_nexus {
+       /* Pointer to TCM session for I_T Nexus */
+       struct se_session *tvn_se_sess;
+};
+
+struct tcm_vhost_nacl {
+       /* Binary World Wide unique Port Name for Vhost Initiator port */
+       u64 iport_wwpn;
+       /* ASCII formatted WWPN for Sas Initiator port */
+       char iport_name[TCM_VHOST_NAMELEN];
+       /* Returned by tcm_vhost_make_nodeacl() */
+       struct se_node_acl se_node_acl;
+};
+
+struct tcm_vhost_tpg {
+       /* Vhost port target portal group tag for TCM */
+       u16 tport_tpgt;
+       /* Used to track number of TPG Port/Lun Links wrt to explict I_T Nexus shutdown */
+       int tv_tpg_port_count;
+       /* Used for vhost_scsi device reference to tpg_nexus, protected by tv_tpg_mutex */
+       int tv_tpg_vhost_count;
+       /* list for tcm_vhost_list */
+       struct list_head tv_tpg_list;
+       /* Used to protect access for tpg_nexus */
+       struct mutex tv_tpg_mutex;
+       /* Pointer to the TCM VHost I_T Nexus for this TPG endpoint */
+       struct tcm_vhost_nexus *tpg_nexus;
+       /* Pointer back to tcm_vhost_tport */
+       struct tcm_vhost_tport *tport;
+       /* Returned by tcm_vhost_make_tpg() */
+       struct se_portal_group se_tpg;
+};
+
+struct tcm_vhost_tport {
+       /* SCSI protocol the tport is providing */
+       u8 tport_proto_id;
+       /* Binary World Wide unique Port Name for Vhost Target port */
+       u64 tport_wwpn;
+       /* ASCII formatted WWPN for Vhost Target port */
+       char tport_name[TCM_VHOST_NAMELEN];
+       /* Returned by tcm_vhost_make_tport() */
+       struct se_wwn tport_wwn;
+};
+
+/*
+ * As per request from MST, keep TCM_VHOST related ioctl defines out of
+ * linux/vhost.h (user-space) for now..
+ */
+
+#include <linux/vhost.h>
+
+/*
+ * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
+ *
+ * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate +
+ *            RFC-v2 vhost-scsi userspace.  Add GET_ABI_VERSION ioctl usage
+ */
+
+#define VHOST_SCSI_ABI_VERSION 0
+
+struct vhost_scsi_target {
+       int abi_version;
+       char vhost_wwpn[TRANSPORT_IQN_LEN];
+       unsigned short vhost_tpgt;
+       unsigned short reserved;
+};
+
+/* VHOST_SCSI specific defines */
+#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
+#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
+/* Changing this breaks userspace. */
+#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int)
index 2e471c22abf5a5e835704e71767017923f747c0c..88e92041d8f02d6136458535c61c3090c304e576 100644 (file)
@@ -372,8 +372,15 @@ static void fb_flashcursor(struct work_struct *work)
        struct vc_data *vc = NULL;
        int c;
        int mode;
+       int ret;
+
+       /* FIXME: we should sort out the unbind locking instead */
+       /* instead we just fail to flash the cursor if we can't get
+        * the lock instead of blocking fbcon deinit */
+       ret = console_trylock();
+       if (ret == 0)
+               return;
 
-       console_lock();
        if (ops && ops->currcon != -1)
                vc = vc_cons[ops->currcon].d;
 
index d90062b211f8a107a142f439129a6f8d699aa1de..92d08e7fcba2377088bf4b45b12e18f773f6bb23 100644 (file)
@@ -91,6 +91,11 @@ static struct w1_family w1_therm_family_DS28EA00 = {
        .fops = &w1_therm_fops,
 };
 
+static struct w1_family w1_therm_family_DS1825 = {
+       .fid = W1_THERM_DS1825,
+       .fops = &w1_therm_fops,
+};
+
 struct w1_therm_family_converter
 {
        u8                      broken;
@@ -120,6 +125,10 @@ static struct w1_therm_family_converter w1_therm_families[] = {
                .f              = &w1_therm_family_DS28EA00,
                .convert        = w1_DS18B20_convert_temp
        },
+       {
+               .f              = &w1_therm_family_DS1825,
+               .convert        = w1_DS18B20_convert_temp
+       }
 };
 
 static inline int w1_DS18B20_convert_temp(u8 rom[9])
index b00ada44a89be8989a46912fb85e976624d5e586..a1f0ce151d53d902813ef9f6521ee4973c9f053b 100644 (file)
@@ -39,6 +39,7 @@
 #define W1_EEPROM_DS2431       0x2D
 #define W1_FAMILY_DS2760       0x30
 #define W1_FAMILY_DS2780       0x32
+#define W1_THERM_DS1825                0x3B
 #define W1_FAMILY_DS2781       0x3D
 #define W1_THERM_DS28EA00      0x42
 
index 3fe82d0e8caae583a2bdd8ac41a30bec5540fa43..5b06d31ab6a98678320b8c88456f0d3abde2cb35 100644 (file)
@@ -166,18 +166,17 @@ static long booke_wdt_ioctl(struct file *file,
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
-               if (copy_to_user((void *)arg, &ident, sizeof(ident)))
-                       return -EFAULT;
+               return copy_to_user(p, &ident, sizeof(ident)) ? -EFAULT : 0;
        case WDIOC_GETSTATUS:
                return put_user(0, p);
        case WDIOC_GETBOOTSTATUS:
                /* XXX: something is clearing TSR */
                tmp = mfspr(SPRN_TSR) & TSR_WRS(3);
                /* returns CARDRESET if last reset was caused by the WDT */
-               return (tmp ? WDIOF_CARDRESET : 0);
+               return put_user((tmp ? WDIOF_CARDRESET : 0), p);
        case WDIOC_SETOPTIONS:
                if (get_user(tmp, p))
-                       return -EINVAL;
+                       return -EFAULT;
                if (tmp == WDIOS_ENABLECARD) {
                        booke_wdt_ping();
                        break;
index 3f75129eb0a9f06cd0a7d194a3c390f5ee9bfd3f..f7abbaeebcaf51466efbc493c2fb433b01408bf3 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
-#include <linux/delay.h>
 
 #include <linux/mfd/da9052/reg.h>
 #include <linux/mfd/da9052/da9052.h>
index d4c50d63acbc14b03b8bcf3aac7d8c80fb1ea2d7..97ca359ae2bdfb8d072ee62348114a252660adf9 100644 (file)
@@ -101,19 +101,6 @@ static int platform_pci_resume(struct pci_dev *pdev)
        return 0;
 }
 
-static void __devinit prepare_shared_info(void)
-{
-#ifdef CONFIG_KEXEC
-       unsigned long addr;
-       struct shared_info *hvm_shared_info;
-
-       addr = alloc_xen_mmio(PAGE_SIZE);
-       hvm_shared_info = ioremap(addr, PAGE_SIZE);
-       memset(hvm_shared_info, 0, PAGE_SIZE);
-       xen_hvm_prepare_kexec(hvm_shared_info, addr >> PAGE_SHIFT);
-#endif
-}
-
 static int __devinit platform_pci_init(struct pci_dev *pdev,
                                       const struct pci_device_id *ent)
 {
@@ -151,8 +138,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
        platform_mmio = mmio_addr;
        platform_mmiolen = mmio_len;
 
-       prepare_shared_info();
-
        if (!xen_have_vector_callback) {
                ret = xen_allocate_irq(pdev);
                if (ret) {
index 181fa8158a8b01d48393bb9d2b1d9d4e0bf9e79e..858c9714b2f390a26e1a1450f196d7abf6e14340 100644 (file)
@@ -37,7 +37,6 @@ struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
      */
 
 struct zorro_bus {
-       struct list_head devices;       /* list of devices on this bus */
        struct device dev;
 };
 
@@ -136,7 +135,6 @@ static int __init amiga_zorro_probe(struct platform_device *pdev)
        if (!bus)
                return -ENOMEM;
 
-       INIT_LIST_HEAD(&bus->devices);
        bus->dev.parent = &pdev->dev;
        dev_set_name(&bus->dev, "zorro");
        error = device_register(&bus->dev);
index 1feb68ecef9509dd88a4323f3193845af6a84e15..842d00048a652f8cb9ebda7eeea40d62e9cb6720 100644 (file)
@@ -94,25 +94,21 @@ static struct dentry *get_next_positive_subdir(struct dentry *prev,
 {
        struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb);
        struct list_head *next;
-       struct dentry *p, *q;
+       struct dentry *q;
 
        spin_lock(&sbi->lookup_lock);
+       spin_lock(&root->d_lock);
 
-       if (prev == NULL) {
-               spin_lock(&root->d_lock);
+       if (prev)
+               next = prev->d_u.d_child.next;
+       else {
                prev = dget_dlock(root);
                next = prev->d_subdirs.next;
-               p = prev;
-               goto start;
        }
 
-       p = prev;
-       spin_lock(&p->d_lock);
-again:
-       next = p->d_u.d_child.next;
-start:
+cont:
        if (next == &root->d_subdirs) {
-               spin_unlock(&p->d_lock);
+               spin_unlock(&root->d_lock);
                spin_unlock(&sbi->lookup_lock);
                dput(prev);
                return NULL;
@@ -121,16 +117,15 @@ start:
        q = list_entry(next, struct dentry, d_u.d_child);
 
        spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
-       /* Negative dentry - try next */
-       if (!simple_positive(q)) {
-               spin_unlock(&p->d_lock);
-               lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_);
-               p = q;
-               goto again;
+       /* Already gone or negative dentry (under construction) - try next */
+       if (q->d_count == 0 || !simple_positive(q)) {
+               spin_unlock(&q->d_lock);
+               next = q->d_u.d_child.next;
+               goto cont;
        }
        dget_dlock(q);
        spin_unlock(&q->d_lock);
-       spin_unlock(&p->d_lock);
+       spin_unlock(&root->d_lock);
        spin_unlock(&sbi->lookup_lock);
 
        dput(prev);
@@ -404,11 +399,6 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
                        DPRINTK("checking mountpoint %p %.*s",
                                dentry, (int)dentry->d_name.len, dentry->d_name.name);
 
-                       /* Path walk currently on this dentry? */
-                       ino_count = atomic_read(&ino->count) + 2;
-                       if (dentry->d_count > ino_count)
-                               goto next;
-
                        /* Can we umount this guy */
                        if (autofs4_mount_busy(mnt, dentry))
                                goto next;
index 73922abba832d0a41c1cb01bbf5bcc0fec1cb78b..71072ab99128aadf1090e2ceab32bae67827dc9c 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -73,7 +73,7 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)
 {
        unsigned int sz = sizeof(struct bio) + extra_size;
        struct kmem_cache *slab = NULL;
-       struct bio_slab *bslab;
+       struct bio_slab *bslab, *new_bio_slabs;
        unsigned int i, entry = -1;
 
        mutex_lock(&bio_slab_lock);
@@ -97,11 +97,12 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)
 
        if (bio_slab_nr == bio_slab_max && entry == -1) {
                bio_slab_max <<= 1;
-               bio_slabs = krealloc(bio_slabs,
-                                    bio_slab_max * sizeof(struct bio_slab),
-                                    GFP_KERNEL);
-               if (!bio_slabs)
+               new_bio_slabs = krealloc(bio_slabs,
+                                        bio_slab_max * sizeof(struct bio_slab),
+                                        GFP_KERNEL);
+               if (!new_bio_slabs)
                        goto out_unlock;
+               bio_slabs = new_bio_slabs;
        }
        if (entry == -1)
                entry = bio_slab_nr++;
@@ -1312,7 +1313,7 @@ EXPORT_SYMBOL(bio_copy_kern);
  * Note that this code is very hard to test under normal circumstances because
  * direct-io pins the pages with get_user_pages().  This makes
  * is_page_cache_freeable return false, and the VM will not clean the pages.
- * But other code (eg, pdflush) could clean the pages if they are mapped
+ * But other code (eg, flusher threads) could clean the pages if they are mapped
  * pagecache.
  *
  * Simply disabling the call to bio_set_pages_dirty() is a good way to test the
index 1e519195d45bd1ab466f8b7ee12505f35a45d271..38e721b35d45388cb0febed8021a02277a4a2f1b 100644 (file)
@@ -1578,10 +1578,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
                         unsigned long nr_segs, loff_t pos)
 {
        struct file *file = iocb->ki_filp;
+       struct blk_plug plug;
        ssize_t ret;
 
        BUG_ON(iocb->ki_pos != pos);
 
+       blk_start_plug(&plug);
        ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
        if (ret > 0 || ret == -EIOCBQUEUED) {
                ssize_t err;
@@ -1590,6 +1592,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
                if (err < 0 && ret > 0)
                        ret = err;
        }
+       blk_finish_plug(&plug);
        return ret;
 }
 EXPORT_SYMBOL_GPL(blkdev_aio_write);
index a256f3b2a845f22ef1c0c8dd1310364a96b651f5..ff6475f409d64aaade5499f9d0cee64c2989a80c 100644 (file)
@@ -1438,10 +1438,10 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
        ret = extent_from_logical(fs_info, logical, path,
                                        &found_key);
        btrfs_release_path(path);
-       if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
-               ret = -EINVAL;
        if (ret < 0)
                return ret;
+       if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+               return -EINVAL;
 
        extent_item_pos = logical - found_key.objectid;
        ret = iterate_extent_inodes(fs_info, found_key.objectid,
index 86eff48dab786d525d3395d31dcf3f45a11dafc1..43d1c5a3a030888544d8dd8f7b36239386552d08 100644 (file)
@@ -818,6 +818,7 @@ static void free_workspace(int type, struct list_head *workspace)
        btrfs_compress_op[idx]->free_workspace(workspace);
        atomic_dec(alloc_workspace);
 wake:
+       smp_mb();
        if (waitqueue_active(workspace_wait))
                wake_up(workspace_wait);
 }
index 9d7621f271ff1e5b3f2b57931d96dad265678d7d..6d183f60d63a0521e8c4461e4d5fd705163d17d1 100644 (file)
@@ -420,12 +420,6 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
        }
        spin_unlock(&fs_info->tree_mod_seq_lock);
 
-       /*
-        * we removed the lowest blocker from the blocker list, so there may be
-        * more processible delayed refs.
-        */
-       wake_up(&fs_info->tree_mod_seq_wait);
-
        /*
         * anything that's lower than the lowest existing (read: blocked)
         * sequence number can be removed from the tree.
@@ -631,6 +625,9 @@ __tree_mod_log_free_eb(struct btrfs_fs_info *fs_info, struct extent_buffer *eb)
        u32 nritems;
        int ret;
 
+       if (btrfs_header_level(eb) == 0)
+               return;
+
        nritems = btrfs_header_nritems(eb);
        for (i = nritems - 1; i >= 0; i--) {
                ret = tree_mod_log_insert_key_locked(fs_info, eb, i,
index 4bab807227ad938c87039ea2aa1ef8f94fe46146..0d195b5076604b4350f88de9a58e9f4836fd785a 100644 (file)
@@ -1252,7 +1252,6 @@ struct btrfs_fs_info {
        atomic_t tree_mod_seq;
        struct list_head tree_mod_seq_list;
        struct seq_list tree_mod_seq_elem;
-       wait_queue_head_t tree_mod_seq_wait;
 
        /* this protects tree_mod_log */
        rwlock_t tree_mod_log_lock;
@@ -3192,7 +3191,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
 int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
                          struct bio *bio, u32 *dst);
 int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
-                             struct bio *bio, u64 logical_offset, u32 *dst);
+                             struct bio *bio, u64 logical_offset);
 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root,
                             u64 objectid, u64 pos,
index 335605c8ceab730394d45d9975adaa7025203dd7..07d5eeb1e6f1df1f8ae2ddf94218b1f45298aeda 100644 (file)
@@ -512,8 +512,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
 
        rb_erase(&delayed_item->rb_node, root);
        delayed_item->delayed_node->count--;
-       atomic_dec(&delayed_root->items);
-       if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND &&
+       if (atomic_dec_return(&delayed_root->items) <
+           BTRFS_DELAYED_BACKGROUND &&
            waitqueue_active(&delayed_root->wait))
                wake_up(&delayed_root->wait);
 }
@@ -1028,9 +1028,10 @@ do_again:
                btrfs_release_delayed_item(prev);
                ret = 0;
                btrfs_release_path(path);
-               if (curr)
+               if (curr) {
+                       mutex_unlock(&node->mutex);
                        goto do_again;
-               else
+               else
                        goto delete_fail;
        }
 
@@ -1055,8 +1056,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
                delayed_node->count--;
 
                delayed_root = delayed_node->root->fs_info->delayed_root;
-               atomic_dec(&delayed_root->items);
-               if (atomic_read(&delayed_root->items) <
+               if (atomic_dec_return(&delayed_root->items) <
                    BTRFS_DELAYED_BACKGROUND &&
                    waitqueue_active(&delayed_root->wait))
                        wake_up(&delayed_root->wait);
index da7419ed01bb7e520cfbcac0fbef44ef607a92e5..ae94117733973e2d7aa8ea590c171fcf2e6bd26a 100644 (file)
 static int comp_tree_refs(struct btrfs_delayed_tree_ref *ref2,
                          struct btrfs_delayed_tree_ref *ref1)
 {
-       if (ref1->node.type == BTRFS_TREE_BLOCK_REF_KEY) {
-               if (ref1->root < ref2->root)
-                       return -1;
-               if (ref1->root > ref2->root)
-                       return 1;
-       } else {
-               if (ref1->parent < ref2->parent)
-                       return -1;
-               if (ref1->parent > ref2->parent)
-                       return 1;
-       }
+       if (ref1->root < ref2->root)
+               return -1;
+       if (ref1->root > ref2->root)
+               return 1;
+       if (ref1->parent < ref2->parent)
+               return -1;
+       if (ref1->parent > ref2->parent)
+               return 1;
        return 0;
 }
 
@@ -85,7 +82,8 @@ static int comp_data_refs(struct btrfs_delayed_data_ref *ref2,
  * type of the delayed backrefs and content of delayed backrefs.
  */
 static int comp_entry(struct btrfs_delayed_ref_node *ref2,
-                     struct btrfs_delayed_ref_node *ref1)
+                     struct btrfs_delayed_ref_node *ref1,
+                     bool compare_seq)
 {
        if (ref1->bytenr < ref2->bytenr)
                return -1;
@@ -102,10 +100,12 @@ static int comp_entry(struct btrfs_delayed_ref_node *ref2,
        if (ref1->type > ref2->type)
                return 1;
        /* merging of sequenced refs is not allowed */
-       if (ref1->seq < ref2->seq)
-               return -1;
-       if (ref1->seq > ref2->seq)
-               return 1;
+       if (compare_seq) {
+               if (ref1->seq < ref2->seq)
+                       return -1;
+               if (ref1->seq > ref2->seq)
+                       return 1;
+       }
        if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY ||
            ref1->type == BTRFS_SHARED_BLOCK_REF_KEY) {
                return comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref2),
@@ -139,7 +139,7 @@ static struct btrfs_delayed_ref_node *tree_insert(struct rb_root *root,
                entry = rb_entry(parent_node, struct btrfs_delayed_ref_node,
                                 rb_node);
 
-               cmp = comp_entry(entry, ins);
+               cmp = comp_entry(entry, ins, 1);
                if (cmp < 0)
                        p = &(*p)->rb_left;
                else if (cmp > 0)
@@ -233,6 +233,114 @@ int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans,
        return 0;
 }
 
+static void inline drop_delayed_ref(struct btrfs_trans_handle *trans,
+                                   struct btrfs_delayed_ref_root *delayed_refs,
+                                   struct btrfs_delayed_ref_node *ref)
+{
+       rb_erase(&ref->rb_node, &delayed_refs->root);
+       ref->in_tree = 0;
+       btrfs_put_delayed_ref(ref);
+       delayed_refs->num_entries--;
+       if (trans->delayed_ref_updates)
+               trans->delayed_ref_updates--;
+}
+
+static int merge_ref(struct btrfs_trans_handle *trans,
+                    struct btrfs_delayed_ref_root *delayed_refs,
+                    struct btrfs_delayed_ref_node *ref, u64 seq)
+{
+       struct rb_node *node;
+       int merged = 0;
+       int mod = 0;
+       int done = 0;
+
+       node = rb_prev(&ref->rb_node);
+       while (node) {
+               struct btrfs_delayed_ref_node *next;
+
+               next = rb_entry(node, struct btrfs_delayed_ref_node, rb_node);
+               node = rb_prev(node);
+               if (next->bytenr != ref->bytenr)
+                       break;
+               if (seq && next->seq >= seq)
+                       break;
+               if (comp_entry(ref, next, 0))
+                       continue;
+
+               if (ref->action == next->action) {
+                       mod = next->ref_mod;
+               } else {
+                       if (ref->ref_mod < next->ref_mod) {
+                               struct btrfs_delayed_ref_node *tmp;
+
+                               tmp = ref;
+                               ref = next;
+                               next = tmp;
+                               done = 1;
+                       }
+                       mod = -next->ref_mod;
+               }
+
+               merged++;
+               drop_delayed_ref(trans, delayed_refs, next);
+               ref->ref_mod += mod;
+               if (ref->ref_mod == 0) {
+                       drop_delayed_ref(trans, delayed_refs, ref);
+                       break;
+               } else {
+                       /*
+                        * You can't have multiples of the same ref on a tree
+                        * block.
+                        */
+                       WARN_ON(ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
+                               ref->type == BTRFS_SHARED_BLOCK_REF_KEY);
+               }
+
+               if (done)
+                       break;
+               node = rb_prev(&ref->rb_node);
+       }
+
+       return merged;
+}
+
+void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
+                             struct btrfs_fs_info *fs_info,
+                             struct btrfs_delayed_ref_root *delayed_refs,
+                             struct btrfs_delayed_ref_head *head)
+{
+       struct rb_node *node;
+       u64 seq = 0;
+
+       spin_lock(&fs_info->tree_mod_seq_lock);
+       if (!list_empty(&fs_info->tree_mod_seq_list)) {
+               struct seq_list *elem;
+
+               elem = list_first_entry(&fs_info->tree_mod_seq_list,
+                                       struct seq_list, list);
+               seq = elem->seq;
+       }
+       spin_unlock(&fs_info->tree_mod_seq_lock);
+
+       node = rb_prev(&head->node.rb_node);
+       while (node) {
+               struct btrfs_delayed_ref_node *ref;
+
+               ref = rb_entry(node, struct btrfs_delayed_ref_node,
+                              rb_node);
+               if (ref->bytenr != head->node.bytenr)
+                       break;
+
+               /* We can't merge refs that are outside of our seq count */
+               if (seq && ref->seq >= seq)
+                       break;
+               if (merge_ref(trans, delayed_refs, ref, seq))
+                       node = rb_prev(&head->node.rb_node);
+               else
+                       node = rb_prev(node);
+       }
+}
+
 int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info,
                            struct btrfs_delayed_ref_root *delayed_refs,
                            u64 seq)
@@ -336,18 +444,11 @@ update_existing_ref(struct btrfs_trans_handle *trans,
                 * every changing the extent allocation tree.
                 */
                existing->ref_mod--;
-               if (existing->ref_mod == 0) {
-                       rb_erase(&existing->rb_node,
-                                &delayed_refs->root);
-                       existing->in_tree = 0;
-                       btrfs_put_delayed_ref(existing);
-                       delayed_refs->num_entries--;
-                       if (trans->delayed_ref_updates)
-                               trans->delayed_ref_updates--;
-               } else {
+               if (existing->ref_mod == 0)
+                       drop_delayed_ref(trans, delayed_refs, existing);
+               else
                        WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY ||
                                existing->type == BTRFS_SHARED_BLOCK_REF_KEY);
-               }
        } else {
                WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY ||
                        existing->type == BTRFS_SHARED_BLOCK_REF_KEY);
@@ -662,9 +763,6 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
        add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr,
                                   num_bytes, parent, ref_root, level, action,
                                   for_cow);
-       if (!need_ref_seq(for_cow, ref_root) &&
-           waitqueue_active(&fs_info->tree_mod_seq_wait))
-               wake_up(&fs_info->tree_mod_seq_wait);
        spin_unlock(&delayed_refs->lock);
        if (need_ref_seq(for_cow, ref_root))
                btrfs_qgroup_record_ref(trans, &ref->node, extent_op);
@@ -713,9 +811,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
        add_delayed_data_ref(fs_info, trans, &ref->node, bytenr,
                                   num_bytes, parent, ref_root, owner, offset,
                                   action, for_cow);
-       if (!need_ref_seq(for_cow, ref_root) &&
-           waitqueue_active(&fs_info->tree_mod_seq_wait))
-               wake_up(&fs_info->tree_mod_seq_wait);
        spin_unlock(&delayed_refs->lock);
        if (need_ref_seq(for_cow, ref_root))
                btrfs_qgroup_record_ref(trans, &ref->node, extent_op);
@@ -744,8 +839,6 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
                                   num_bytes, BTRFS_UPDATE_DELAYED_HEAD,
                                   extent_op->is_data);
 
-       if (waitqueue_active(&fs_info->tree_mod_seq_wait))
-               wake_up(&fs_info->tree_mod_seq_wait);
        spin_unlock(&delayed_refs->lock);
        return 0;
 }
index 0d7c90c366b629152796c0c717c0e4cd5f50e9b1..ab5300595847e20602c307620a3a5059ca258b06 100644 (file)
@@ -167,6 +167,10 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
                                struct btrfs_trans_handle *trans,
                                u64 bytenr, u64 num_bytes,
                                struct btrfs_delayed_extent_op *extent_op);
+void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
+                             struct btrfs_fs_info *fs_info,
+                             struct btrfs_delayed_ref_root *delayed_refs,
+                             struct btrfs_delayed_ref_head *head);
 
 struct btrfs_delayed_ref_head *
 btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr);
index 62e0cafd6e250d5d1717656d3d5821e2d1bfec42..22e98e04c2eabbc0b4baeb2618033657a9344fb9 100644 (file)
@@ -377,9 +377,13 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
                ret = read_extent_buffer_pages(io_tree, eb, start,
                                               WAIT_COMPLETE,
                                               btree_get_extent, mirror_num);
-               if (!ret && !verify_parent_transid(io_tree, eb,
+               if (!ret) {
+                       if (!verify_parent_transid(io_tree, eb,
                                                   parent_transid, 0))
-                       break;
+                               break;
+                       else
+                               ret = -EIO;
+               }
 
                /*
                 * This buffer's crc is fine, but its contents are corrupted, so
@@ -754,9 +758,7 @@ static void run_one_async_done(struct btrfs_work *work)
        limit = btrfs_async_submit_limit(fs_info);
        limit = limit * 2 / 3;
 
-       atomic_dec(&fs_info->nr_async_submits);
-
-       if (atomic_read(&fs_info->nr_async_submits) < limit &&
+       if (atomic_dec_return(&fs_info->nr_async_submits) < limit &&
            waitqueue_active(&fs_info->async_submit_wait))
                wake_up(&fs_info->async_submit_wait);
 
@@ -2032,8 +2034,6 @@ int open_ctree(struct super_block *sb,
        fs_info->free_chunk_space = 0;
        fs_info->tree_mod_log = RB_ROOT;
 
-       init_waitqueue_head(&fs_info->tree_mod_seq_wait);
-
        /* readahead state */
        INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT);
        spin_lock_init(&fs_info->reada_lock);
@@ -2528,8 +2528,7 @@ retry_root_backup:
                goto fail_trans_kthread;
 
        /* do not make disk changes in broken FS */
-       if (btrfs_super_log_root(disk_super) != 0 &&
-           !(fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)) {
+       if (btrfs_super_log_root(disk_super) != 0) {
                u64 bytenr = btrfs_super_log_root(disk_super);
 
                if (fs_devices->rw_devices == 0) {
@@ -3189,30 +3188,14 @@ int close_ctree(struct btrfs_root *root)
        /* clear out the rbtree of defraggable inodes */
        btrfs_run_defrag_inodes(fs_info);
 
-       /*
-        * Here come 2 situations when btrfs is broken to flip readonly:
-        *
-        * 1. when btrfs flips readonly somewhere else before
-        * btrfs_commit_super, sb->s_flags has MS_RDONLY flag,
-        * and btrfs will skip to write sb directly to keep
-        * ERROR state on disk.
-        *
-        * 2. when btrfs flips readonly just in btrfs_commit_super,
-        * and in such case, btrfs cannot write sb via btrfs_commit_super,
-        * and since fs_state has been set BTRFS_SUPER_FLAG_ERROR flag,
-        * btrfs will cleanup all FS resources first and write sb then.
-        */
        if (!(fs_info->sb->s_flags & MS_RDONLY)) {
                ret = btrfs_commit_super(root);
                if (ret)
                        printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
        }
 
-       if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
-               ret = btrfs_error_commit_super(root);
-               if (ret)
-                       printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
-       }
+       if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
+               btrfs_error_commit_super(root);
 
        btrfs_put_block_group_cache(fs_info);
 
@@ -3434,18 +3417,11 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
        if (read_only)
                return 0;
 
-       if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
-               printk(KERN_WARNING "warning: mount fs with errors, "
-                      "running btrfsck is recommended\n");
-       }
-
        return 0;
 }
 
-int btrfs_error_commit_super(struct btrfs_root *root)
+void btrfs_error_commit_super(struct btrfs_root *root)
 {
-       int ret;
-
        mutex_lock(&root->fs_info->cleaner_mutex);
        btrfs_run_delayed_iputs(root);
        mutex_unlock(&root->fs_info->cleaner_mutex);
@@ -3455,10 +3431,6 @@ int btrfs_error_commit_super(struct btrfs_root *root)
 
        /* cleanup FS via transaction */
        btrfs_cleanup_transaction(root);
-
-       ret = write_ctree_super(NULL, root, 0);
-
-       return ret;
 }
 
 static void btrfs_destroy_ordered_operations(struct btrfs_root *root)
@@ -3782,14 +3754,17 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
                /* FIXME: cleanup wait for commit */
                t->in_commit = 1;
                t->blocked = 1;
+               smp_mb();
                if (waitqueue_active(&root->fs_info->transaction_blocked_wait))
                        wake_up(&root->fs_info->transaction_blocked_wait);
 
                t->blocked = 0;
+               smp_mb();
                if (waitqueue_active(&root->fs_info->transaction_wait))
                        wake_up(&root->fs_info->transaction_wait);
 
                t->commit_done = 1;
+               smp_mb();
                if (waitqueue_active(&t->commit_wait))
                        wake_up(&t->commit_wait);
 
index 95e147eea23952c689ee9e87cfd39e7d61fde96b..c5b00a735fefac258b7914223139d902efacbf99 100644 (file)
@@ -54,7 +54,7 @@ int write_ctree_super(struct btrfs_trans_handle *trans,
                      struct btrfs_root *root, int max_mirrors);
 struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
 int btrfs_commit_super(struct btrfs_root *root);
-int btrfs_error_commit_super(struct btrfs_root *root);
+void btrfs_error_commit_super(struct btrfs_root *root);
 struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
                                            u64 bytenr, u32 blocksize);
 struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
index 4e1b153b7c47c99e00adffd8ee6d24e2db29093d..ba58024d40d3eaf486c50d96cd116c3b828b9c75 100644 (file)
@@ -2251,6 +2251,16 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
                        }
                }
 
+               /*
+                * We need to try and merge add/drops of the same ref since we
+                * can run into issues with relocate dropping the implicit ref
+                * and then it being added back again before the drop can
+                * finish.  If we merged anything we need to re-loop so we can
+                * get a good ref.
+                */
+               btrfs_merge_delayed_refs(trans, fs_info, delayed_refs,
+                                        locked_ref);
+
                /*
                 * locked_ref is the head node, so we have to go one
                 * node back for any delayed ref updates
@@ -2318,12 +2328,23 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
                ref->in_tree = 0;
                rb_erase(&ref->rb_node, &delayed_refs->root);
                delayed_refs->num_entries--;
-               /*
-                * we modified num_entries, but as we're currently running
-                * delayed refs, skip
-                *     wake_up(&delayed_refs->seq_wait);
-                * here.
-                */
+               if (locked_ref) {
+                       /*
+                        * when we play the delayed ref, also correct the
+                        * ref_mod on head
+                        */
+                       switch (ref->action) {
+                       case BTRFS_ADD_DELAYED_REF:
+                       case BTRFS_ADD_DELAYED_EXTENT:
+                               locked_ref->node.ref_mod -= ref->ref_mod;
+                               break;
+                       case BTRFS_DROP_DELAYED_REF:
+                               locked_ref->node.ref_mod += ref->ref_mod;
+                               break;
+                       default:
+                               WARN_ON(1);
+                       }
+               }
                spin_unlock(&delayed_refs->lock);
 
                ret = run_one_delayed_ref(trans, root, ref, extent_op,
@@ -2350,22 +2371,6 @@ next:
        return count;
 }
 
-static void wait_for_more_refs(struct btrfs_fs_info *fs_info,
-                              struct btrfs_delayed_ref_root *delayed_refs,
-                              unsigned long num_refs,
-                              struct list_head *first_seq)
-{
-       spin_unlock(&delayed_refs->lock);
-       pr_debug("waiting for more refs (num %ld, first %p)\n",
-                num_refs, first_seq);
-       wait_event(fs_info->tree_mod_seq_wait,
-                  num_refs != delayed_refs->num_entries ||
-                  fs_info->tree_mod_seq_list.next != first_seq);
-       pr_debug("done waiting for more refs (num %ld, first %p)\n",
-                delayed_refs->num_entries, fs_info->tree_mod_seq_list.next);
-       spin_lock(&delayed_refs->lock);
-}
-
 #ifdef SCRAMBLE_DELAYED_REFS
 /*
  * Normally delayed refs get processed in ascending bytenr order. This
@@ -2460,13 +2465,11 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
        struct btrfs_delayed_ref_root *delayed_refs;
        struct btrfs_delayed_ref_node *ref;
        struct list_head cluster;
-       struct list_head *first_seq = NULL;
        int ret;
        u64 delayed_start;
        int run_all = count == (unsigned long)-1;
        int run_most = 0;
-       unsigned long num_refs = 0;
-       int consider_waiting;
+       int loops;
 
        /* We'll clean this up in btrfs_cleanup_transaction */
        if (trans->aborted)
@@ -2484,7 +2487,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
        delayed_refs = &trans->transaction->delayed_refs;
        INIT_LIST_HEAD(&cluster);
 again:
-       consider_waiting = 0;
+       loops = 0;
        spin_lock(&delayed_refs->lock);
 
 #ifdef SCRAMBLE_DELAYED_REFS
@@ -2512,31 +2515,6 @@ again:
                if (ret)
                        break;
 
-               if (delayed_start >= delayed_refs->run_delayed_start) {
-                       if (consider_waiting == 0) {
-                               /*
-                                * btrfs_find_ref_cluster looped. let's do one
-                                * more cycle. if we don't run any delayed ref
-                                * during that cycle (because we can't because
-                                * all of them are blocked) and if the number of
-                                * refs doesn't change, we avoid busy waiting.
-                                */
-                               consider_waiting = 1;
-                               num_refs = delayed_refs->num_entries;
-                               first_seq = root->fs_info->tree_mod_seq_list.next;
-                       } else {
-                               wait_for_more_refs(root->fs_info, delayed_refs,
-                                                  num_refs, first_seq);
-                               /*
-                                * after waiting, things have changed. we
-                                * dropped the lock and someone else might have
-                                * run some refs, built new clusters and so on.
-                                * therefore, we restart staleness detection.
-                                */
-                               consider_waiting = 0;
-                       }
-               }
-
                ret = run_clustered_refs(trans, root, &cluster);
                if (ret < 0) {
                        spin_unlock(&delayed_refs->lock);
@@ -2549,9 +2527,26 @@ again:
                if (count == 0)
                        break;
 
-               if (ret || delayed_refs->run_delayed_start == 0) {
+               if (delayed_start >= delayed_refs->run_delayed_start) {
+                       if (loops == 0) {
+                               /*
+                                * btrfs_find_ref_cluster looped. let's do one
+                                * more cycle. if we don't run any delayed ref
+                                * during that cycle (because we can't because
+                                * all of them are blocked), bail out.
+                                */
+                               loops = 1;
+                       } else {
+                               /*
+                                * no runnable refs left, stop trying
+                                */
+                               BUG_ON(run_all);
+                               break;
+                       }
+               }
+               if (ret) {
                        /* refs were run, let's reset staleness detection */
-                       consider_waiting = 0;
+                       loops = 0;
                }
        }
 
@@ -3007,17 +3002,16 @@ again:
        }
        spin_unlock(&block_group->lock);
 
-       num_pages = (int)div64_u64(block_group->key.offset, 1024 * 1024 * 1024);
+       /*
+        * Try to preallocate enough space based on how big the block group is.
+        * Keep in mind this has to include any pinned space which could end up
+        * taking up quite a bit since it's not folded into the other space
+        * cache.
+        */
+       num_pages = (int)div64_u64(block_group->key.offset, 256 * 1024 * 1024);
        if (!num_pages)
                num_pages = 1;
 
-       /*
-        * Just to make absolutely sure we have enough space, we're going to
-        * preallocate 12 pages worth of space for each block group.  In
-        * practice we ought to use at most 8, but we need extra space so we can
-        * add our header and have a terminator between the extents and the
-        * bitmaps.
-        */
        num_pages *= 16;
        num_pages *= PAGE_CACHE_SIZE;
 
@@ -4571,8 +4565,10 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        if (root->fs_info->quota_enabled) {
                ret = btrfs_qgroup_reserve(root, num_bytes +
                                           nr_extents * root->leafsize);
-               if (ret)
+               if (ret) {
+                       mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
                        return ret;
+               }
        }
 
        ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
@@ -5294,9 +5290,6 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
        rb_erase(&head->node.rb_node, &delayed_refs->root);
 
        delayed_refs->num_entries--;
-       smp_mb();
-       if (waitqueue_active(&root->fs_info->tree_mod_seq_wait))
-               wake_up(&root->fs_info->tree_mod_seq_wait);
 
        /*
         * we don't take a ref on the node because we're removing it from the
index 45c81bb4ac820323c7fd4282a0cf71f7cc2d190d..4c878476bb91ce0985dabc25464622442aaca54a 100644 (file)
@@ -2330,23 +2330,10 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {
                        ret = tree->ops->readpage_end_io_hook(page, start, end,
                                                              state, mirror);
-                       if (ret) {
-                               /* no IO indicated but software detected errors
-                                * in the block, either checksum errors or
-                                * issues with the contents */
-                               struct btrfs_root *root =
-                                       BTRFS_I(page->mapping->host)->root;
-                               struct btrfs_device *device;
-
+                       if (ret)
                                uptodate = 0;
-                               device = btrfs_find_device_for_logical(
-                                               root, start, mirror);
-                               if (device)
-                                       btrfs_dev_stat_inc_and_print(device,
-                                               BTRFS_DEV_STAT_CORRUPTION_ERRS);
-                       } else {
+                       else
                                clean_io_failure(start, page);
-                       }
                }
 
                if (!uptodate && tree->ops && tree->ops->readpage_io_failed_hook) {
index b45b9de0c21d0f773f19f45ee10ae9803fa36f3a..857d93cd01dc579eb46838624349442fef07cf00 100644 (file)
@@ -272,9 +272,9 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
 }
 
 int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
-                             struct bio *bio, u64 offset, u32 *dst)
+                             struct bio *bio, u64 offset)
 {
-       return __btrfs_lookup_bio_sums(root, inode, bio, offset, dst, 1);
+       return __btrfs_lookup_bio_sums(root, inode, bio, offset, NULL, 1);
 }
 
 int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
index 83baec24946d7449194e94893f92f918b14c79b5..ec154f95464696cfa7df3cd6ab87ac4a0185ed03 100644 (file)
@@ -324,7 +324,8 @@ static noinline int add_async_extent(struct async_cow *cow,
  * If this code finds it can't get good compression, it puts an
  * entry onto the work queue to write the uncompressed bytes.  This
  * makes sure that both compressed inodes and uncompressed inodes
- * are written in the same order that pdflush sent them down.
+ * are written in the same order that the flusher thread sent them
+ * down.
  */
 static noinline int compress_file_range(struct inode *inode,
                                        struct page *locked_page,
@@ -1007,9 +1008,7 @@ static noinline void async_cow_submit(struct btrfs_work *work)
        nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >>
                PAGE_CACHE_SHIFT;
 
-       atomic_sub(nr_pages, &root->fs_info->async_delalloc_pages);
-
-       if (atomic_read(&root->fs_info->async_delalloc_pages) <
+       if (atomic_sub_return(nr_pages, &root->fs_info->async_delalloc_pages) <
            5 * 1024 * 1024 &&
            waitqueue_active(&root->fs_info->async_submit_wait))
                wake_up(&root->fs_info->async_submit_wait);
@@ -1884,8 +1883,11 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                                trans = btrfs_join_transaction_nolock(root);
                        else
                                trans = btrfs_join_transaction(root);
-                       if (IS_ERR(trans))
-                               return PTR_ERR(trans);
+                       if (IS_ERR(trans)) {
+                               ret = PTR_ERR(trans);
+                               trans = NULL;
+                               goto out;
+                       }
                        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
                        ret = btrfs_update_inode_fallback(trans, root, inode);
                        if (ret) /* -ENOMEM or corruption */
@@ -3173,7 +3175,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
        btrfs_i_size_write(dir, dir->i_size - name_len * 2);
        inode_inc_iversion(dir);
        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-       ret = btrfs_update_inode(trans, root, dir);
+       ret = btrfs_update_inode_fallback(trans, root, dir);
        if (ret)
                btrfs_abort_transaction(trans, root, ret);
 out:
@@ -5773,18 +5775,112 @@ out:
        return ret;
 }
 
+static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
+                             struct extent_state **cached_state, int writing)
+{
+       struct btrfs_ordered_extent *ordered;
+       int ret = 0;
+
+       while (1) {
+               lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend,
+                                0, cached_state);
+               /*
+                * We're concerned with the entire range that we're going to be
+                * doing DIO to, so we need to make sure theres no ordered
+                * extents in this range.
+                */
+               ordered = btrfs_lookup_ordered_range(inode, lockstart,
+                                                    lockend - lockstart + 1);
+
+               /*
+                * We need to make sure there are no buffered pages in this
+                * range either, we could have raced between the invalidate in
+                * generic_file_direct_write and locking the extent.  The
+                * invalidate needs to happen so that reads after a write do not
+                * get stale data.
+                */
+               if (!ordered && (!writing ||
+                   !test_range_bit(&BTRFS_I(inode)->io_tree,
+                                   lockstart, lockend, EXTENT_UPTODATE, 0,
+                                   *cached_state)))
+                       break;
+
+               unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend,
+                                    cached_state, GFP_NOFS);
+
+               if (ordered) {
+                       btrfs_start_ordered_extent(inode, ordered, 1);
+                       btrfs_put_ordered_extent(ordered);
+               } else {
+                       /* Screw you mmap */
+                       ret = filemap_write_and_wait_range(inode->i_mapping,
+                                                          lockstart,
+                                                          lockend);
+                       if (ret)
+                               break;
+
+                       /*
+                        * If we found a page that couldn't be invalidated just
+                        * fall back to buffered.
+                        */
+                       ret = invalidate_inode_pages2_range(inode->i_mapping,
+                                       lockstart >> PAGE_CACHE_SHIFT,
+                                       lockend >> PAGE_CACHE_SHIFT);
+                       if (ret)
+                               break;
+               }
+
+               cond_resched();
+       }
+
+       return ret;
+}
+
 static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
                                   struct buffer_head *bh_result, int create)
 {
        struct extent_map *em;
        struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct extent_state *cached_state = NULL;
        u64 start = iblock << inode->i_blkbits;
+       u64 lockstart, lockend;
        u64 len = bh_result->b_size;
        struct btrfs_trans_handle *trans;
+       int unlock_bits = EXTENT_LOCKED;
+       int ret;
+
+       if (create) {
+               ret = btrfs_delalloc_reserve_space(inode, len);
+               if (ret)
+                       return ret;
+               unlock_bits |= EXTENT_DELALLOC | EXTENT_DIRTY;
+       } else {
+               len = min_t(u64, len, root->sectorsize);
+       }
+
+       lockstart = start;
+       lockend = start + len - 1;
+
+       /*
+        * If this errors out it's because we couldn't invalidate pagecache for
+        * this range and we need to fallback to buffered.
+        */
+       if (lock_extent_direct(inode, lockstart, lockend, &cached_state, create))
+               return -ENOTBLK;
+
+       if (create) {
+               ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
+                                    lockend, EXTENT_DELALLOC, NULL,
+                                    &cached_state, GFP_NOFS);
+               if (ret)
+                       goto unlock_err;
+       }
 
        em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
-       if (IS_ERR(em))
-               return PTR_ERR(em);
+       if (IS_ERR(em)) {
+               ret = PTR_ERR(em);
+               goto unlock_err;
+       }
 
        /*
         * Ok for INLINE and COMPRESSED extents we need to fallback on buffered
@@ -5803,17 +5899,16 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
        if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags) ||
            em->block_start == EXTENT_MAP_INLINE) {
                free_extent_map(em);
-               return -ENOTBLK;
+               ret = -ENOTBLK;
+               goto unlock_err;
        }
 
        /* Just a good old fashioned hole, return */
        if (!create && (em->block_start == EXTENT_MAP_HOLE ||
                        test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
                free_extent_map(em);
-               /* DIO will do one hole at a time, so just unlock a sector */
-               unlock_extent(&BTRFS_I(inode)->io_tree, start,
-                             start + root->sectorsize - 1);
-               return 0;
+               ret = 0;
+               goto unlock_err;
        }
 
        /*
@@ -5826,8 +5921,9 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
         *
         */
        if (!create) {
-               len = em->len - (start - em->start);
-               goto map;
+               len = min(len, em->len - (start - em->start));
+               lockstart = start + len;
+               goto unlock;
        }
 
        if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) ||
@@ -5859,7 +5955,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
                        btrfs_end_transaction(trans, root);
                        if (ret) {
                                free_extent_map(em);
-                               return ret;
+                               goto unlock_err;
                        }
                        goto unlock;
                }
@@ -5872,14 +5968,12 @@ must_cow:
         */
        len = bh_result->b_size;
        em = btrfs_new_extent_direct(inode, em, start, len);
-       if (IS_ERR(em))
-               return PTR_ERR(em);
+       if (IS_ERR(em)) {
+               ret = PTR_ERR(em);
+               goto unlock_err;
+       }
        len = min(len, em->len - (start - em->start));
 unlock:
-       clear_extent_bit(&BTRFS_I(inode)->io_tree, start, start + len - 1,
-                         EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DIRTY, 1,
-                         0, NULL, GFP_NOFS);
-map:
        bh_result->b_blocknr = (em->block_start + (start - em->start)) >>
                inode->i_blkbits;
        bh_result->b_size = len;
@@ -5897,9 +5991,44 @@ map:
                        i_size_write(inode, start + len);
        }
 
+       /*
+        * In the case of write we need to clear and unlock the entire range,
+        * in the case of read we need to unlock only the end area that we
+        * aren't using if there is any left over space.
+        */
+       if (lockstart < lockend) {
+               if (create && len < lockend - lockstart) {
+                       clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
+                                        lockstart + len - 1, unlock_bits, 1, 0,
+                                        &cached_state, GFP_NOFS);
+                       /*
+                        * Beside unlock, we also need to cleanup reserved space
+                        * for the left range by attaching EXTENT_DO_ACCOUNTING.
+                        */
+                       clear_extent_bit(&BTRFS_I(inode)->io_tree,
+                                        lockstart + len, lockend,
+                                        unlock_bits | EXTENT_DO_ACCOUNTING,
+                                        1, 0, NULL, GFP_NOFS);
+               } else {
+                       clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
+                                        lockend, unlock_bits, 1, 0,
+                                        &cached_state, GFP_NOFS);
+               }
+       } else {
+               free_extent_state(cached_state);
+       }
+
        free_extent_map(em);
 
        return 0;
+
+unlock_err:
+       if (create)
+               unlock_bits |= EXTENT_DO_ACCOUNTING;
+
+       clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend,
+                        unlock_bits, 1, 0, &cached_state, GFP_NOFS);
+       return ret;
 }
 
 struct btrfs_dio_private {
@@ -5907,7 +6036,6 @@ struct btrfs_dio_private {
        u64 logical_offset;
        u64 disk_bytenr;
        u64 bytes;
-       u32 *csums;
        void *private;
 
        /* number of bios pending for this dio */
@@ -5927,7 +6055,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
        struct inode *inode = dip->inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        u64 start;
-       u32 *private = dip->csums;
 
        start = dip->logical_offset;
        do {
@@ -5935,8 +6062,12 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
                        struct page *page = bvec->bv_page;
                        char *kaddr;
                        u32 csum = ~(u32)0;
+                       u64 private = ~(u32)0;
                        unsigned long flags;
 
+                       if (get_state_private(&BTRFS_I(inode)->io_tree,
+                                             start, &private))
+                               goto failed;
                        local_irq_save(flags);
                        kaddr = kmap_atomic(page);
                        csum = btrfs_csum_data(root, kaddr + bvec->bv_offset,
@@ -5946,18 +6077,18 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
                        local_irq_restore(flags);
 
                        flush_dcache_page(bvec->bv_page);
-                       if (csum != *private) {
+                       if (csum != private) {
+failed:
                                printk(KERN_ERR "btrfs csum failed ino %llu off"
                                      " %llu csum %u private %u\n",
                                      (unsigned long long)btrfs_ino(inode),
                                      (unsigned long long)start,
-                                     csum, *private);
+                                     csum, (unsigned)private);
                                err = -EIO;
                        }
                }
 
                start += bvec->bv_len;
-               private++;
                bvec++;
        } while (bvec <= bvec_end);
 
@@ -5965,7 +6096,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
                      dip->logical_offset + dip->bytes - 1);
        bio->bi_private = dip->private;
 
-       kfree(dip->csums);
        kfree(dip);
 
        /* If we had a csum failure make sure to clear the uptodate flag */
@@ -6071,7 +6201,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,
 
 static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
                                         int rw, u64 file_offset, int skip_sum,
-                                        u32 *csums, int async_submit)
+                                        int async_submit)
 {
        int write = rw & REQ_WRITE;
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -6104,8 +6234,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
                if (ret)
                        goto err;
        } else if (!skip_sum) {
-               ret = btrfs_lookup_bio_sums_dio(root, inode, bio,
-                                         file_offset, csums);
+               ret = btrfs_lookup_bio_sums_dio(root, inode, bio, file_offset);
                if (ret)
                        goto err;
        }
@@ -6131,10 +6260,8 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
        u64 submit_len = 0;
        u64 map_length;
        int nr_pages = 0;
-       u32 *csums = dip->csums;
        int ret = 0;
        int async_submit = 0;
-       int write = rw & REQ_WRITE;
 
        map_length = orig_bio->bi_size;
        ret = btrfs_map_block(map_tree, READ, start_sector << 9,
@@ -6170,16 +6297,13 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
                        atomic_inc(&dip->pending_bios);
                        ret = __btrfs_submit_dio_bio(bio, inode, rw,
                                                     file_offset, skip_sum,
-                                                    csums, async_submit);
+                                                    async_submit);
                        if (ret) {
                                bio_put(bio);
                                atomic_dec(&dip->pending_bios);
                                goto out_err;
                        }
 
-                       /* Write's use the ordered csums */
-                       if (!write && !skip_sum)
-                               csums = csums + nr_pages;
                        start_sector += submit_len >> 9;
                        file_offset += submit_len;
 
@@ -6209,7 +6333,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
 
 submit:
        ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum,
-                                    csums, async_submit);
+                                    async_submit);
        if (!ret)
                return 0;
 
@@ -6245,17 +6369,6 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
                ret = -ENOMEM;
                goto free_ordered;
        }
-       dip->csums = NULL;
-
-       /* Write's use the ordered csum stuff, so we don't need dip->csums */
-       if (!write && !skip_sum) {
-               dip->csums = kmalloc(sizeof(u32) * bio->bi_vcnt, GFP_NOFS);
-               if (!dip->csums) {
-                       kfree(dip);
-                       ret = -ENOMEM;
-                       goto free_ordered;
-               }
-       }
 
        dip->private = bio->bi_private;
        dip->inode = inode;
@@ -6340,132 +6453,22 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io
 out:
        return retval;
 }
+
 static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
                        const struct iovec *iov, loff_t offset,
                        unsigned long nr_segs)
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_mapping->host;
-       struct btrfs_ordered_extent *ordered;
-       struct extent_state *cached_state = NULL;
-       u64 lockstart, lockend;
-       ssize_t ret;
-       int writing = rw & WRITE;
-       int write_bits = 0;
-       size_t count = iov_length(iov, nr_segs);
 
        if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov,
-                           offset, nr_segs)) {
+                           offset, nr_segs))
                return 0;
-       }
-
-       lockstart = offset;
-       lockend = offset + count - 1;
-
-       if (writing) {
-               ret = btrfs_delalloc_reserve_space(inode, count);
-               if (ret)
-                       goto out;
-       }
-
-       while (1) {
-               lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend,
-                                0, &cached_state);
-               /*
-                * We're concerned with the entire range that we're going to be
-                * doing DIO to, so we need to make sure theres no ordered
-                * extents in this range.
-                */
-               ordered = btrfs_lookup_ordered_range(inode, lockstart,
-                                                    lockend - lockstart + 1);
-
-               /*
-                * We need to make sure there are no buffered pages in this
-                * range either, we could have raced between the invalidate in
-                * generic_file_direct_write and locking the extent.  The
-                * invalidate needs to happen so that reads after a write do not
-                * get stale data.
-                */
-               if (!ordered && (!writing ||
-                   !test_range_bit(&BTRFS_I(inode)->io_tree,
-                                   lockstart, lockend, EXTENT_UPTODATE, 0,
-                                   cached_state)))
-                       break;
-
-               unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend,
-                                    &cached_state, GFP_NOFS);
-
-               if (ordered) {
-                       btrfs_start_ordered_extent(inode, ordered, 1);
-                       btrfs_put_ordered_extent(ordered);
-               } else {
-                       /* Screw you mmap */
-                       ret = filemap_write_and_wait_range(file->f_mapping,
-                                                          lockstart,
-                                                          lockend);
-                       if (ret)
-                               goto out;
-
-                       /*
-                        * If we found a page that couldn't be invalidated just
-                        * fall back to buffered.
-                        */
-                       ret = invalidate_inode_pages2_range(file->f_mapping,
-                                       lockstart >> PAGE_CACHE_SHIFT,
-                                       lockend >> PAGE_CACHE_SHIFT);
-                       if (ret) {
-                               if (ret == -EBUSY)
-                                       ret = 0;
-                               goto out;
-                       }
-               }
-
-               cond_resched();
-       }
 
-       /*
-        * we don't use btrfs_set_extent_delalloc because we don't want
-        * the dirty or uptodate bits
-        */
-       if (writing) {
-               write_bits = EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING;
-               ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend,
-                                    EXTENT_DELALLOC, NULL, &cached_state,
-                                    GFP_NOFS);
-               if (ret) {
-                       clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
-                                        lockend, EXTENT_LOCKED | write_bits,
-                                        1, 0, &cached_state, GFP_NOFS);
-                       goto out;
-               }
-       }
-
-       free_extent_state(cached_state);
-       cached_state = NULL;
-
-       ret = __blockdev_direct_IO(rw, iocb, inode,
+       return __blockdev_direct_IO(rw, iocb, inode,
                   BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev,
                   iov, offset, nr_segs, btrfs_get_blocks_direct, NULL,
                   btrfs_submit_direct, 0);
-
-       if (ret < 0 && ret != -EIOCBQUEUED) {
-               clear_extent_bit(&BTRFS_I(inode)->io_tree, offset,
-                             offset + iov_length(iov, nr_segs) - 1,
-                             EXTENT_LOCKED | write_bits, 1, 0,
-                             &cached_state, GFP_NOFS);
-       } else if (ret >= 0 && ret < iov_length(iov, nr_segs)) {
-               /*
-                * We're falling back to buffered, unlock the section we didn't
-                * do IO on.
-                */
-               clear_extent_bit(&BTRFS_I(inode)->io_tree, offset + ret,
-                             offset + iov_length(iov, nr_segs) - 1,
-                             EXTENT_LOCKED | write_bits, 1, 0,
-                             &cached_state, GFP_NOFS);
-       }
-out:
-       free_extent_state(cached_state);
-       return ret;
 }
 
 static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
index bc2f6ffff3cfb004099a5d4eb84f8a9aa688d7cd..9df50fa8a0781ba387553297fbe442ed964e671e 100644 (file)
@@ -424,7 +424,7 @@ static noinline int create_subvol(struct btrfs_root *root,
        uuid_le_gen(&new_uuid);
        memcpy(root_item.uuid, new_uuid.b, BTRFS_UUID_SIZE);
        root_item.otime.sec = cpu_to_le64(cur_time.tv_sec);
-       root_item.otime.nsec = cpu_to_le64(cur_time.tv_nsec);
+       root_item.otime.nsec = cpu_to_le32(cur_time.tv_nsec);
        root_item.ctime = root_item.otime;
        btrfs_set_root_ctransid(&root_item, trans->transid);
        btrfs_set_root_otransid(&root_item, trans->transid);
@@ -664,10 +664,6 @@ static noinline int btrfs_mksubvol(struct path *parent,
        struct dentry *dentry;
        int error;
 
-       error = mnt_want_write(parent->mnt);
-       if (error)
-               return error;
-
        mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
 
        dentry = lookup_one_len(name, parent->dentry, namelen);
@@ -703,7 +699,6 @@ out_dput:
        dput(dentry);
 out_unlock:
        mutex_unlock(&dir->i_mutex);
-       mnt_drop_write(parent->mnt);
        return error;
 }
 
index a44eff0748051b1627448e54f281ca04cd77c719..2a1762c660416c662d32f95060046ba2557ab903 100644 (file)
@@ -67,7 +67,7 @@ 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) {
+               if (eb->lock_nested && current->pid == eb->lock_owner) {
                        read_unlock(&eb->lock);
                        return;
                }
index 643335a4fe3c6699a894c19d01e79bed9ef631c7..051c7fe551dd38bb7e391e5abaeff992f32b90f7 100644 (file)
@@ -596,7 +596,7 @@ void btrfs_start_ordered_extent(struct inode *inode,
        /*
         * pages in the range can be dirty, clean or writeback.  We
         * start IO on any dirty ones so the wait doesn't stall waiting
-        * for pdflush to find them
+        * for the flusher thread to find them
         */
        if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags))
                filemap_fdatawrite_range(inode->i_mapping, start, end);
index bc424ae5a81a49ef15cadb0159812f80acf0221f..38b42e7bc91d0e258a7fd086d793aae3d43ac4c1 100644 (file)
@@ -1364,13 +1364,17 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
        spin_lock(&fs_info->qgroup_lock);
 
        dstgroup = add_qgroup_rb(fs_info, objectid);
-       if (!dstgroup)
+       if (IS_ERR(dstgroup)) {
+               ret = PTR_ERR(dstgroup);
                goto unlock;
+       }
 
        if (srcid) {
                srcgroup = find_qgroup_rb(fs_info, srcid);
-               if (!srcgroup)
+               if (!srcgroup) {
+                       ret = -EINVAL;
                        goto unlock;
+               }
                dstgroup->rfer = srcgroup->rfer - level_size;
                dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size;
                srcgroup->excl = level_size;
@@ -1379,8 +1383,10 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
                qgroup_dirty(fs_info, srcgroup);
        }
 
-       if (!inherit)
+       if (!inherit) {
+               ret = -EINVAL;
                goto unlock;
+       }
 
        i_qgroups = (u64 *)(inherit + 1);
        for (i = 0; i < inherit->num_qgroups; ++i) {
index 6bb465cca20f5c68804ac3c4f78d4aa650fee96c..10d8e4d88071747651afd3a875eae0fb407c22e4 100644 (file)
@@ -544,8 +544,8 @@ void btrfs_update_root_times(struct btrfs_trans_handle *trans,
        struct timespec ct = CURRENT_TIME;
 
        spin_lock(&root->root_times_lock);
-       item->ctransid = trans->transid;
+       item->ctransid = cpu_to_le64(trans->transid);
        item->ctime.sec = cpu_to_le64(ct.tv_sec);
-       item->ctime.nsec = cpu_to_le64(ct.tv_nsec);
+       item->ctime.nsec = cpu_to_le32(ct.tv_nsec);
        spin_unlock(&root->root_times_lock);
 }
index 8c6e61d6eed5b754945930fbaaaaf21d6f98d028..83d6f9f9c2209861efdec86dec9ad54d629deeb9 100644 (file)
@@ -100,10 +100,6 @@ static void __save_error_info(struct btrfs_fs_info *fs_info)
        fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR;
 }
 
-/* NOTE:
- *     We move write_super stuff at umount in order to avoid deadlock
- *     for umount hold all lock.
- */
 static void save_error_info(struct btrfs_fs_info *fs_info)
 {
        __save_error_info(fs_info);
@@ -842,7 +838,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
        struct btrfs_trans_handle *trans;
        struct btrfs_fs_info *fs_info = btrfs_sb(sb);
        struct btrfs_root *root = fs_info->tree_root;
-       int ret;
 
        trace_btrfs_sync_fs(wait);
 
@@ -853,11 +848,17 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
 
        btrfs_wait_ordered_extents(root, 0, 0);
 
-       trans = btrfs_start_transaction(root, 0);
+       spin_lock(&fs_info->trans_lock);
+       if (!fs_info->running_transaction) {
+               spin_unlock(&fs_info->trans_lock);
+               return 0;
+       }
+       spin_unlock(&fs_info->trans_lock);
+
+       trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
                return PTR_ERR(trans);
-       ret = btrfs_commit_transaction(trans, root);
-       return ret;
+       return btrfs_commit_transaction(trans, root);
 }
 
 static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
@@ -1534,6 +1535,8 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root)
        while (cur_devices) {
                head = &cur_devices->devices;
                list_for_each_entry(dev, head, dev_list) {
+                       if (dev->missing)
+                               continue;
                        if (!first_dev || dev->devid < first_dev->devid)
                                first_dev = dev;
                }
index 17be3dedacbab1c47084270153ed059719984470..27c26004e050a33211674363cfd80c02c98d1063 100644 (file)
@@ -1031,6 +1031,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 
        btrfs_i_size_write(parent_inode, parent_inode->i_size +
                                         dentry->d_name.len * 2);
+       parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
        ret = btrfs_update_inode(trans, parent_root, parent_inode);
        if (ret)
                goto abort_trans_dput;
@@ -1066,7 +1067,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        memcpy(new_root_item->parent_uuid, root->root_item.uuid,
                        BTRFS_UUID_SIZE);
        new_root_item->otime.sec = cpu_to_le64(cur_time.tv_sec);
-       new_root_item->otime.nsec = cpu_to_le64(cur_time.tv_nsec);
+       new_root_item->otime.nsec = cpu_to_le32(cur_time.tv_nsec);
        btrfs_set_root_otransid(new_root_item, trans->transid);
        memset(&new_root_item->stime, 0, sizeof(new_root_item->stime));
        memset(&new_root_item->rtime, 0, sizeof(new_root_item->rtime));
index b8708f994e679a559af68b90b3135b2b8fa2a9ac..88b969aeeb71a53128ae941e569ad19f7b1038c3 100644 (file)
@@ -227,9 +227,8 @@ loop_lock:
                cur = pending;
                pending = pending->bi_next;
                cur->bi_next = NULL;
-               atomic_dec(&fs_info->nr_async_bios);
 
-               if (atomic_read(&fs_info->nr_async_bios) < limit &&
+               if (atomic_dec_return(&fs_info->nr_async_bios) < limit &&
                    waitqueue_active(&fs_info->async_submit_wait))
                        wake_up(&fs_info->async_submit_wait);
 
@@ -569,9 +568,11 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
                memcpy(new_device, device, sizeof(*new_device));
 
                /* Safe because we are under uuid_mutex */
-               name = rcu_string_strdup(device->name->str, GFP_NOFS);
-               BUG_ON(device->name && !name); /* -ENOMEM */
-               rcu_assign_pointer(new_device->name, name);
+               if (device->name) {
+                       name = rcu_string_strdup(device->name->str, GFP_NOFS);
+                       BUG_ON(device->name && !name); /* -ENOMEM */
+                       rcu_assign_pointer(new_device->name, name);
+               }
                new_device->bdev = NULL;
                new_device->writeable = 0;
                new_device->in_fs_metadata = 0;
@@ -1744,10 +1745,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
 
        device->fs_devices = root->fs_info->fs_devices;
 
-       /*
-        * we don't want write_supers to jump in here with our device
-        * half setup
-        */
        mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
        list_add_rcu(&device->dev_list, &root->fs_info->fs_devices->devices);
        list_add(&device->dev_alloc_list,
@@ -4609,28 +4606,6 @@ int btrfs_read_sys_array(struct btrfs_root *root)
        return ret;
 }
 
-struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root,
-                                                  u64 logical, int mirror_num)
-{
-       struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree;
-       int ret;
-       u64 map_length = 0;
-       struct btrfs_bio *bbio = NULL;
-       struct btrfs_device *device;
-
-       BUG_ON(mirror_num == 0);
-       ret = btrfs_map_block(map_tree, WRITE, logical, &map_length, &bbio,
-                             mirror_num);
-       if (ret) {
-               BUG_ON(bbio != NULL);
-               return NULL;
-       }
-       BUG_ON(mirror_num != bbio->mirror_num);
-       device = bbio->stripes[mirror_num - 1].dev;
-       kfree(bbio);
-       return device;
-}
-
 int btrfs_read_chunk_tree(struct btrfs_root *root)
 {
        struct btrfs_path *path;
index 5479325987b3c8af40e0760790d5365fda0efc8d..53c06af92e8da94270dab4f24906b937441d8a8f 100644 (file)
@@ -289,8 +289,6 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
 int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
 int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
                         u64 *start, u64 *max_avail);
-struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root,
-                                                  u64 logical, int mirror_num);
 void btrfs_dev_stat_print_on_error(struct btrfs_device *device);
 void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
 int btrfs_get_dev_stats(struct btrfs_root *root,
index 9f6d2e41281d69752f77d9c68772a46c855a8453..58e2e7b7737264fac2da09e2a71d451497e25e83 100644 (file)
@@ -914,7 +914,7 @@ link_dev_buffers(struct page *page, struct buffer_head *head)
 /*
  * Initialise the state of a blockdev page's buffers.
  */ 
-static void
+static sector_t
 init_page_buffers(struct page *page, struct block_device *bdev,
                        sector_t block, int size)
 {
@@ -936,33 +936,41 @@ init_page_buffers(struct page *page, struct block_device *bdev,
                block++;
                bh = bh->b_this_page;
        } while (bh != head);
+
+       /*
+        * Caller needs to validate requested block against end of device.
+        */
+       return end_block;
 }
 
 /*
  * Create the page-cache page that contains the requested block.
  *
- * This is user purely for blockdev mappings.
+ * This is used purely for blockdev mappings.
  */
-static struct page *
+static int
 grow_dev_page(struct block_device *bdev, sector_t block,
-               pgoff_t index, int size)
+               pgoff_t index, int size, int sizebits)
 {
        struct inode *inode = bdev->bd_inode;
        struct page *page;
        struct buffer_head *bh;
+       sector_t end_block;
+       int ret = 0;            /* Will call free_more_memory() */
 
        page = find_or_create_page(inode->i_mapping, index,
                (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE);
        if (!page)
-               return NULL;
+               return ret;
 
        BUG_ON(!PageLocked(page));
 
        if (page_has_buffers(page)) {
                bh = page_buffers(page);
                if (bh->b_size == size) {
-                       init_page_buffers(page, bdev, block, size);
-                       return page;
+                       end_block = init_page_buffers(page, bdev,
+                                               index << sizebits, size);
+                       goto done;
                }
                if (!try_to_free_buffers(page))
                        goto failed;
@@ -982,14 +990,14 @@ grow_dev_page(struct block_device *bdev, sector_t block,
         */
        spin_lock(&inode->i_mapping->private_lock);
        link_dev_buffers(page, bh);
-       init_page_buffers(page, bdev, block, size);
+       end_block = init_page_buffers(page, bdev, index << sizebits, size);
        spin_unlock(&inode->i_mapping->private_lock);
-       return page;
-
+done:
+       ret = (block < end_block) ? 1 : -ENXIO;
 failed:
        unlock_page(page);
        page_cache_release(page);
-       return NULL;
+       return ret;
 }
 
 /*
@@ -999,7 +1007,6 @@ failed:
 static int
 grow_buffers(struct block_device *bdev, sector_t block, int size)
 {
-       struct page *page;
        pgoff_t index;
        int sizebits;
 
@@ -1023,22 +1030,14 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
                        bdevname(bdev, b));
                return -EIO;
        }
-       block = index << sizebits;
+
        /* Create a page with the proper size buffers.. */
-       page = grow_dev_page(bdev, block, index, size);
-       if (!page)
-               return 0;
-       unlock_page(page);
-       page_cache_release(page);
-       return 1;
+       return grow_dev_page(bdev, block, index, size, sizebits);
 }
 
 static struct buffer_head *
 __getblk_slow(struct block_device *bdev, sector_t block, int size)
 {
-       int ret;
-       struct buffer_head *bh;
-
        /* Size must be multiple of hard sectorsize */
        if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
                        (size < 512 || size > PAGE_SIZE))) {
@@ -1051,21 +1050,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
                return NULL;
        }
 
-retry:
-       bh = __find_get_block(bdev, block, size);
-       if (bh)
-               return bh;
+       for (;;) {
+               struct buffer_head *bh;
+               int ret;
 
-       ret = grow_buffers(bdev, block, size);
-       if (ret == 0) {
-               free_more_memory();
-               goto retry;
-       } else if (ret > 0) {
                bh = __find_get_block(bdev, block, size);
                if (bh)
                        return bh;
+
+               ret = grow_buffers(bdev, block, size);
+               if (ret < 0)
+                       return NULL;
+               if (ret == 0)
+                       free_more_memory();
        }
-       return NULL;
 }
 
 /*
@@ -1321,10 +1319,6 @@ EXPORT_SYMBOL(__find_get_block);
  * which corresponds to the passed block_device, block and size. The
  * returned buffer has its reference count incremented.
  *
- * __getblk() cannot fail - it just keeps trying.  If you pass it an
- * illegal block number, __getblk() will happily return a buffer_head
- * which represents the non-existent block.  Very weird.
- *
  * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers()
  * attempt is failing.  FIXME, perhaps?
  */
index fb962efdacee8cdbbdff2c3324516d0356d2e2e5..6d59006bfa27e688d37499b88f45e28a22df24db 100644 (file)
@@ -201,6 +201,7 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
        int err = -ENOMEM;
 
        dout("ceph_fs_debugfs_init\n");
+       BUG_ON(!fsc->client->debugfs_dir);
        fsc->debugfs_congestion_kb =
                debugfs_create_file("writeback_congestion_kb",
                                    0600,
index 9fff9f3b17e4a5206a9073cec2be714fba44bda0..4b5762ef7c2bf87ecb937a70a55ae20b100d77c9 100644 (file)
@@ -992,11 +992,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
        if (rinfo->head->is_dentry) {
                struct inode *dir = req->r_locked_dir;
 
-               err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
-                                session, req->r_request_started, -1,
-                                &req->r_caps_reservation);
-               if (err < 0)
-                       return err;
+               if (dir) {
+                       err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
+                                        session, req->r_request_started, -1,
+                                        &req->r_caps_reservation);
+                       if (err < 0)
+                               return err;
+               } else {
+                       WARN_ON_ONCE(1);
+               }
        }
 
        /*
@@ -1004,6 +1008,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
         * will have trouble splicing in the virtual snapdir later
         */
        if (rinfo->head->is_dentry && !req->r_aborted &&
+           req->r_locked_dir &&
            (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
                                               fsc->mount_options->snapdir_name,
                                               req->r_dentry->d_name.len))) {
index 8e3fb69fbe62e60cd3698c07d9fa8e53d6d2b184..1396ceb46797400c124ac80880f31a90583d0e4b 100644 (file)
@@ -42,7 +42,8 @@ static long __validate_layout(struct ceph_mds_client *mdsc,
        /* validate striping parameters */
        if ((l->object_size & ~PAGE_MASK) ||
            (l->stripe_unit & ~PAGE_MASK) ||
-           ((unsigned)l->object_size % (unsigned)l->stripe_unit))
+           (l->stripe_unit != 0 &&
+            ((unsigned)l->object_size % (unsigned)l->stripe_unit)))
                return -EINVAL;
 
        /* make sure it's a valid data pool */
index 6161255fac45648efdfe437d9d880d390268d14f..1bdb350ea5d345fc2842c75ad7cc2e5065c81c16 100644 (file)
@@ -1155,11 +1155,14 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
        struct file *file;
        int fput_needed;
        ssize_t ret;
+       loff_t pos;
 
        file = fget_light(fd, &fput_needed);
        if (!file)
                return -EBADF;
-       ret = compat_readv(file, vec, vlen, &file->f_pos);
+       pos = file->f_pos;
+       ret = compat_readv(file, vec, vlen, &pos);
+       file->f_pos = pos;
        fput_light(file, fput_needed);
        return ret;
 }
@@ -1221,11 +1224,14 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
        struct file *file;
        int fput_needed;
        ssize_t ret;
+       loff_t pos;
 
        file = fget_light(fd, &fput_needed);
        if (!file)
                return -EBADF;
-       ret = compat_writev(file, vec, vlen, &file->f_pos);
+       pos = file->f_pos;
+       ret = compat_writev(file, vec, vlen, &pos);
+       file->f_pos = pos;
        fput_light(file, fput_needed);
        return ret;
 }
index 1faf4cb56f3963d0945d8004b8640464b9e3b6fd..f86c720dba0eeea72d7ecefdefa8ad0b52886011 100644 (file)
@@ -1062,6 +1062,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        unsigned long user_addr;
        size_t bytes;
        struct buffer_head map_bh = { 0, };
+       struct blk_plug plug;
 
        if (rw & WRITE)
                rw = WRITE_ODIRECT;
@@ -1177,6 +1178,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
                                PAGE_SIZE - user_addr / PAGE_SIZE);
        }
 
+       blk_start_plug(&plug);
+
        for (seg = 0; seg < nr_segs; seg++) {
                user_addr = (unsigned long)iov[seg].iov_base;
                sdio.size += bytes = iov[seg].iov_len;
@@ -1235,6 +1238,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        if (sdio.bio)
                dio_bio_submit(dio, &sdio);
 
+       blk_finish_plug(&plug);
+
        /*
         * It is possible that, we return short IO due to end of file.
         * In that case, we need to release all the pages we got hold on.
index 1c8b55670804c20e88a10a48668f574d54f58205..eedec84c1809173eb4c627815ad70122de66eeb3 100644 (file)
@@ -1654,8 +1654,8 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
                error = PTR_ERR(file);
                goto out_free_fd;
        }
-       fd_install(fd, file);
        ep->file = file;
+       fd_install(fd, file);
        return fd;
 
 out_free_fd:
index 5badb0c039de404b24208c8e6c2041b3331ae5bb..1562c27a2fab27f700825e0090e4d98492fa2fbd 100644 (file)
 
 #define EXOFS_DBGMSG2(M...) do {} while (0)
 
-enum {MAX_PAGES_KMALLOC = PAGE_SIZE / sizeof(struct page *), };
-
 unsigned exofs_max_io_pages(struct ore_layout *layout,
                            unsigned expected_pages)
 {
-       unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC);
+       unsigned pages = min_t(unsigned, expected_pages,
+                              layout->max_io_length / PAGE_SIZE);
 
-       /* TODO: easily support bio chaining */
-       pages =  min_t(unsigned, pages, layout->max_io_length / PAGE_SIZE);
        return pages;
 }
 
@@ -101,7 +98,8 @@ static void _pcol_reset(struct page_collect *pcol)
         * it might not end here. don't be left with nothing
         */
        if (!pcol->expected_pages)
-               pcol->expected_pages = MAX_PAGES_KMALLOC;
+               pcol->expected_pages =
+                               exofs_max_io_pages(&pcol->sbi->layout, ~0);
 }
 
 static int pcol_try_alloc(struct page_collect *pcol)
@@ -389,6 +387,8 @@ static int readpage_strip(void *data, struct page *page)
        size_t len;
        int ret;
 
+       BUG_ON(!PageLocked(page));
+
        /* FIXME: Just for debugging, will be removed */
        if (PageUptodate(page))
                EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino,
@@ -572,8 +572,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
 
        if (!pcol->that_locked_page ||
            (pcol->that_locked_page->index != index)) {
-               struct page *page = find_get_page(pcol->inode->i_mapping, index);
+               struct page *page;
+               loff_t i_size = i_size_read(pcol->inode);
+
+               if (offset >= i_size) {
+                       *uptodate = true;
+                       EXOFS_DBGMSG("offset >= i_size index=0x%lx\n", index);
+                       return ZERO_PAGE(0);
+               }
 
+               page =  find_get_page(pcol->inode->i_mapping, index);
                if (!page) {
                        page = find_or_create_page(pcol->inode->i_mapping,
                                                   index, GFP_NOFS);
@@ -602,12 +610,13 @@ static void __r4w_put_page(void *priv, struct page *page)
 {
        struct page_collect *pcol = priv;
 
-       if (pcol->that_locked_page != page) {
+       if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) {
                EXOFS_DBGMSG("index=0x%lx\n", page->index);
                page_cache_release(page);
                return;
        }
-       EXOFS_DBGMSG("that_locked_page index=0x%lx\n", page->index);
+       EXOFS_DBGMSG("that_locked_page index=0x%lx\n",
+                    ZERO_PAGE(0) == page ? -1 : page->index);
 }
 
 static const struct _ore_r4w_op _r4w_op = {
index 24a49d47e9354c00f0ebd2da6c92d3520e71332c..1585db1aa3651a3eb2fbe586156fd5bd270f5b82 100644 (file)
@@ -837,11 +837,11 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
                                bio->bi_rw |= REQ_WRITE;
                        }
 
-                       osd_req_write(or, _ios_obj(ios, dev), per_dev->offset,
-                                     bio, per_dev->length);
+                       osd_req_write(or, _ios_obj(ios, cur_comp),
+                                     per_dev->offset, bio, per_dev->length);
                        ORE_DBGMSG("write(0x%llx) offset=0x%llx "
                                      "length=0x%llx dev=%d\n",
-                                    _LLU(_ios_obj(ios, dev)->id),
+                                    _LLU(_ios_obj(ios, cur_comp)->id),
                                     _LLU(per_dev->offset),
                                     _LLU(per_dev->length), dev);
                } else if (ios->kern_buff) {
@@ -853,20 +853,20 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
                               (ios->si.unit_off + ios->length >
                                ios->layout->stripe_unit));
 
-                       ret = osd_req_write_kern(or, _ios_obj(ios, per_dev->dev),
+                       ret = osd_req_write_kern(or, _ios_obj(ios, cur_comp),
                                                 per_dev->offset,
                                                 ios->kern_buff, ios->length);
                        if (unlikely(ret))
                                goto out;
                        ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx "
                                      "length=0x%llx dev=%d\n",
-                                    _LLU(_ios_obj(ios, dev)->id),
+                                    _LLU(_ios_obj(ios, cur_comp)->id),
                                     _LLU(per_dev->offset),
                                     _LLU(ios->length), per_dev->dev);
                } else {
-                       osd_req_set_attributes(or, _ios_obj(ios, dev));
+                       osd_req_set_attributes(or, _ios_obj(ios, cur_comp));
                        ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n",
-                                    _LLU(_ios_obj(ios, dev)->id),
+                                    _LLU(_ios_obj(ios, cur_comp)->id),
                                     ios->out_attr_len, dev);
                }
 
index 433783624d107d1d29fd16ffb1c4890ecd78c7cd..dde41a75c7c8dbd36597272a13f5c6f3487507d3 100644 (file)
@@ -400,8 +400,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
        ret = ore_write(ios);
        if (unlikely(ret))
                EXOFS_ERR("%s: ore_write failed.\n", __func__);
-       else
-               sb->s_dirt = 0;
 
 
        unlock_super(sb);
@@ -412,14 +410,6 @@ out:
        return ret;
 }
 
-static void exofs_write_super(struct super_block *sb)
-{
-       if (!(sb->s_flags & MS_RDONLY))
-               exofs_sync_fs(sb, 1);
-       else
-               sb->s_dirt = 0;
-}
-
 static void _exofs_print_device(const char *msg, const char *dev_path,
                                struct osd_dev *od, u64 pid)
 {
@@ -952,7 +942,6 @@ static const struct super_operations exofs_sops = {
        .write_inode    = exofs_write_inode,
        .evict_inode    = exofs_evict_inode,
        .put_super      = exofs_put_super,
-       .write_super    = exofs_write_super,
        .sync_fs        = exofs_sync_fs,
        .statfs         = exofs_statfs,
 };
index 9a4a5c48b1c99f6a60ff02d35cda4ef1ced9bd50..a07597307fd1cd221b20997d9e0268caa6bc9138 100644 (file)
@@ -3459,14 +3459,6 @@ ext3_reserve_inode_write(handle_t *handle, struct inode *inode,
  * inode out, but prune_icache isn't a user-visible syncing function.
  * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync)
  * we start and wait on commits.
- *
- * Is this efficient/effective?  Well, we're being nice to the system
- * by cleaning up our inodes proactively so they can be reaped
- * without I/O.  But we are potentially leaving up to five seconds'
- * worth of inodes floating about which prune_icache wants us to
- * write out.  One way to fix that would be to get prune_icache()
- * to do a write_super() to free up some memory.  It has the desired
- * effect.
  */
 int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode)
 {
index ff9bcdc5b0d5a7b5f210723092716e9e0f32937c..8c892e93d8e7b6f2ff727709619eedde0e880812 100644 (file)
@@ -64,11 +64,6 @@ static int ext3_freeze(struct super_block *sb);
 
 /*
  * Wrappers for journal_start/end.
- *
- * The only special thing we need to do here is to make sure that all
- * journal_end calls result in the superblock being marked dirty, so
- * that sync() will call the filesystem's write_super callback if
- * appropriate.
  */
 handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks)
 {
@@ -90,12 +85,6 @@ handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks)
        return journal_start(journal, nblocks);
 }
 
-/*
- * The only special thing we need to do here is to make sure that all
- * journal_stop calls result in the superblock being marked dirty, so
- * that sync() will call the filesystem's write_super callback if
- * appropriate.
- */
 int __ext3_journal_stop(const char *where, handle_t *handle)
 {
        struct super_block *sb;
index d23b31ca9d7a713cfff0899889dd6eeb46f1b2c6..1b5089067d018d581c68242f39fcf522a8fee55d 100644 (file)
@@ -280,14 +280,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
        return desc;
 }
 
-static int ext4_valid_block_bitmap(struct super_block *sb,
-                                  struct ext4_group_desc *desc,
-                                  unsigned int block_group,
-                                  struct buffer_head *bh)
+/*
+ * Return the block number which was discovered to be invalid, or 0 if
+ * the block bitmap is valid.
+ */
+static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
+                                           struct ext4_group_desc *desc,
+                                           unsigned int block_group,
+                                           struct buffer_head *bh)
 {
        ext4_grpblk_t offset;
        ext4_grpblk_t next_zero_bit;
-       ext4_fsblk_t bitmap_blk;
+       ext4_fsblk_t blk;
        ext4_fsblk_t group_first_block;
 
        if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
@@ -297,37 +301,33 @@ static int ext4_valid_block_bitmap(struct super_block *sb,
                 * or it has to also read the block group where the bitmaps
                 * are located to verify they are set.
                 */
-               return 1;
+               return 0;
        }
        group_first_block = ext4_group_first_block_no(sb, block_group);
 
        /* check whether block bitmap block number is set */
-       bitmap_blk = ext4_block_bitmap(sb, desc);
-       offset = bitmap_blk - group_first_block;
+       blk = ext4_block_bitmap(sb, desc);
+       offset = blk - group_first_block;
        if (!ext4_test_bit(offset, bh->b_data))
                /* bad block bitmap */
-               goto err_out;
+               return blk;
 
        /* check whether the inode bitmap block number is set */
-       bitmap_blk = ext4_inode_bitmap(sb, desc);
-       offset = bitmap_blk - group_first_block;
+       blk = ext4_inode_bitmap(sb, desc);
+       offset = blk - group_first_block;
        if (!ext4_test_bit(offset, bh->b_data))
                /* bad block bitmap */
-               goto err_out;
+               return blk;
 
        /* check whether the inode table block number is set */
-       bitmap_blk = ext4_inode_table(sb, desc);
-       offset = bitmap_blk - group_first_block;
+       blk = ext4_inode_table(sb, desc);
+       offset = blk - group_first_block;
        next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
                                offset + EXT4_SB(sb)->s_itb_per_group,
                                offset);
-       if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group)
-               /* good bitmap for inode tables */
-               return 1;
-
-err_out:
-       ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu",
-                       block_group, bitmap_blk);
+       if (next_zero_bit < offset + EXT4_SB(sb)->s_itb_per_group)
+               /* bad bitmap for inode tables */
+               return blk;
        return 0;
 }
 
@@ -336,14 +336,26 @@ void ext4_validate_block_bitmap(struct super_block *sb,
                               unsigned int block_group,
                               struct buffer_head *bh)
 {
+       ext4_fsblk_t    blk;
+
        if (buffer_verified(bh))
                return;
 
        ext4_lock_group(sb, block_group);
-       if (ext4_valid_block_bitmap(sb, desc, block_group, bh) &&
-           ext4_block_bitmap_csum_verify(sb, block_group, desc, bh,
-                                         EXT4_BLOCKS_PER_GROUP(sb) / 8))
-               set_buffer_verified(bh);
+       blk = ext4_valid_block_bitmap(sb, desc, block_group, bh);
+       if (unlikely(blk != 0)) {
+               ext4_unlock_group(sb, block_group);
+               ext4_error(sb, "bg %u: block %llu: invalid block bitmap",
+                          block_group, blk);
+               return;
+       }
+       if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
+                       desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) {
+               ext4_unlock_group(sb, block_group);
+               ext4_error(sb, "bg %u: bad block bitmap checksum", block_group);
+               return;
+       }
+       set_buffer_verified(bh);
        ext4_unlock_group(sb, block_group);
 }
 
index f8716eab99952401dc473deb6619295b4a830f3b..5c2d1813ebe919188d53dac74de8b512a7f02965 100644 (file)
@@ -79,7 +79,6 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
        if (provided == calculated)
                return 1;
 
-       ext4_error(sb, "Bad block bitmap checksum: block_group = %u", group);
        return 0;
 }
 
index cd0c7ed0677200d09ce1445def04452a2f178978..aabbb3f53683f54081cd04c9a6d150e0121cc640 100644 (file)
@@ -2662,6 +2662,7 @@ cont:
                }
                path[0].p_depth = depth;
                path[0].p_hdr = ext_inode_hdr(inode);
+               i = 0;
 
                if (ext4_ext_check(inode, path[0].p_hdr, depth)) {
                        err = -EIO;
index 6324f74e03424e9ac21ceb01f6fbee07caa546df..dff171c3a1234e2ea9f545d8c2fd65c1b9b4bc1d 100644 (file)
@@ -1970,7 +1970,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
  * This function can get called via...
  *   - ext4_da_writepages after taking page lock (have journal handle)
  *   - journal_submit_inode_data_buffers (no journal handle)
- *   - shrink_page_list via pdflush (no journal handle)
+ *   - shrink_page_list via the kswapd/direct reclaim (no journal handle)
  *   - grab_page_cache when doing write_begin (have journal handle)
  *
  * We don't do any block allocation in this function. If we have page with
@@ -4589,14 +4589,6 @@ static int ext4_expand_extra_isize(struct inode *inode,
  * inode out, but prune_icache isn't a user-visible syncing function.
  * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync)
  * we start and wait on commits.
- *
- * Is this efficient/effective?  Well, we're being nice to the system
- * by cleaning up our inodes proactively so they can be reaped
- * without I/O.  But we are potentially leaving up to five seconds'
- * worth of inodes floating about which prune_icache wants us to
- * write out.  One way to fix that would be to get prune_icache()
- * to do a write_super() to free up some memory.  It has the desired
- * effect.
  */
 int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
 {
index d76ec8277d3fca660e619d097711cc0057349823..c6e0cb3d1f4a9e3730aea4904037eb0e9d4dd6d8 100644 (file)
@@ -326,11 +326,6 @@ static void ext4_put_nojournal(handle_t *handle)
 
 /*
  * Wrappers for jbd2_journal_start/end.
- *
- * The only special thing we need to do here is to make sure that all
- * journal_end calls result in the superblock being marked dirty, so
- * that sync() will call the filesystem's write_super callback if
- * appropriate.
  */
 handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
 {
@@ -356,12 +351,6 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
        return jbd2_journal_start(journal, nblocks);
 }
 
-/*
- * The only special thing we need to do here is to make sure that all
- * jbd2_journal_stop calls result in the superblock being marked dirty, so
- * that sync() will call the filesystem's write_super callback if
- * appropriate.
- */
 int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
 {
        struct super_block *sb;
@@ -959,6 +948,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        ei->i_reserved_meta_blocks = 0;
        ei->i_allocated_meta_blocks = 0;
        ei->i_da_metadata_calc_len = 0;
+       ei->i_da_metadata_calc_last_lblock = 0;
        spin_lock_init(&(ei->i_block_reservation_lock));
 #ifdef CONFIG_QUOTA
        ei->i_reserved_quota = 0;
@@ -3119,6 +3109,10 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp,
        ext4_group_t            i, ngroups = ext4_get_groups_count(sb);
        int                     s, j, count = 0;
 
+       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC))
+               return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) +
+                       sbi->s_itb_per_group + 2);
+
        first_block = le32_to_cpu(sbi->s_es->s_first_data_block) +
                (grp * EXT4_BLOCKS_PER_GROUP(sb));
        last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1;
@@ -4430,6 +4424,7 @@ static void ext4_clear_journal_err(struct super_block *sb,
                ext4_commit_super(sb, 1);
 
                jbd2_journal_clear_err(journal);
+               jbd2_journal_update_sb_errno(journal);
        }
 }
 
index 8964cf3999b2bb561ec71d93914170529f72977a..324bc085053447665eccaacdc8fcf169cb418413 100644 (file)
@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        struct fuse_entry_out outentry;
        struct fuse_file *ff;
 
+       /* Userspace expects S_IFREG in create mode */
+       BUG_ON((mode & S_IFMT) != S_IFREG);
+
        forget = fuse_alloc_forget();
        err = -ENOMEM;
        if (!forget)
index 93d8d6c9494dbd5737b0842a3ebb55ef972e0d87..aba15f1b7ad2974aa85e2c7272afc3d7836a40bc 100644 (file)
@@ -703,13 +703,16 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                                  unsigned long nr_segs, loff_t pos)
 {
        struct inode *inode = iocb->ki_filp->f_mapping->host;
+       struct fuse_conn *fc = get_fuse_conn(inode);
 
-       if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) {
+       /*
+        * In auto invalidate mode, always update attributes on read.
+        * Otherwise, only update if we attempt to read past EOF (to ensure
+        * i_size is up to date).
+        */
+       if (fc->auto_inval_data ||
+           (pos + iov_length(iov, nr_segs) > i_size_read(inode))) {
                int err;
-               /*
-                * If trying to read past EOF, make sure the i_size
-                * attribute is up-to-date.
-                */
                err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
                if (err)
                        return err;
@@ -1700,7 +1703,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
        size_t n;
        u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
 
-       for (n = 0; n < count; n++) {
+       for (n = 0; n < count; n++, iov++) {
                if (iov->iov_len > (size_t) max)
                        return -ENOMEM;
                max -= iov->iov_len;
index 771fb6322c0750d223bb2ee7873f6d0cdbdef41b..e24dd74e3068d130545ee58f918519d4ca2ee620 100644 (file)
@@ -484,6 +484,9 @@ struct fuse_conn {
        /** Is fallocate not implemented by fs? */
        unsigned no_fallocate:1;
 
+       /** Use enhanced/automatic page cache invalidation. */
+       unsigned auto_inval_data:1;
+
        /** The number of requests waiting for completion */
        atomic_t num_waiting;
 
index 1cd61652018c7c8547a060344ef998ee6ae96879..ce0a2838ccd097a5392d469fc0650d2e7b0d7e8d 100644 (file)
@@ -197,6 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
        loff_t oldsize;
+       struct timespec old_mtime;
 
        spin_lock(&fc->lock);
        if (attr_version != 0 && fi->attr_version > attr_version) {
@@ -204,15 +205,35 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
                return;
        }
 
+       old_mtime = inode->i_mtime;
        fuse_change_attributes_common(inode, attr, attr_valid);
 
        oldsize = inode->i_size;
        i_size_write(inode, attr->size);
        spin_unlock(&fc->lock);
 
-       if (S_ISREG(inode->i_mode) && oldsize != attr->size) {
-               truncate_pagecache(inode, oldsize, attr->size);
-               invalidate_inode_pages2(inode->i_mapping);
+       if (S_ISREG(inode->i_mode)) {
+               bool inval = false;
+
+               if (oldsize != attr->size) {
+                       truncate_pagecache(inode, oldsize, attr->size);
+                       inval = true;
+               } else if (fc->auto_inval_data) {
+                       struct timespec new_mtime = {
+                               .tv_sec = attr->mtime,
+                               .tv_nsec = attr->mtimensec,
+                       };
+
+                       /*
+                        * Auto inval mode also checks and invalidates if mtime
+                        * has changed.
+                        */
+                       if (!timespec_equal(&old_mtime, &new_mtime))
+                               inval = true;
+               }
+
+               if (inval)
+                       invalidate_inode_pages2(inode->i_mapping);
        }
 }
 
@@ -834,6 +855,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->big_writes = 1;
                        if (arg->flags & FUSE_DONT_MASK)
                                fc->dont_mask = 1;
+                       if (arg->flags & FUSE_AUTO_INVAL_DATA)
+                               fc->auto_inval_data = 1;
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
@@ -859,7 +882,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
        arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
        arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
                FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
-               FUSE_FLOCK_LOCKS;
+               FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
+               FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
index 3a56c8d94de0607249e6296a18ec28b5ea120e89..22255d96b27efbb9c3a93e6db8678a147d99548b 100644 (file)
@@ -52,7 +52,7 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb
                /*
                 * If it's a fully non-blocking write attempt and we cannot
                 * lock the buffer then redirty the page.  Note that this can
-                * potentially cause a busy-wait loop from pdflush and kswapd
+                * potentially cause a busy-wait loop from flusher thread and kswapd
                 * activity, but those code paths have their own higher-level
                 * throttling.
                 */
index 5fd51a5833ffb91facba871b74589bf8b9a6c087..b7ec224910c5d7bda2f36432260fa6a6050d76d4 100644 (file)
@@ -236,10 +236,10 @@ out:
  * hfs_mdb_commit()
  *
  * Description:
- *   This updates the MDB on disk (look also at hfs_write_super()).
+ *   This updates the MDB on disk.
  *   It does not check, if the superblock has been modified, or
  *   if the filesystem has been mounted read-only. It is mainly
- *   called by hfs_write_super() and hfs_btree_extend().
+ *   called by hfs_sync_fs() and flush_mdb().
  * Input Variable(s):
  *   struct hfs_mdb *mdb: Pointer to the hfs MDB
  *   int backup;
index 425c2f2cf1700a3f5d9db8fc4e93dcde0450d998..a2862339323b2a5f1e08dd7e25a779e1b683b828 100644 (file)
@@ -534,8 +534,8 @@ int journal_start_commit(journal_t *journal, tid_t *ptid)
                ret = 1;
        } else if (journal->j_committing_transaction) {
                /*
-                * If ext3_write_super() recently started a commit, then we
-                * have to wait for completion of that transaction
+                * If commit has been started, then we have to wait for
+                * completion of that transaction.
                 */
                if (ptid)
                        *ptid = journal->j_committing_transaction->t_tid;
@@ -1113,6 +1113,11 @@ static void mark_journal_empty(journal_t *journal)
 
        BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
        spin_lock(&journal->j_state_lock);
+       /* Is it already empty? */
+       if (sb->s_start == 0) {
+               spin_unlock(&journal->j_state_lock);
+               return;
+       }
        jbd_debug(1, "JBD: Marking journal as empty (seq %d)\n",
                  journal->j_tail_sequence);
 
index e9a3c4c85594e30aca1ed1f14d5667ba0595160a..e149b99a7ffb8e0c0db2a042aaac864f5fc65348 100644 (file)
@@ -612,8 +612,8 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid)
                ret = 1;
        } else if (journal->j_committing_transaction) {
                /*
-                * If ext3_write_super() recently started a commit, then we
-                * have to wait for completion of that transaction
+                * If commit has been started, then we have to wait for
+                * completion of that transaction.
                 */
                if (ptid)
                        *ptid = journal->j_committing_transaction->t_tid;
@@ -1377,7 +1377,7 @@ static void jbd2_mark_journal_empty(journal_t *journal)
  * Update a journal's errno.  Write updated superblock to disk waiting for IO
  * to complete.
  */
-static void jbd2_journal_update_sb_errno(journal_t *journal)
+void jbd2_journal_update_sb_errno(journal_t *journal)
 {
        journal_superblock_t *sb = journal->j_superblock;
 
@@ -1390,6 +1390,7 @@ static void jbd2_journal_update_sb_errno(journal_t *journal)
 
        jbd2_write_superblock(journal, WRITE_SYNC);
 }
+EXPORT_SYMBOL(jbd2_journal_update_sb_errno);
 
 /*
  * Read the superblock for a given journal, performing initial
index df0de27c273349c22ee6b8770b589663801c68f5..e784a217b50067919ad3ebffe559b3552b58a9bc 100644 (file)
@@ -26,6 +26,7 @@ static int sync_request(struct page *page, struct block_device *bdev, int rw)
        struct completion complete;
 
        bio_init(&bio);
+       bio.bi_max_vecs = 1;
        bio.bi_io_vec = &bio_vec;
        bio_vec.bv_page = page;
        bio_vec.bv_len = PAGE_SIZE;
@@ -95,12 +96,11 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
        struct address_space *mapping = super->s_mapping_inode->i_mapping;
        struct bio *bio;
        struct page *page;
-       struct request_queue *q = bdev_get_queue(sb->s_bdev);
-       unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
+       unsigned int max_pages;
        int i;
 
-       if (max_pages > BIO_MAX_PAGES)
-               max_pages = BIO_MAX_PAGES;
+       max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev));
+
        bio = bio_alloc(GFP_NOFS, max_pages);
        BUG_ON(!bio);
 
@@ -190,12 +190,11 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,
 {
        struct logfs_super *super = logfs_super(sb);
        struct bio *bio;
-       struct request_queue *q = bdev_get_queue(sb->s_bdev);
-       unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
+       unsigned int max_pages;
        int i;
 
-       if (max_pages > BIO_MAX_PAGES)
-               max_pages = BIO_MAX_PAGES;
+       max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev));
+
        bio = bio_alloc(GFP_NOFS, max_pages);
        BUG_ON(!bio);
 
index a422f42238b250764011fa421d24a1a0858dd153..6984562738d36bc4142a3e0556730ae9e3bf3a57 100644 (file)
@@ -156,10 +156,26 @@ static void __logfs_destroy_inode(struct inode *inode)
        call_rcu(&inode->i_rcu, logfs_i_callback);
 }
 
+static void __logfs_destroy_meta_inode(struct inode *inode)
+{
+       struct logfs_inode *li = logfs_inode(inode);
+       BUG_ON(li->li_block);
+       call_rcu(&inode->i_rcu, logfs_i_callback);
+}
+
 static void logfs_destroy_inode(struct inode *inode)
 {
        struct logfs_inode *li = logfs_inode(inode);
 
+       if (inode->i_ino < LOGFS_RESERVED_INOS) {
+               /*
+                * The reserved inodes are never destroyed unless we are in
+                * unmont path.
+                */
+               __logfs_destroy_meta_inode(inode);
+               return;
+       }
+
        BUG_ON(list_empty(&li->li_freeing_list));
        spin_lock(&logfs_inode_lock);
        li->li_refcount--;
@@ -373,8 +389,8 @@ static void logfs_put_super(struct super_block *sb)
 {
        struct logfs_super *super = logfs_super(sb);
        /* kill the meta-inodes */
-       iput(super->s_master_inode);
        iput(super->s_segfile_inode);
+       iput(super->s_master_inode);
        iput(super->s_mapping_inode);
 }
 
index 1e1c369df22bb085f62519b1100eb300053aaae8..2a09b8d73989539aedfe205fafd7f856f1122c7c 100644 (file)
@@ -565,7 +565,7 @@ static void write_wbuf(struct super_block *sb, struct logfs_area *area,
        index = ofs >> PAGE_SHIFT;
        page_ofs = ofs & (PAGE_SIZE - 1);
 
-       page = find_lock_page(mapping, index);
+       page = find_or_create_page(mapping, index, GFP_NOFS);
        BUG_ON(!page);
        memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize);
        unlock_page(page);
index f1cb512c5019dacf057391ed857a9697f0b98422..5be0abef603d4f82af9e59aaca639118e280476b 100644 (file)
@@ -2189,7 +2189,6 @@ void logfs_evict_inode(struct inode *inode)
                return;
        }
 
-       BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS);
        page = inode_to_page(inode);
        BUG_ON(!page); /* FIXME: Use emergency page */
        logfs_put_write_page(page);
index e28d090c98d6bbb2986d40fd4ae57e795cf7415c..038da0991794a39962fac3d4ef7ed5b18008c6f9 100644 (file)
@@ -886,7 +886,7 @@ static struct logfs_area *alloc_area(struct super_block *sb)
 
 static void map_invalidatepage(struct page *page, unsigned long l)
 {
-       BUG();
+       return;
 }
 
 static int map_releasepage(struct page *page, gfp_t g)
index 1b464390dde85ecd783eb45f64aee1f89f6c3ff1..dd1ed1b8e98efe048683e81bd1244c483160ad55 100644 (file)
@@ -352,6 +352,7 @@ int __inode_permission(struct inode *inode, int mask)
 /**
  * sb_permission - Check superblock-level permissions
  * @sb: Superblock of inode to check permission on
+ * @inode: Inode to check permission on
  * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
  *
  * Separate out file-system wide checks from inode-specific permission checks.
@@ -656,6 +657,7 @@ int sysctl_protected_hardlinks __read_mostly = 1;
 /**
  * may_follow_link - Check symlink following for unsafe situations
  * @link: The path of the symlink
+ * @nd: nameidata pathwalk data
  *
  * In the case of the sysctl_protected_symlinks sysctl being enabled,
  * CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is
@@ -2414,7 +2416,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
                goto out;
        }
 
-       mode = op->mode & S_IALLUGO;
+       mode = op->mode;
        if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
                mode &= ~current_umask();
 
@@ -2452,7 +2454,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
        }
 
        if (open_flag & O_CREAT) {
-               error = may_o_create(&nd->path, dentry, op->mode);
+               error = may_o_create(&nd->path, dentry, mode);
                if (error) {
                        create_error = error;
                        if (open_flag & O_EXCL)
@@ -2489,6 +2491,10 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
                        dput(dentry);
                        dentry = file->f_path.dentry;
                }
+               if (create_error && dentry->d_inode == NULL) {
+                       error = create_error;
+                       goto out;
+               }
                goto looked_up;
        }
 
index 8bf3a3f6925ab7459d93416f171b05d8cbf13cb7..b7db60897f91d5e8be99f59400add178cd082b8e 100644 (file)
@@ -12,19 +12,19 @@ nfs-$(CONFIG_ROOT_NFS)      += nfsroot.o
 nfs-$(CONFIG_SYSCTL)   += sysctl.o
 nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
 
-obj-$(CONFIG_NFS_V2) += nfs2.o
-nfs2-y := nfs2super.o proc.o nfs2xdr.o
+obj-$(CONFIG_NFS_V2) += nfsv2.o
+nfsv2-y := nfs2super.o proc.o nfs2xdr.o
 
-obj-$(CONFIG_NFS_V3) += nfs3.o
-nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
-nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
+obj-$(CONFIG_NFS_V3) += nfsv3.o
+nfsv3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
+nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
 
-obj-$(CONFIG_NFS_V4) += nfs4.o
-nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
+obj-$(CONFIG_NFS_V4) += nfsv4.o
+nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
          delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
          nfs4namespace.o nfs4getroot.o nfs4client.o
-nfs4-$(CONFIG_SYSCTL)  += nfs4sysctl.o
-nfs4-$(CONFIG_NFS_V4_1)        += pnfs.o pnfs_dev.o
+nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
+nfsv4-$(CONFIG_NFS_V4_1)       += pnfs.o pnfs_dev.o
 
 obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
 nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
index 9fc0d9dfc91b8a5e4226b0fcfb56bb55658f0869..99694442b93f6d64f5f433d8cf3cc8fdc08de52e 100644 (file)
@@ -105,7 +105,7 @@ struct nfs_subversion *get_nfs_version(unsigned int version)
 
        if (IS_ERR(nfs)) {
                mutex_lock(&nfs_version_mutex);
-               request_module("nfs%d", version);
+               request_module("nfsv%d", version);
                nfs = find_nfs_version(version);
                mutex_unlock(&nfs_version_mutex);
        }
index b701358c39c351d0613d1db29ebcf382ca8cb0a6..a850079467d85f149d997b9c96176c9a0829be0d 100644 (file)
@@ -61,6 +61,12 @@ struct idmap {
        struct mutex            idmap_mutex;
 };
 
+struct idmap_legacy_upcalldata {
+       struct rpc_pipe_msg pipe_msg;
+       struct idmap_msg idmap_msg;
+       struct idmap *idmap;
+};
+
 /**
  * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
  * @fattr: fully initialised struct nfs_fattr
@@ -324,6 +330,7 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
                ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
                                            name, namelen, type, data,
                                            data_size, idmap);
+               idmap->idmap_key_cons = NULL;
                mutex_unlock(&idmap->idmap_mutex);
        }
        return ret;
@@ -380,11 +387,13 @@ static const match_table_t nfs_idmap_tokens = {
 static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *);
 static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
                                   size_t);
+static void idmap_release_pipe(struct inode *);
 static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
 
 static const struct rpc_pipe_ops idmap_upcall_ops = {
        .upcall         = rpc_pipe_generic_upcall,
        .downcall       = idmap_pipe_downcall,
+       .release_pipe   = idmap_release_pipe,
        .destroy_msg    = idmap_pipe_destroy_msg,
 };
 
@@ -616,7 +625,8 @@ void nfs_idmap_quit(void)
        nfs_idmap_quit_keyring();
 }
 
-static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im,
+static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
+                                    struct idmap_msg *im,
                                     struct rpc_pipe_msg *msg)
 {
        substring_t substr;
@@ -659,6 +669,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
                                   const char *op,
                                   void *aux)
 {
+       struct idmap_legacy_upcalldata *data;
        struct rpc_pipe_msg *msg;
        struct idmap_msg *im;
        struct idmap *idmap = (struct idmap *)aux;
@@ -666,15 +677,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
        int ret = -ENOMEM;
 
        /* msg and im are freed in idmap_pipe_destroy_msg */
-       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
-       if (!msg)
-               goto out0;
-
-       im = kmalloc(sizeof(*im), GFP_KERNEL);
-       if (!im)
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
                goto out1;
 
-       ret = nfs_idmap_prepare_message(key->description, im, msg);
+       msg = &data->pipe_msg;
+       im = &data->idmap_msg;
+       data->idmap = idmap;
+
+       ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
        if (ret < 0)
                goto out2;
 
@@ -683,15 +694,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
 
        ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
        if (ret < 0)
-               goto out2;
+               goto out3;
 
        return ret;
 
+out3:
+       idmap->idmap_key_cons = NULL;
 out2:
-       kfree(im);
+       kfree(data);
 out1:
-       kfree(msg);
-out0:
        complete_request_key(cons, ret);
        return ret;
 }
@@ -749,9 +760,8 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
        }
 
        if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
-               ret = mlen;
-               complete_request_key(cons, -ENOKEY);
-               goto out_incomplete;
+               ret = -ENOKEY;
+               goto out;
        }
 
        namelen_in = strnlen(im.im_name, IDMAP_NAMESZ);
@@ -768,16 +778,32 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 
 out:
        complete_request_key(cons, ret);
-out_incomplete:
        return ret;
 }
 
 static void
 idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
 {
+       struct idmap_legacy_upcalldata *data = container_of(msg,
+                       struct idmap_legacy_upcalldata,
+                       pipe_msg);
+       struct idmap *idmap = data->idmap;
+       struct key_construction *cons;
+       if (msg->errno) {
+               cons = ACCESS_ONCE(idmap->idmap_key_cons);
+               idmap->idmap_key_cons = NULL;
+               complete_request_key(cons, msg->errno);
+       }
        /* Free memory allocated in nfs_idmap_legacy_upcall() */
-       kfree(msg->data);
-       kfree(msg);
+       kfree(data);
+}
+
+static void
+idmap_release_pipe(struct inode *inode)
+{
+       struct rpc_inode *rpci = RPC_I(inode);
+       struct idmap *idmap = (struct idmap *)rpci->private;
+       idmap->idmap_key_cons = NULL;
 }
 
 int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
index 0952c791df36eb4f1aa58beb20732c9af67a3098..d6b3b5f2d779acd1ce7e0324e8c52e388c7a273a 100644 (file)
@@ -69,7 +69,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
        nfs_fattr_init(info->fattr);
        status = rpc_call_sync(client, &msg, 0);
        dprintk("%s: reply fsinfo: %d\n", __func__, status);
-       if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
+       if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) {
                msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
                msg.rpc_resp = info->fattr;
                status = rpc_call_sync(client, &msg, 0);
index 3b950dd81e81f82b4fd32c5b508fde181d07b875..da0618aeeadb88c04447a63b18e2d908b6d03955 100644 (file)
@@ -205,6 +205,9 @@ extern const struct dentry_operations nfs4_dentry_operations;
 int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
                    unsigned, umode_t, int *);
 
+/* super.c */
+extern struct file_system_type nfs4_fs_type;
+
 /* nfs4namespace.c */
 rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
 struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
index cbcdfaf325054e215159f2d1c1797994eff050ac..24eb663f8ed528426572471a629ab033726919d8 100644 (file)
@@ -74,7 +74,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
        return clp;
 
 error:
-       kfree(clp);
+       nfs_free_client(clp);
        return ERR_PTR(err);
 }
 
index a99a8d94872131610ab543d5a06d9f4f541cc2dc..635274140b180287668dbaa7540bd84852051181 100644 (file)
@@ -3737,9 +3737,10 @@ out:
 static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len)
 {
        struct nfs4_cached_acl *acl;
+       size_t buflen = sizeof(*acl) + acl_len;
 
-       if (pages && acl_len <= PAGE_SIZE) {
-               acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL);
+       if (pages && buflen <= PAGE_SIZE) {
+               acl = kmalloc(buflen, GFP_KERNEL);
                if (acl == NULL)
                        goto out;
                acl->cached = 1;
@@ -3819,7 +3820,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
        if (ret)
                goto out_free;
 
-       acl_len = res.acl_len - res.acl_data_offset;
+       acl_len = res.acl_len;
        if (acl_len > args.acl_len)
                nfs4_write_cached_acl(inode, NULL, 0, acl_len);
        else
@@ -6223,11 +6224,58 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
        dprintk("<-- %s\n", __func__);
 }
 
+static size_t max_response_pages(struct nfs_server *server)
+{
+       u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
+       return nfs_page_array_len(0, max_resp_sz);
+}
+
+static void nfs4_free_pages(struct page **pages, size_t size)
+{
+       int i;
+
+       if (!pages)
+               return;
+
+       for (i = 0; i < size; i++) {
+               if (!pages[i])
+                       break;
+               __free_page(pages[i]);
+       }
+       kfree(pages);
+}
+
+static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
+{
+       struct page **pages;
+       int i;
+
+       pages = kcalloc(size, sizeof(struct page *), gfp_flags);
+       if (!pages) {
+               dprintk("%s: can't alloc array of %zu pages\n", __func__, size);
+               return NULL;
+       }
+
+       for (i = 0; i < size; i++) {
+               pages[i] = alloc_page(gfp_flags);
+               if (!pages[i]) {
+                       dprintk("%s: failed to allocate page\n", __func__);
+                       nfs4_free_pages(pages, size);
+                       return NULL;
+               }
+       }
+
+       return pages;
+}
+
 static void nfs4_layoutget_release(void *calldata)
 {
        struct nfs4_layoutget *lgp = calldata;
+       struct nfs_server *server = NFS_SERVER(lgp->args.inode);
+       size_t max_pages = max_response_pages(server);
 
        dprintk("--> %s\n", __func__);
+       nfs4_free_pages(lgp->args.layout.pages, max_pages);
        put_nfs_open_context(lgp->args.ctx);
        kfree(calldata);
        dprintk("<-- %s\n", __func__);
@@ -6239,9 +6287,10 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
        .rpc_release = nfs4_layoutget_release,
 };
 
-int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
+void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
 {
        struct nfs_server *server = NFS_SERVER(lgp->args.inode);
+       size_t max_pages = max_response_pages(server);
        struct rpc_task *task;
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET],
@@ -6259,12 +6308,19 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
 
        dprintk("--> %s\n", __func__);
 
+       lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
+       if (!lgp->args.layout.pages) {
+               nfs4_layoutget_release(lgp);
+               return;
+       }
+       lgp->args.layout.pglen = max_pages * PAGE_SIZE;
+
        lgp->res.layoutp = &lgp->args.layout;
        lgp->res.seq_res.sr_slot = NULL;
        nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
        task = rpc_run_task(&task_setup_data);
        if (IS_ERR(task))
-               return PTR_ERR(task);
+               return;
        status = nfs4_wait_for_completion_rpc_task(task);
        if (status == 0)
                status = task->tk_status;
@@ -6272,7 +6328,7 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
                status = pnfs_layout_process(lgp);
        rpc_put_task(task);
        dprintk("<-- %s status=%d\n", __func__, status);
-       return status;
+       return;
 }
 
 static void
@@ -6304,12 +6360,8 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
                return;
        }
        spin_lock(&lo->plh_inode->i_lock);
-       if (task->tk_status == 0) {
-               if (lrp->res.lrs_present) {
-                       pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
-               } else
-                       BUG_ON(!list_empty(&lo->plh_segs));
-       }
+       if (task->tk_status == 0 && lrp->res.lrs_present)
+               pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
        lo->plh_block_lgets--;
        spin_unlock(&lo->plh_inode->i_lock);
        dprintk("<-- %s\n", __func__);
index 12a31a9dbcddc562e7f55e65ae4952810dccb3f7..bd61221ad2c5542b08f42249d10285c159f66b1d 100644 (file)
@@ -23,14 +23,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
 static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *raw_data);
 
-static struct file_system_type nfs4_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "nfs4",
-       .mount          = nfs_fs_mount,
-       .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
-};
-
 static struct file_system_type nfs4_remote_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "nfs4",
@@ -344,14 +336,8 @@ static int __init init_nfs_v4(void)
        if (err)
                goto out1;
 
-       err = register_filesystem(&nfs4_fs_type);
-       if (err < 0)
-               goto out2;
-
        register_nfs_version(&nfs_v4);
        return 0;
-out2:
-       nfs4_unregister_sysctl();
 out1:
        nfs_idmap_quit();
 out:
@@ -361,7 +347,6 @@ out:
 static void __exit exit_nfs_v4(void)
 {
        unregister_nfs_version(&nfs_v4);
-       unregister_filesystem(&nfs4_fs_type);
        nfs4_unregister_sysctl();
        nfs_idmap_quit();
 }
index ca13483edd60aee67c8e1673b18250959187f8a4..1bfbd67c556d753a21f046c87edc3c9b07b0b8f0 100644 (file)
@@ -5045,22 +5045,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
                         struct nfs_getaclres *res)
 {
        unsigned int savep;
-       __be32 *bm_p;
        uint32_t attrlen,
                 bitmap[3] = {0};
        int status;
-       size_t page_len = xdr->buf->page_len;
+       unsigned int pg_offset;
 
        res->acl_len = 0;
        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
                goto out;
 
-       bm_p = xdr->p;
-       res->acl_data_offset = be32_to_cpup(bm_p) + 2;
-       res->acl_data_offset <<= 2;
-       /* Check if the acl data starts beyond the allocated buffer */
-       if (res->acl_data_offset > page_len)
-               return -ERANGE;
+       xdr_enter_page(xdr, xdr->buf->page_len);
+
+       /* Calculate the offset of the page data */
+       pg_offset = xdr->buf->head[0].iov_len;
 
        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
                goto out;
@@ -5074,23 +5071,20 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
                /* The bitmap (xdr len + bitmaps) and the attr xdr len words
                 * are stored with the acl data to handle the problem of
                 * variable length bitmaps.*/
-               xdr->p = bm_p;
+               res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset;
 
                /* We ignore &savep and don't do consistency checks on
                 * the attr length.  Let userspace figure it out.... */
-               attrlen += res->acl_data_offset;
-               if (attrlen > page_len) {
+               res->acl_len = attrlen;
+               if (attrlen > (xdr->nwords << 2)) {
                        if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
                                /* getxattr interface called with a NULL buf */
-                               res->acl_len = attrlen;
                                goto out;
                        }
-                       dprintk("NFS: acl reply: attrlen %u > page_len %zu\n",
-                                       attrlen, page_len);
+                       dprintk("NFS: acl reply: attrlen %u > page_len %u\n",
+                                       attrlen, xdr->nwords << 2);
                        return -EINVAL;
                }
-               xdr_read_pages(xdr, attrlen);
-               res->acl_len = attrlen;
        } else
                status = -EOPNOTSUPP;
 
index f50d3e8d6f2230a42cdc656b61004dcf62182dd2..ea6d111b03e9484c23d5ca3f7997f10d893a57ad 100644 (file)
@@ -570,17 +570,66 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
                return false;
 
        return pgio->pg_count + req->wb_bytes <=
-                       OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
+                       (unsigned long)pgio->pg_layout_private;
+}
+
+void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
+{
+       pnfs_generic_pg_init_read(pgio, req);
+       if (unlikely(pgio->pg_lseg == NULL))
+               return; /* Not pNFS */
+
+       pgio->pg_layout_private = (void *)
+                               OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
+}
+
+static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout,
+                                  unsigned long *stripe_end)
+{
+       u32 stripe_off;
+       unsigned stripe_size;
+
+       if (layout->raid_algorithm == PNFS_OSD_RAID_0)
+               return true;
+
+       stripe_size = layout->stripe_unit *
+                               (layout->group_width - layout->parity);
+
+       div_u64_rem(offset, stripe_size, &stripe_off);
+       if (!stripe_off)
+               return true;
+
+       *stripe_end = stripe_size - stripe_off;
+       return false;
+}
+
+void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
+{
+       unsigned long stripe_end = 0;
+
+       pnfs_generic_pg_init_write(pgio, req);
+       if (unlikely(pgio->pg_lseg == NULL))
+               return; /* Not pNFS */
+
+       if (req->wb_offset ||
+           !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE,
+                              &OBJIO_LSEG(pgio->pg_lseg)->layout,
+                              &stripe_end)) {
+               pgio->pg_layout_private = (void *)stripe_end;
+       } else {
+               pgio->pg_layout_private = (void *)
+                               OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
+       }
 }
 
 static const struct nfs_pageio_ops objio_pg_read_ops = {
-       .pg_init = pnfs_generic_pg_init_read,
+       .pg_init = objio_init_read,
        .pg_test = objio_pg_test,
        .pg_doio = pnfs_generic_pg_readpages,
 };
 
 static const struct nfs_pageio_ops objio_pg_write_ops = {
-       .pg_init = pnfs_generic_pg_init_write,
+       .pg_init = objio_init_write,
        .pg_test = objio_pg_test,
        .pg_doio = pnfs_generic_pg_writepages,
 };
index 1a6732ed04a447aa14147468e15f4b7956557376..311a79681e2b16311724e25921d922768c999026 100644 (file)
@@ -49,6 +49,7 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
        hdr->io_start = req_offset(hdr->req);
        hdr->good_bytes = desc->pg_count;
        hdr->dreq = desc->pg_dreq;
+       hdr->layout_private = desc->pg_layout_private;
        hdr->release = release;
        hdr->completion_ops = desc->pg_completion_ops;
        if (hdr->completion_ops->init_hdr)
@@ -268,6 +269,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
        desc->pg_error = 0;
        desc->pg_lseg = NULL;
        desc->pg_dreq = NULL;
+       desc->pg_layout_private = NULL;
 }
 EXPORT_SYMBOL_GPL(nfs_pageio_init);
 
index 76875bfcf19ceda4a54cb0dde14466a304191cf9..2e00feacd4bee642c59c965612068653f120756c 100644 (file)
@@ -583,9 +583,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
        struct nfs_server *server = NFS_SERVER(ino);
        struct nfs4_layoutget *lgp;
        struct pnfs_layout_segment *lseg = NULL;
-       struct page **pages = NULL;
-       int i;
-       u32 max_resp_sz, max_pages;
 
        dprintk("--> %s\n", __func__);
 
@@ -594,20 +591,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
        if (lgp == NULL)
                return NULL;
 
-       /* allocate pages for xdr post processing */
-       max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
-       max_pages = nfs_page_array_len(0, max_resp_sz);
-
-       pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags);
-       if (!pages)
-               goto out_err_free;
-
-       for (i = 0; i < max_pages; i++) {
-               pages[i] = alloc_page(gfp_flags);
-               if (!pages[i])
-                       goto out_err_free;
-       }
-
        lgp->args.minlength = PAGE_CACHE_SIZE;
        if (lgp->args.minlength > range->length)
                lgp->args.minlength = range->length;
@@ -616,39 +599,19 @@ send_layoutget(struct pnfs_layout_hdr *lo,
        lgp->args.type = server->pnfs_curr_ld->id;
        lgp->args.inode = ino;
        lgp->args.ctx = get_nfs_open_context(ctx);
-       lgp->args.layout.pages = pages;
-       lgp->args.layout.pglen = max_pages * PAGE_SIZE;
        lgp->lsegpp = &lseg;
        lgp->gfp_flags = gfp_flags;
 
        /* Synchronously retrieve layout information from server and
         * store in lseg.
         */
-       nfs4_proc_layoutget(lgp);
+       nfs4_proc_layoutget(lgp, gfp_flags);
        if (!lseg) {
                /* remember that LAYOUTGET failed and suspend trying */
                set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
        }
 
-       /* free xdr pages */
-       for (i = 0; i < max_pages; i++)
-               __free_page(pages[i]);
-       kfree(pages);
-
        return lseg;
-
-out_err_free:
-       /* free any allocated xdr pages, lgp as it's not used */
-       if (pages) {
-               for (i = 0; i < max_pages; i++) {
-                       if (!pages[i])
-                               break;
-                       __free_page(pages[i]);
-               }
-               kfree(pages);
-       }
-       kfree(lgp);
-       return NULL;
 }
 
 /*
index 2c6c80503ba4851ed1e69c253293684c540b2c32..745aa1b39e7c3d1e543a1c0beae0113c99a23cac 100644 (file)
@@ -172,7 +172,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server,
                                   struct pnfs_devicelist *devlist);
 extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
                                   struct pnfs_device *dev);
-extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
+extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
 extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
 
 /* pnfs.c */
index ac6a3c55dce408afbd5348a2f9af42a7f78e660e..239aff7338eb89ee8c0d4080694178317d84929e 100644 (file)
@@ -319,6 +319,34 @@ EXPORT_SYMBOL_GPL(nfs_sops);
 static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
 static int nfs4_validate_mount_data(void *options,
        struct nfs_parsed_mount_data *args, const char *dev_name);
+
+struct file_system_type nfs4_fs_type = {
+       .owner          = THIS_MODULE,
+       .name           = "nfs4",
+       .mount          = nfs_fs_mount,
+       .kill_sb        = nfs_kill_super,
+       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+};
+EXPORT_SYMBOL_GPL(nfs4_fs_type);
+
+static int __init register_nfs4_fs(void)
+{
+       return register_filesystem(&nfs4_fs_type);
+}
+
+static void unregister_nfs4_fs(void)
+{
+       unregister_filesystem(&nfs4_fs_type);
+}
+#else
+static int __init register_nfs4_fs(void)
+{
+       return 0;
+}
+
+static void unregister_nfs4_fs(void)
+{
+}
 #endif
 
 static struct shrinker acl_shrinker = {
@@ -337,12 +365,18 @@ int __init register_nfs_fs(void)
        if (ret < 0)
                goto error_0;
 
-       ret = nfs_register_sysctl();
+       ret = register_nfs4_fs();
        if (ret < 0)
                goto error_1;
+
+       ret = nfs_register_sysctl();
+       if (ret < 0)
+               goto error_2;
        register_shrinker(&acl_shrinker);
        return 0;
 
+error_2:
+       unregister_nfs4_fs();
 error_1:
        unregister_filesystem(&nfs_fs_type);
 error_0:
@@ -356,6 +390,7 @@ void __exit unregister_nfs_fs(void)
 {
        unregister_shrinker(&acl_shrinker);
        nfs_unregister_sysctl();
+       unregister_nfs4_fs();
        unregister_filesystem(&nfs_fs_type);
 }
 
@@ -2645,4 +2680,6 @@ MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
 module_param(send_implementation_id, ushort, 0644);
 MODULE_PARM_DESC(send_implementation_id,
                "Send implementation ID with NFSv4.1 exchange_id");
+MODULE_ALIAS("nfs4");
+
 #endif /* CONFIG_NFS_V4 */
index 5829d0ce7cfb574f28451380b153df72d3dcd18f..e3b55372726cb0d2a082c62ed86a35e8605c66b5 100644 (file)
@@ -1814,19 +1814,19 @@ int __init nfs_init_writepagecache(void)
        nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE,
                                                     nfs_wdata_cachep);
        if (nfs_wdata_mempool == NULL)
-               return -ENOMEM;
+               goto out_destroy_write_cache;
 
        nfs_cdata_cachep = kmem_cache_create("nfs_commit_data",
                                             sizeof(struct nfs_commit_data),
                                             0, SLAB_HWCACHE_ALIGN,
                                             NULL);
        if (nfs_cdata_cachep == NULL)
-               return -ENOMEM;
+               goto out_destroy_write_mempool;
 
        nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
                                                      nfs_wdata_cachep);
        if (nfs_commit_mempool == NULL)
-               return -ENOMEM;
+               goto out_destroy_commit_cache;
 
        /*
         * NFS congestion size, scale with available memory.
@@ -1849,11 +1849,20 @@ int __init nfs_init_writepagecache(void)
                nfs_congestion_kb = 256*1024;
 
        return 0;
+
+out_destroy_commit_cache:
+       kmem_cache_destroy(nfs_cdata_cachep);
+out_destroy_write_mempool:
+       mempool_destroy(nfs_wdata_mempool);
+out_destroy_write_cache:
+       kmem_cache_destroy(nfs_wdata_cachep);
+       return -ENOMEM;
 }
 
 void nfs_destroy_writepagecache(void)
 {
        mempool_destroy(nfs_commit_mempool);
+       kmem_cache_destroy(nfs_cdata_cachep);
        mempool_destroy(nfs_wdata_mempool);
        kmem_cache_destroy(nfs_wdata_cachep);
 }
index cbaf4f8bb7b712be7e92db2a7bf102c1f8c2dc6f..4c7bd35b187687915ab4826877dc62aecca707e3 100644 (file)
@@ -651,12 +651,12 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
 
        if (clp->cl_minorversion == 0) {
                if (!clp->cl_cred.cr_principal &&
-                               (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
+                               (clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5))
                        return -EINVAL;
                args.client_name = clp->cl_cred.cr_principal;
                args.prognumber = conn->cb_prog,
                args.protocol = XPRT_TRANSPORT_TCP;
-               args.authflavor = clp->cl_flavor;
+               args.authflavor = clp->cl_cred.cr_flavor;
                clp->cl_cb_ident = conn->cb_ident;
        } else {
                if (!conn->cb_xprt)
index e6173147f9821c816527e0bde05289d392374af7..22bd0a66c3566465ee77ca228b1979134b625ab2 100644 (file)
@@ -231,7 +231,6 @@ struct nfs4_client {
        nfs4_verifier           cl_verifier;    /* generated by client */
        time_t                  cl_time;        /* time of last lease renewal */
        struct sockaddr_storage cl_addr;        /* client ipaddress */
-       u32                     cl_flavor;      /* setclientid pseudoflavor */
        struct svc_cred         cl_cred;        /* setclientid principal */
        clientid_t              cl_clientid;    /* generated by server */
        nfs4_verifier           cl_confirm;     /* generated by server */
index 6522cac6057c900fccdac3138475ea4c0aa0a830..6a10812711c1d37bca6660530cd6c34cbb7b30fb 100644 (file)
@@ -676,17 +676,13 @@ static const struct super_operations nilfs_sops = {
        .alloc_inode    = nilfs_alloc_inode,
        .destroy_inode  = nilfs_destroy_inode,
        .dirty_inode    = nilfs_dirty_inode,
-       /* .write_inode    = nilfs_write_inode, */
-       /* .drop_inode    = nilfs_drop_inode, */
        .evict_inode    = nilfs_evict_inode,
        .put_super      = nilfs_put_super,
-       /* .write_super    = nilfs_write_super, */
        .sync_fs        = nilfs_sync_fs,
        .freeze_fs      = nilfs_freeze,
        .unfreeze_fs    = nilfs_unfreeze,
        .statfs         = nilfs_statfs,
        .remount_fs     = nilfs_remount,
-       /* .umount_begin */
        .show_options = nilfs_show_options
 };
 
index 6eee4177807bf611874208c09fce9440979fbc4f..be1267a34ceae883b7d705c967347ad4a4185b57 100644 (file)
@@ -107,8 +107,6 @@ struct the_nilfs {
         * used for
         * - loading the latest checkpoint exclusively.
         * - allocating a new full segment.
-        * - protecting s_dirt in the super_block struct
-        *   (see nilfs_write_super) and the following fields.
         */
        struct buffer_head     *ns_sbh[2];
        struct nilfs_super_block *ns_sbp[2];
index f3d96e7e7b19d4254924a59dfc4121aa5d8635b4..e1f2cdb91a4dc494473986f1b0c8b91f23614a43 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -717,7 +717,7 @@ cleanup_all:
                         * here, so just reset the state.
                         */
                        file_reset_write(f);
-                       mnt_drop_write(f->f_path.mnt);
+                       __mnt_drop_write(f->f_path.mnt);
                }
        }
 cleanup_file:
@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
        int lookup_flags = 0;
        int acc_mode;
 
-       if (!(flags & O_CREAT))
-               mode = 0;
-       op->mode = mode;
+       if (flags & O_CREAT)
+               op->mode = (mode & S_IALLUGO) | S_IFREG;
+       else
+               op->mode = 0;
 
        /* Must never be set by userspace */
        flags &= ~FMODE_NONOTIFY;
index 36a29b753c79c709175ebfd788196d1ecad948b5..c495a3055e2a3be9b5e471afebdf53ac00c6fe51 100644 (file)
@@ -1589,10 +1589,10 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
                goto out;
        }
 
-       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
                warn[cnt].w_type = QUOTA_NL_NOWARN;
 
+       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
        spin_lock(&dq_data_lock);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                if (!dquots[cnt])
index 4c0c7d163d150c02535cffcad08a1aead02f53d2..a98b7740a0fcade0b894920154e65ecbe7987509 100644 (file)
@@ -1334,9 +1334,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
        else if (bitmap == 0)
                block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
 
-       reiserfs_write_unlock(sb);
        bh = sb_bread(sb, block);
-       reiserfs_write_lock(sb);
        if (bh == NULL)
                reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) "
                                 "reading failed", __func__, block);
index a6d4268fb6c11798db5f8339bd14ab297cd9b21f..855da58db1456b94d43715bb4a28bbc5f982a8d7 100644 (file)
@@ -76,10 +76,10 @@ void reiserfs_evict_inode(struct inode *inode)
                ;
        }
       out:
+       reiserfs_write_unlock_once(inode->i_sb, depth);
        clear_inode(inode);     /* note this must go after the journal_end to prevent deadlock */
        dquot_drop(inode);
        inode->i_blocks = 0;
-       reiserfs_write_unlock_once(inode->i_sb, depth);
        return;
 
 no_delete:
index b05cf47463d0c2347e8eca1597001f96dd2a97fc..0902cfa6a12efd21e4ebd52a39333b7f9d6270eb 100644 (file)
@@ -536,46 +536,6 @@ void drop_super(struct super_block *sb)
 
 EXPORT_SYMBOL(drop_super);
 
-/**
- * sync_supers - helper for periodic superblock writeback
- *
- * Call the write_super method if present on all dirty superblocks in
- * the system.  This is for the periodic writeback used by most older
- * filesystems.  For data integrity superblock writeback use
- * sync_filesystems() instead.
- *
- * Note: check the dirty flag before waiting, so we don't
- * hold up the sync while mounting a device. (The newly
- * mounted device won't need syncing.)
- */
-void sync_supers(void)
-{
-       struct super_block *sb, *p = NULL;
-
-       spin_lock(&sb_lock);
-       list_for_each_entry(sb, &super_blocks, s_list) {
-               if (hlist_unhashed(&sb->s_instances))
-                       continue;
-               if (sb->s_op->write_super && sb->s_dirt) {
-                       sb->s_count++;
-                       spin_unlock(&sb_lock);
-
-                       down_read(&sb->s_umount);
-                       if (sb->s_root && sb->s_dirt && (sb->s_flags & MS_BORN))
-                               sb->s_op->write_super(sb);
-                       up_read(&sb->s_umount);
-
-                       spin_lock(&sb_lock);
-                       if (p)
-                               __put_super(p);
-                       p = sb;
-               }
-       }
-       if (p)
-               __put_super(p);
-       spin_unlock(&sb_lock);
-}
-
 /**
  *     iterate_supers - call function for all active superblocks
  *     @f: function to call
index 8b8cc4e945f4014bd8e0a77d1d9bde0197f0fa76..760de723dadb4928eec6f9c4729245a40dcce5de 100644 (file)
@@ -167,7 +167,7 @@ struct ubifs_global_debug_info {
 #define ubifs_dbg_msg(type, fmt, ...) \
        pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__)
 
-#define DBG_KEY_BUF_LEN 32
+#define DBG_KEY_BUF_LEN 48
 #define ubifs_dbg_msg_key(type, key, fmt, ...) do {                            \
        char __tmp_key_buf[DBG_KEY_BUF_LEN];                                   \
        pr_debug("UBIFS DBG " type ": " fmt "%s\n", ##__VA_ARGS__,             \
index 35389ca2d267093895681dc0f01dfa1e5f577d79..7bd6e72afd1136a3141e42227553ba5daa5ffcba 100644 (file)
  *
  * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we
  * implement. However, this is not true for 'ubifs_writepage()', which may be
- * called with @i_mutex unlocked. For example, when pdflush is doing background
- * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal"
- * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the
- * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()'
- * we are only guaranteed that the page is locked.
+ * called with @i_mutex unlocked. For example, when flusher thread is doing
+ * background write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex.
+ * At "normal" work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g.
+ * in the "sys_write -> alloc_pages -> direct reclaim path". So, in
+ * 'ubifs_writepage()' we are only guaranteed that the page is locked.
  *
  * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the
  * read-ahead path does not lock it ("sys_read -> generic_file_aio_read ->
index ce33b2beb151f92ac61e51dcefc47cd25ee8dd15..8640920766ed461896add49f69b9db767aa9569c 100644 (file)
@@ -1749,7 +1749,10 @@ int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr)
        return 0;
 
 out_err:
-       ubifs_lpt_free(c, 0);
+       if (wr)
+               ubifs_lpt_free(c, 1);
+       if (rd)
+               ubifs_lpt_free(c, 0);
        return err;
 }
 
index c30d976b4be857a9d222cedd5b7192a4f90e6cfa..edeec499c048ba1d93375796b5fd4f439f38dd81 100644 (file)
@@ -788,7 +788,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
 
 corrupted_rescan:
        /* Re-scan the corrupted data with verbose messages */
-       ubifs_err("corruptio %d", ret);
+       ubifs_err("corruption %d", ret);
        ubifs_scan_a_node(c, buf, len, lnum, offs, 1);
 corrupted:
        ubifs_scanned_corruption(c, lnum, offs, buf);
index eba46d4a76192c017846c4389addf2ebdcc2a78e..94d78fc5d4e0dc11e6ea4db670f43853f569eabb 100644 (file)
@@ -1026,7 +1026,6 @@ int ubifs_replay_journal(struct ubifs_info *c)
        c->replaying = 1;
        lnum = c->ltail_lnum = c->lhead_lnum;
 
-       lnum = UBIFS_LOG_LNUM;
        do {
                err = replay_log_leb(c, lnum, 0, c->sbuf);
                if (err == 1)
@@ -1035,7 +1034,7 @@ int ubifs_replay_journal(struct ubifs_info *c)
                if (err)
                        goto out;
                lnum = ubifs_next_log_lnum(c, lnum);
-       } while (lnum != UBIFS_LOG_LNUM);
+       } while (lnum != c->ltail_lnum);
 
        err = replay_buds(c);
        if (err)
index 1c766c39c03819b4d088f19f0215c63a89f2b539..71a197f0f93d24c0cc33527d4f2d69c8c3d51f7b 100644 (file)
@@ -303,7 +303,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
        mutex_lock(&ui->ui_mutex);
        /*
         * Due to races between write-back forced by budgeting
-        * (see 'sync_some_inodes()') and pdflush write-back, the inode may
+        * (see 'sync_some_inodes()') and background write-back, the inode may
         * have already been synchronized, do not do this again. This might
         * also happen if it was synchronized in an VFS operation, e.g.
         * 'ubifs_link()'.
@@ -1157,9 +1157,6 @@ static int check_free_space(struct ubifs_info *c)
  *
  * This function mounts UBIFS file system. Returns zero in case of success and
  * a negative error code in case of failure.
- *
- * Note, the function does not de-allocate resources it it fails half way
- * through, and the caller has to do this instead.
  */
 static int mount_ubifs(struct ubifs_info *c)
 {
index fafaad795cd6da4842a798e25446f6b426d65d65..aa233469b3c1a0deb1e3ef60b8039f5dd2e1cd55 100644 (file)
@@ -1124,14 +1124,17 @@ int udf_setsize(struct inode *inode, loff_t newsize)
                                if (err)
                                        return err;
                                down_write(&iinfo->i_data_sem);
-                       } else
+                       } else {
                                iinfo->i_lenAlloc = newsize;
+                               goto set_size;
+                       }
                }
                err = udf_extend_file(inode, newsize);
                if (err) {
                        up_write(&iinfo->i_data_sem);
                        return err;
                }
+set_size:
                truncate_setsize(inode, newsize);
                up_write(&iinfo->i_data_sem);
        } else {
index dcbf98722afcd5df2a8940f4dbd5c1c8a02c7b40..18fc038a438da4b6bbf58fa73c23c27ecd0cb721 100644 (file)
@@ -1344,6 +1344,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
                udf_err(sb, "error loading logical volume descriptor: "
                        "Partition table too long (%u > %lu)\n", table_len,
                        sb->s_blocksize - sizeof(*lvd));
+               ret = 1;
                goto out_bh;
        }
 
@@ -1388,8 +1389,10 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
                                                UDF_ID_SPARABLE,
                                                strlen(UDF_ID_SPARABLE))) {
                                if (udf_load_sparable_map(sb, map,
-                                   (struct sparablePartitionMap *)gpm) < 0)
+                                   (struct sparablePartitionMap *)gpm) < 0) {
+                                       ret = 1;
                                        goto out_bh;
+                               }
                        } else if (!strncmp(upm2->partIdent.ident,
                                                UDF_ID_METADATA,
                                                strlen(UDF_ID_METADATA))) {
@@ -2000,6 +2003,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                        if (!silent)
                                pr_notice("Rescanning with blocksize %d\n",
                                          UDF_DEFAULT_BLOCKSIZE);
+                       brelse(sbi->s_lvid_bh);
+                       sbi->s_lvid_bh = NULL;
                        uopt.blocksize = UDF_DEFAULT_BLOCKSIZE;
                        ret = udf_load_vrs(sb, &uopt, silent, &fileset);
                }
index f9c3fe304a17fc9ae470c7754294b3f129c78bea..69cf4fcde03e2d31266f70f6dfee1b73fe71b4a7 100644 (file)
@@ -179,12 +179,14 @@ xfs_ioc_trim(
         * used by the fstrim application.  In the end it really doesn't
         * matter as trimming blocks is an advisory interface.
         */
+       if (range.start >= XFS_FSB_TO_B(mp, mp->m_sb.sb_dblocks) ||
+           range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp)))
+               return -XFS_ERROR(EINVAL);
+
        start = BTOBB(range.start);
        end = start + BTOBBT(range.len) - 1;
        minlen = BTOBB(max_t(u64, granularity, range.minlen));
 
-       if (XFS_BB_TO_FSB(mp, start) >= mp->m_sb.sb_dblocks)
-               return -XFS_ERROR(EINVAL);
        if (end > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1)
                end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)- 1;
 
index 21e37b55f7e596c6d29c0c0125a755f7a8ada7f6..5aceb3f8ecd625de029daaff00e6093a0e0213a2 100644 (file)
@@ -962,23 +962,22 @@ xfs_dialloc(
                if (!pag->pagi_freecount && !okalloc)
                        goto nextag;
 
+               /*
+                * Then read in the AGI buffer and recheck with the AGI buffer
+                * lock held.
+                */
                error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
                if (error)
                        goto out_error;
 
-               /*
-                * Once the AGI has been read in we have to recheck
-                * pagi_freecount with the AGI buffer lock held.
-                */
                if (pag->pagi_freecount) {
                        xfs_perag_put(pag);
                        goto out_alloc;
                }
 
-               if (!okalloc) {
-                       xfs_trans_brelse(tp, agbp);
-                       goto nextag;
-               }
+               if (!okalloc)
+                       goto nextag_relse_buffer;
+
 
                error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced);
                if (error) {
@@ -1007,6 +1006,8 @@ xfs_dialloc(
                        return 0;
                }
 
+nextag_relse_buffer:
+               xfs_trans_brelse(tp, agbp);
 nextag:
                xfs_perag_put(pag);
                if (++agno == mp->m_sb.sb_agcount)
index 92d4331cd4f1c118ea0a0087849d399a3948f230..ca28a4ba4b548f0c379291bfb0e716ac3a9ec54e 100644 (file)
@@ -857,7 +857,7 @@ xfs_rtbuf_get(
        xfs_buf_t       *bp;            /* block buffer, result */
        xfs_inode_t     *ip;            /* bitmap or summary inode */
        xfs_bmbt_irec_t map;
-       int             nmap;
+       int             nmap = 1;
        int             error;          /* error value */
 
        ip = issum ? mp->m_rsumip : mp->m_rbmip;
index 2c744c7a5b3dcdd452d1c531884faa0ed0a3e29b..26a92fc28a590ce68a198b326632835f46cda1d9 100644 (file)
@@ -491,11 +491,11 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b);
 
 acpi_status acpi_enter_sleep_state_prep(u8 sleep_state);
 
-acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags);
+acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state);
 
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void))
 
-acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags);
+acpi_status acpi_leave_sleep_state_prep(u8 sleep_state);
 
 acpi_status acpi_leave_sleep_state(u8 sleep_state);
 
index 3af87de6a68cd1a9afbcf21aaa4a47151158416e..3d00bd5bd7e30bdfb11689512f7e502d22d4ab71 100644 (file)
@@ -803,7 +803,7 @@ typedef u8 acpi_adr_space_type;
 
 /* Sleep function dispatch */
 
-typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state, u8 flags);
+typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state);
 
 struct acpi_sleep_functions {
        ACPI_SLEEP_FUNCTION legacy_function;
index 580a6d35c70078bd91bff6619860b5159b7130b2..c04e0db8a2d6df273472a04bfb882aecdc0d54ce 100644 (file)
@@ -26,7 +26,13 @@ static inline void
 __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
        if (unlikely(atomic_xchg(count, 0) != 1))
-               fail_fn(count);
+               /*
+                * We failed to acquire the lock, so mark it contended
+                * to ensure that any waiting tasks are woken up by the
+                * unlock slow path.
+                */
+               if (likely(atomic_xchg(count, -1) != 1))
+                       fail_fn(count);
 }
 
 /**
@@ -43,7 +49,8 @@ static inline int
 __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 {
        if (unlikely(atomic_xchg(count, 0) != 1))
-               return fail_fn(count);
+               if (likely(atomic_xchg(count, -1) != 1))
+                       return fail_fn(count);
        return 0;
 }
 
index a1a0386e0160d9278f6b74e213f26915a87551af..bfacf0d5a225fd0dd4c9a52d42496f3e7049a030 100644 (file)
@@ -118,7 +118,8 @@ enum drm_mode_status {
        .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
        .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
        .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
-       .vscan = (vs), .flags = (f), .vrefresh = 0
+       .vscan = (vs), .flags = (f), .vrefresh = 0, \
+       .base.type = DRM_MODE_OBJECT_MODE
 
 #define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */
 
@@ -166,8 +167,6 @@ struct drm_display_mode {
        int crtc_vsync_start;
        int crtc_vsync_end;
        int crtc_vtotal;
-       int crtc_hadjusted;
-       int crtc_vadjusted;
 
        /* Driver private mode info */
        int private_size;
index 5581980b14f606e593e9827e175980e5a50802f0..3d6301b6ec16d36b60cb4f69570170b8c804fb6d 100644 (file)
@@ -359,8 +359,9 @@ struct drm_mode_mode_cmd {
        struct drm_mode_modeinfo mode;
 };
 
-#define DRM_MODE_CURSOR_BO     (1<<0)
-#define DRM_MODE_CURSOR_MOVE   (1<<1)
+#define DRM_MODE_CURSOR_BO     0x01
+#define DRM_MODE_CURSOR_MOVE   0x02
+#define DRM_MODE_CURSOR_FLAGS  0x03
 
 /*
  * depending on the value in flags different members are used.
index 7ff5c99b16389330e21110a8c43b3b8877484f82..c78bb997e2c60846a1f5e261664d96ee1656fe6d 100644 (file)
        {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6806, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
index 58056865b8e9601bc40da73198a82d0bcb406960..dc3a8cd7db8a0741ff5b4478476e8d0e3d566b9c 100644 (file)
@@ -964,6 +964,8 @@ struct drm_radeon_cs {
 #define RADEON_INFO_IB_VM_MAX_SIZE     0x0f
 /* max pipes - needed for compute shaders */
 #define RADEON_INFO_MAX_PIPES          0x10
+/* timestamp for GL_ARB_timer_query (OpenGL), returns the current GPU clock */
+#define RADEON_INFO_TIMESTAMP          0x11
 
 struct drm_radeon_info {
        uint32_t                request;
index d9a7544748785d020ba77f74392fb1275fbe02fd..fa217607c582e7feb5cf1ef301b1659f7b9db1ff 100644 (file)
@@ -391,6 +391,7 @@ header-y += v4l2-dv-timings.h
 header-y += v4l2-mediabus.h
 header-y += v4l2-subdev.h
 header-y += veth.h
+header-y += vfio.h
 header-y += vhost.h
 header-y += videodev2.h
 header-y += virtio_9p.h
index 3ad510b25283ee1e5285929b702d739fb0afc31a..4f2a76224509ef5c652a8503153ca73435b9dde1 100644 (file)
@@ -96,7 +96,7 @@ void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
 void acpi_numa_slit_init (struct acpi_table_slit *slit);
 void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
 void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
-void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
+int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
 void acpi_numa_arch_fixup(void);
 
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
index c97c6b9cd38ee34e501735758de2b710decceae0..2a9a9abc91260c09a7940136a965a08209c5828b 100644 (file)
@@ -124,7 +124,6 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
 void bdi_start_background_writeback(struct backing_dev_info *bdi);
 int bdi_writeback_thread(void *data);
 int bdi_has_dirty_io(struct backing_dev_info *bdi);
-void bdi_arm_supers_timer(void);
 void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi);
 void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2);
 
index 3c80885fa829dcb6fe60616b9aba6e85bea550fb..d323a4b4143c6e2d1f43b4a82e459fad157d5f04 100644 (file)
 #define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
 #define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
 #define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
+#define  BCMA_CC_CHIPST_43228_ILP_DIV_EN       0x00000001
+#define  BCMA_CC_CHIPST_43228_OTP_PRESENT      0x00000002
+#define  BCMA_CC_CHIPST_43228_SERDES_REFCLK_PADSEL     0x00000004
+#define  BCMA_CC_CHIPST_43228_SDIO_MODE                0x00000008
+#define  BCMA_CC_CHIPST_43228_SDIO_OTP_PRESENT 0x00000010
+#define  BCMA_CC_CHIPST_43228_SDIO_RESET       0x00000020
 #define  BCMA_CC_CHIPST_4706_PKG_OPTION                BIT(0) /* 0: full-featured package 1: low-cost package */
 #define  BCMA_CC_CHIPST_4706_SFLASH_PRESENT    BIT(1) /* 0: parallel, 1: serial flash is present */
 #define  BCMA_CC_CHIPST_4706_SFLASH_TYPE       BIT(2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */
index 4e72a9d48232d513b5b2fe44d973de8dfeb1e9e4..4a2ab7c85393df48fd8d93e085f3b7ead5de7be2 100644 (file)
@@ -601,7 +601,7 @@ static inline void blk_clear_rl_full(struct request_list *rl, bool sync)
  * it already be started by driver.
  */
 #define RQ_NOMERGE_FLAGS       \
-       (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
+       (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_DISCARD)
 #define rq_mergeable(rq)       \
        (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \
         (((rq)->cmd_flags & REQ_DISCARD) || \
@@ -894,6 +894,8 @@ extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable);
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
 
 extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
+extern int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
+                         struct scatterlist *sglist);
 extern void blk_dump_rq_flags(struct request *, char *);
 extern long nr_blockdev_pages(void);
 
@@ -1139,6 +1141,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector
                & (lim->discard_granularity - 1);
 }
 
+static inline int bdev_discard_alignment(struct block_device *bdev)
+{
+       struct request_queue *q = bdev_get_queue(bdev);
+
+       if (bdev != bdev->bd_contains)
+               return bdev->bd_part->discard_alignment;
+
+       return q->limits.discard_alignment;
+}
+
 static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
 {
        if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)
index 018055efc0343b2a8f7e800255ff53b9e10a3584..e52958d7c2d119cb416587466f4a4d2a5bb1e8d0 100644 (file)
@@ -74,20 +74,21 @@ struct can_frame {
 /*
  * defined bits for canfd_frame.flags
  *
- * As the default for CAN FD should be to support the high data rate in the
- * payload section of the frame (HDR) and to support up to 64 byte in the
- * data section (EDL) the bits are only set in the non-default case.
- * Btw. as long as there's no real implementation for CAN FD network driver
- * these bits are only preliminary.
+ * The use of struct canfd_frame implies the Extended Data Length (EDL) bit to
+ * be set in the CAN frame bitstream on the wire. The EDL bit switch turns
+ * the CAN controllers bitstream processor into the CAN FD mode which creates
+ * two new options within the CAN FD frame specification:
  *
- * RX: NOHDR/NOEDL - info about received CAN FD frame
- *     ESI         - bit from originating CAN controller
- * TX: NOHDR/NOEDL - control per-frame settings if supported by CAN controller
- *     ESI         - bit is set by local CAN controller
+ * Bit Rate Switch - to indicate a second bitrate is/was used for the payload
+ * Error State Indicator - represents the error state of the transmitting node
+ *
+ * As the CANFD_ESI bit is internally generated by the transmitting CAN
+ * controller only the CANFD_BRS bit is relevant for real CAN controllers when
+ * building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
+ * sense for virtual CAN interfaces to test applications with echoed frames.
  */
-#define CANFD_NOHDR 0x01 /* frame without high data rate */
-#define CANFD_NOEDL 0x02 /* frame without extended data length */
-#define CANFD_ESI   0x04 /* error state indicator */
+#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
+#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
 
 /**
  * struct canfd_frame - CAN flexible data rate frame structure
index 133ddcf83397036a5c20ed6431db3b789eeab37a..ef658147e4e8391eec61aa7559a1452fcffe6a79 100644 (file)
@@ -22,7 +22,7 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write,
 extern int fragmentation_index(struct zone *zone, unsigned int order);
 extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *mask,
-                       bool sync);
+                       bool sync, bool *contended);
 extern int compact_pgdat(pg_data_t *pgdat, int order);
 extern unsigned long compaction_suitable(struct zone *zone, int order);
 
@@ -64,7 +64,7 @@ static inline bool compaction_deferred(struct zone *zone, int order)
 #else
 static inline unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *nodemask,
-                       bool sync)
+                       bool sync, bool *contended)
 {
        return COMPACT_CONTINUE;
 }
index 040b13b5c14a5bdc500f82855123e7940fda6f6f..279b1eaa8b7304bf1028b6f91acedf4f15317148 100644 (file)
@@ -194,6 +194,10 @@ static inline int cpuidle_play_dead(void) {return -ENODEV; }
 
 #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
 void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
+#else
+static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
+{
+}
 #endif
 
 /******************************
index 103adc6d7e3a740dc72cb9f47caa0def680fe1f9..ec45ccd8708a85f54a903d769b0b5c2fbaf8bc3f 100644 (file)
@@ -503,6 +503,8 @@ extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size);
 extern int __init efi_uart_console_only (void);
 extern void efi_initialize_iomem_resources(struct resource *code_resource,
                struct resource *data_resource, struct resource *bss_resource);
+extern unsigned long efi_get_time(void);
+extern int efi_set_rtc_mmss(unsigned long nowtime);
 extern void efi_reserve_boot_services(void);
 extern struct efi_memory_map memmap;
 
index 38dba16c417646ff28f9ea78dea28a268d65d125..aa110476a95be0b1d479555346c560d45ecc0b20 100644 (file)
@@ -1491,7 +1491,6 @@ struct sb_writers {
 struct super_block {
        struct list_head        s_list;         /* Keep this first */
        dev_t                   s_dev;          /* search index; _not_ kdev_t */
-       unsigned char           s_dirt;
        unsigned char           s_blocksize_bits;
        unsigned long           s_blocksize;
        loff_t                  s_maxbytes;     /* Max file size */
@@ -1861,7 +1860,6 @@ struct super_operations {
        int (*drop_inode) (struct inode *);
        void (*evict_inode) (struct inode *);
        void (*put_super) (struct super_block *);
-       void (*write_super) (struct super_block *);
        int (*sync_fs)(struct super_block *sb, int wait);
        int (*freeze_fs) (struct super_block *);
        int (*unfreeze_fs) (struct super_block *);
@@ -2397,7 +2395,6 @@ extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
                           int datasync);
 extern int vfs_fsync(struct file *file, int datasync);
 extern int generic_write_sync(struct file *file, loff_t pos, loff_t count);
-extern void sync_supers(void);
 extern void emergency_sync(void);
 extern void emergency_remount(void);
 #ifdef CONFIG_BLOCK
index af961d6f7ab14edc6b3a0c8ec813124fba5415da..642928cf57b4b47672c6fd18552b3fd3e114153e 100644 (file)
@@ -306,9 +306,10 @@ extern void *perf_trace_buf_prepare(int size, unsigned short type,
 
 static inline void
 perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr,
-                      u64 count, struct pt_regs *regs, void *head)
+                      u64 count, struct pt_regs *regs, void *head,
+                      struct task_struct *task)
 {
-       perf_tp_event(addr, count, raw_data, size, regs, head, rctx);
+       perf_tp_event(addr, count, raw_data, size, regs, head, rctx, task);
 }
 #endif
 
index 9303348965fbdbc8a8d6d706949b543d54c5609b..d8c713e148e3a5c15fc166e507fe811210872027 100644 (file)
@@ -57,6 +57,9 @@
  *
  * 7.19
  *  - add FUSE_FALLOCATE
+ *
+ * 7.20
+ *  - add FUSE_AUTO_INVAL_DATA
  */
 
 #ifndef _LINUX_FUSE_H
@@ -88,7 +91,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 19
+#define FUSE_KERNEL_MINOR_VERSION 20
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -163,10 +166,19 @@ struct fuse_file_lock {
 /**
  * INIT request/reply flags
  *
+ * FUSE_ASYNC_READ: asynchronous read requests
  * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
+ * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported)
+ * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem
  * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
+ * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
  * FUSE_DONT_MASK: don't apply umask to file mode on create operations
+ * FUSE_SPLICE_WRITE: kernel supports splice write on the device
+ * FUSE_SPLICE_MOVE: kernel supports splice move on the device
+ * FUSE_SPLICE_READ: kernel supports splice read on the device
  * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
+ * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
+ * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
@@ -175,7 +187,12 @@ struct fuse_file_lock {
 #define FUSE_EXPORT_SUPPORT    (1 << 4)
 #define FUSE_BIG_WRITES                (1 << 5)
 #define FUSE_DONT_MASK         (1 << 6)
+#define FUSE_SPLICE_WRITE      (1 << 7)
+#define FUSE_SPLICE_MOVE       (1 << 8)
+#define FUSE_SPLICE_READ       (1 << 9)
 #define FUSE_FLOCK_LOCKS       (1 << 10)
+#define FUSE_HAS_IOCTL_DIR     (1 << 11)
+#define FUSE_AUTO_INVAL_DATA   (1 << 12)
 
 /**
  * CUSE INIT request/reply flags
index bb7f30971858ca5127de592cdaa0cec227935384..305f23cd7cff53f3ef97794db7d6aa7dde6035c6 100644 (file)
@@ -22,7 +22,7 @@
  *
  * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024)
  * - bit 26 is the NMI_MASK
- * - bit 28 is the PREEMPT_ACTIVE flag
+ * - bit 27 is the PREEMPT_ACTIVE flag
  *
  * PREEMPT_MASK: 0x000000ff
  * SOFTIRQ_MASK: 0x0000ff00
index 6960fc1841a7adc3bd42ff5b9a2221b78f2b9eb2..aa2e167e1ef434a696a55322bd941bdb3983bf50 100644 (file)
@@ -96,21 +96,6 @@ static inline void team_netpoll_send_skb(struct team_port *port,
 }
 #endif
 
-static inline int team_dev_queue_xmit(struct team *team, struct team_port *port,
-                                     struct sk_buff *skb)
-{
-       BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
-                    sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
-       skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping);
-
-       skb->dev = port->dev;
-       if (unlikely(netpoll_tx_running(port->dev))) {
-               team_netpoll_send_skb(port, skb);
-               return 0;
-       }
-       return dev_queue_xmit(skb);
-}
-
 struct team_mode_ops {
        int (*init)(struct team *team);
        void (*exit)(struct team *team);
@@ -200,6 +185,21 @@ struct team {
        long mode_priv[TEAM_MODE_PRIV_LONGS];
 };
 
+static inline int team_dev_queue_xmit(struct team *team, struct team_port *port,
+                                     struct sk_buff *skb)
+{
+       BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
+                    sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
+       skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping);
+
+       skb->dev = port->dev;
+       if (unlikely(netpoll_tx_running(team->dev))) {
+               team_netpoll_send_skb(port, skb);
+               return 0;
+       }
+       return dev_queue_xmit(skb);
+}
+
 static inline struct hlist_head *team_port_index_hash(struct team *team,
                                                      int port_index)
 {
index b76b4a87065e3615cbfc1b17e81b9fd90bcf8898..be91f344d5fce1b3b8a41ff149ece8b917715542 100644 (file)
@@ -87,6 +87,8 @@
 #define ADF4350_MAX_BANDSEL_CLK                125000 /* Hz */
 #define ADF4350_MAX_FREQ_REFIN         250000000 /* Hz */
 #define ADF4350_MAX_MODULUS            4095
+#define ADF4350_MAX_R_CNT              1023
+
 
 /**
  * struct adf4350_platform_data - platform specific information
index f875b316249d257ce2f56e7243e4463c9d4994e2..16625d799b6fc1ca85f89d5d9f81415332c8e86e 100644 (file)
@@ -2,6 +2,7 @@
 #define LINUX_INPUT_EETI_TS_H
 
 struct eeti_ts_platform_data {
+       int irq_gpio;
        unsigned int irq_active_high;
 };
 
index 54d6d690073c1cb5119671b99df70af3ddfc615d..7e83370e6fd2b134691e7fa348529e70d0a1ae56 100644 (file)
@@ -20,6 +20,7 @@
 #define __LINUX_IOMMU_H
 
 #include <linux/errno.h>
+#include <linux/types.h>
 
 #define IOMMU_READ     (1)
 #define IOMMU_WRITE    (2)
@@ -30,6 +31,7 @@ struct iommu_group;
 struct bus_type;
 struct device;
 struct iommu_domain;
+struct notifier_block;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ       0x0
index 379e433e15e0fc97fc3f376b610f12ff77f694ae..879db26ec4013297fb76f16143b87ec9db52b5e4 100644 (file)
@@ -369,6 +369,7 @@ struct ipv6_pinfo {
        __u8                    rcv_tclass;
 
        __u32                   dst_cookie;
+       __u32                   rx_dst_cookie;
 
        struct ipv6_mc_socklist __rcu *ipv6_mc_list;
        struct ipv6_ac_socklist *ipv6_ac_list;
index 553fb66da130a3a9b3700958c5cce22a6b5cda73..216b0ba109d72f453836568e1aa6c7b7c85e21a6 100644 (file)
@@ -349,6 +349,7 @@ enum {
        IRQCHIP_MASK_ON_SUSPEND         = (1 <<  2),
        IRQCHIP_ONOFFLINE_ENABLED       = (1 <<  3),
        IRQCHIP_SKIP_SET_WAKE           = (1 <<  4),
+       IRQCHIP_ONESHOT_SAFE            = (1 <<  5),
 };
 
 /* This include will go away once we isolated irq_desc usage to core code */
index f334c7fab96762ab4131c9886df87d4d6d4dde9d..3efc43f3f162c3427099cb31fdafd5c1e5d226de 100644 (file)
@@ -1125,6 +1125,7 @@ extern int           jbd2_journal_destroy    (journal_t *);
 extern int        jbd2_journal_recover    (journal_t *journal);
 extern int        jbd2_journal_wipe       (journal_t *, int);
 extern int        jbd2_journal_skip_recovery   (journal_t *);
+extern void       jbd2_journal_update_sb_errno(journal_t *);
 extern void       jbd2_journal_update_sb_log_tail      (journal_t *, tid_t,
                                unsigned long, int);
 extern void       __jbd2_journal_abort_hard    (journal_t *);
index 265e2c3cbd1cd74d2b3efd416aa9301c90ae90ad..82680541576d2f2d307ba9bfb1847681f290f49b 100644 (file)
@@ -39,9 +39,6 @@
 # error Invalid value of HZ.
 #endif
 
-/* LATCH is used in the interval timer and ftape setup. */
-#define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
-
 /* Suppose we want to divide two numbers NOM and DEN: NOM/DEN, then we can
  * improve accuracy by shifting LSH bits, hence calculating:
  *     (NOM << LSH) / DEN
 #define SH_DIV(NOM,DEN,LSH) (   (((NOM) / (DEN)) << (LSH))              \
                              + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN))
 
-/* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */
-#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))
+#ifdef CLOCK_TICK_RATE
+/* LATCH is used in the interval timer and ftape setup. */
+# define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
+
+/*
+ * HZ is the requested value. However the CLOCK_TICK_RATE may not allow
+ * for exactly HZ. So SHIFTED_HZ is high res HZ ("<< 8" is for accuracy)
+ */
+# define SHIFTED_HZ (SH_DIV(CLOCK_TICK_RATE, LATCH, 8))
+#else
+# define SHIFTED_HZ (HZ << 8)
+#endif
 
-/* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */
-#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))
+/* TICK_NSEC is the time between ticks in nsec assuming SHIFTED_HZ */
+#define TICK_NSEC (SH_DIV(1000000UL * 1000, SHIFTED_HZ, 8))
 
 /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */
 #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
 
-/* TICK_USEC_TO_NSEC is the time between ticks in nsec assuming real ACTHZ and */
-/* a value TUSEC for TICK_USEC (can be set bij adjtimex)               */
-#define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8))
+/*
+ * TICK_USEC_TO_NSEC is the time between ticks in nsec assuming SHIFTED_HZ and
+ * a value TUSEC for TICK_USEC (can be set bij adjtimex)
+ */
+#define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV(TUSEC * USER_HZ * 1000, SHIFTED_HZ, 8))
 
 /* some arch's have a small-data section that can be accessed register-relative
  * but that can only take up to, say, 4-byte variables. jiffies being part of
index 064725854db8c7eff3c5a38a093aec190a6c6c7f..42d9e863a3139ad953c23f53ef36f4cc19182dd8 100644 (file)
@@ -75,8 +75,6 @@ extern const char *kdb_diemsg;
 #define KDB_FLAG_CATASTROPHIC  (1 << 1) /* A catastrophic event has occurred */
 #define KDB_FLAG_CMD_INTERRUPT (1 << 2) /* Previous command was interrupted */
 #define KDB_FLAG_NOIPI         (1 << 3) /* Do not send IPIs */
-#define KDB_FLAG_ONLY_DO_DUMP  (1 << 4) /* Only do a dump, used when
-                                         * kdb is off */
 #define KDB_FLAG_NO_CONSOLE    (1 << 5) /* No console is available,
                                          * kdb is disabled */
 #define KDB_FLAG_NO_VT_CONSOLE (1 << 6) /* No VT console is available, do
index 9c07dcebded747493041c8e6a5c18d68bc43fabf..65af6887872f1e62d51afa7381ac3b790a302182 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/bug.h>
 #include <linux/atomic.h>
 #include <linux/kernel.h>
+#include <linux/mutex.h>
 
 struct kref {
        atomic_t refcount;
@@ -93,4 +94,21 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)
 {
        return kref_sub(kref, 1, release);
 }
+
+static inline int kref_put_mutex(struct kref *kref,
+                                void (*release)(struct kref *kref),
+                                struct mutex *lock)
+{
+       WARN_ON(release == NULL);
+        if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) {
+               mutex_lock(lock);
+               if (unlikely(!atomic_dec_and_test(&kref->refcount))) {
+                       mutex_unlock(lock);
+                       return 0;
+               }
+               release(kref);
+               return 1;
+       }
+       return 0;
+}
 #endif /* _KREF_H_ */
index 603bec2913b00ca40086149828f3fcddab32a435..06177ba10a1617461dbe6803efc22ba6dfb43304 100644 (file)
@@ -58,13 +58,6 @@ union ktime {
 
 typedef union ktime ktime_t;           /* Kill this */
 
-#define KTIME_MAX                      ((s64)~((u64)1 << 63))
-#if (BITS_PER_LONG == 64)
-# define KTIME_SEC_MAX                 (KTIME_MAX / NSEC_PER_SEC)
-#else
-# define KTIME_SEC_MAX                 LONG_MAX
-#endif
-
 /*
  * ktime_t definitions when using the 64-bit scalar representation:
  */
index 40c372165f3edc0413a709c57c4e728bd0198ca5..32a1b5cfeba1f426547127233c84732363fc4e30 100644 (file)
@@ -16,6 +16,7 @@ struct pcap_subdev {
 struct pcap_platform_data {
        unsigned int irq_base;
        unsigned int config;
+       int gpio;
        void (*init) (void *);  /* board specific init */
        int num_subdevs;
        struct pcap_subdev *subdevs;
index 51bf8ada6dc0166b103c4d11067d92fbb2496d78..49258e0ed1c679e4dfacc488b8e94aa49e7d815e 100644 (file)
@@ -15,6 +15,8 @@
 #define MV643XX_ETH_SIZE_REG_4         0x2224
 #define MV643XX_ETH_BASE_ADDR_ENABLE_REG       0x2290
 
+#define MV643XX_TX_CSUM_DEFAULT_LIMIT  0
+
 struct mv643xx_eth_shared_platform_data {
        struct mbus_dram_target_info    *dram;
        struct platform_device  *shared_smi;
index eb06e58bed0b2dc9c7e2d6a9b166d69380556e58..59dc05f382475d67d5d4326c852f3b7d49332e3b 100644 (file)
@@ -953,7 +953,8 @@ struct net_device_ops {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        void                    (*ndo_poll_controller)(struct net_device *dev);
        int                     (*ndo_netpoll_setup)(struct net_device *dev,
-                                                    struct netpoll_info *info);
+                                                    struct netpoll_info *info,
+                                                    gfp_t gfp);
        void                    (*ndo_netpoll_cleanup)(struct net_device *dev);
 #endif
        int                     (*ndo_set_vf_mac)(struct net_device *dev,
@@ -1300,6 +1301,8 @@ struct net_device {
        /* for setting kernel sock attribute on TCP connection setup */
 #define GSO_MAX_SIZE           65536
        unsigned int            gso_max_size;
+#define GSO_MAX_SEGS           65535
+       u16                     gso_max_segs;
 
 #ifdef CONFIG_DCB
        /* Data Center Bridging netlink ops */
@@ -1519,6 +1522,8 @@ struct packet_type {
        struct sk_buff          **(*gro_receive)(struct sk_buff **head,
                                               struct sk_buff *skb);
        int                     (*gro_complete)(struct sk_buff *skb);
+       bool                    (*id_match)(struct packet_type *ptype,
+                                           struct sock *sk);
        void                    *af_packet_priv;
        struct list_head        list;
 };
index 0dfc8b7210a3c3df26d582aef6399c65ab1c0519..89f2a627f3f086febbcf1a93ab0fe9f42b6eac30 100644 (file)
@@ -164,7 +164,7 @@ extern int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr
                                      unsigned int dataoff, unsigned int datalen,
                                      const char *name,
                                      unsigned int *matchoff, unsigned int *matchlen,
-                                     union nf_inet_addr *addr);
+                                     union nf_inet_addr *addr, bool delim);
 extern int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
                                        unsigned int off, unsigned int datalen,
                                        const char *name,
index 28f5389c924b51b76cf88dc5da1af7f3a0853138..66d5379c305e60d17dcde8b60d286f0b57b23a16 100644 (file)
@@ -23,6 +23,7 @@ struct netpoll {
        u8 remote_mac[ETH_ALEN];
 
        struct list_head rx; /* rx_np list element */
+       struct rcu_head rcu;
 };
 
 struct netpoll_info {
@@ -38,28 +39,40 @@ struct netpoll_info {
        struct delayed_work tx_work;
 
        struct netpoll *netpoll;
+       struct rcu_head rcu;
 };
 
 void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
 void netpoll_print_options(struct netpoll *np);
 int netpoll_parse_options(struct netpoll *np, char *opt);
-int __netpoll_setup(struct netpoll *np, struct net_device *ndev);
+int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp);
 int netpoll_setup(struct netpoll *np);
 int netpoll_trap(void);
 void netpoll_set_trap(int trap);
 void __netpoll_cleanup(struct netpoll *np);
+void __netpoll_free_rcu(struct netpoll *np);
 void netpoll_cleanup(struct netpoll *np);
-int __netpoll_rx(struct sk_buff *skb);
+int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo);
 void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
                             struct net_device *dev);
 static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
 {
+       unsigned long flags;
+       local_irq_save(flags);
        netpoll_send_skb_on_dev(np, skb, np->dev);
+       local_irq_restore(flags);
 }
 
 
 
 #ifdef CONFIG_NETPOLL
+static inline bool netpoll_rx_on(struct sk_buff *skb)
+{
+       struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo);
+
+       return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags);
+}
+
 static inline bool netpoll_rx(struct sk_buff *skb)
 {
        struct netpoll_info *npinfo;
@@ -67,14 +80,14 @@ static inline bool netpoll_rx(struct sk_buff *skb)
        bool ret = false;
 
        local_irq_save(flags);
-       npinfo = rcu_dereference_bh(skb->dev->npinfo);
 
-       if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags))
+       if (!netpoll_rx_on(skb))
                goto out;
 
+       npinfo = rcu_dereference_bh(skb->dev->npinfo);
        spin_lock(&npinfo->rx_lock);
        /* check rx_flags again with the lock held */
-       if (npinfo->rx_flags && __netpoll_rx(skb))
+       if (npinfo->rx_flags && __netpoll_rx(skb, npinfo))
                ret = true;
        spin_unlock(&npinfo->rx_lock);
 
@@ -83,13 +96,6 @@ out:
        return ret;
 }
 
-static inline int netpoll_rx_on(struct sk_buff *skb)
-{
-       struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo);
-
-       return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags);
-}
-
 static inline int netpoll_receive_skb(struct sk_buff *skb)
 {
        if (!list_empty(&skb->dev->napi_list))
@@ -119,7 +125,7 @@ static inline void netpoll_poll_unlock(void *have)
        }
 }
 
-static inline int netpoll_tx_running(struct net_device *dev)
+static inline bool netpoll_tx_running(struct net_device *dev)
 {
        return irqs_disabled();
 }
@@ -127,11 +133,11 @@ static inline int netpoll_tx_running(struct net_device *dev)
 #else
 static inline bool netpoll_rx(struct sk_buff *skb)
 {
-       return 0;
+       return false;
 }
-static inline int netpoll_rx_on(struct sk_buff *skb)
+static inline bool netpoll_rx_on(struct sk_buff *skb)
 {
-       return 0;
+       return false;
 }
 static inline int netpoll_receive_skb(struct sk_buff *skb)
 {
@@ -147,9 +153,9 @@ static inline void netpoll_poll_unlock(void *have)
 static inline void netpoll_netdev_init(struct net_device *dev)
 {
 }
-static inline int netpoll_tx_running(struct net_device *dev)
+static inline bool netpoll_tx_running(struct net_device *dev)
 {
-       return 0;
+       return false;
 }
 #endif
 
index 880805774f9f105425a7eade9721b9965f7d43c9..92ce5783b707df8ea90306aaf145f1fbba3d02a2 100644 (file)
@@ -69,6 +69,7 @@ struct nfs_pageio_descriptor {
        const struct nfs_pgio_completion_ops *pg_completion_ops;
        struct pnfs_layout_segment *pg_lseg;
        struct nfs_direct_req   *pg_dreq;
+       void                    *pg_layout_private;
 };
 
 #define NFS_WBACK_BUSY(req)    (test_bit(PG_BUSY,&(req)->wb_flags))
index 00485e084394d4ca1a5782b3cd54fc63e9b06acd..ac7c8ae254f251933e48f04d5c877eaaa3ec6e09 100644 (file)
@@ -1248,6 +1248,7 @@ struct nfs_pgio_header {
        void (*release) (struct nfs_pgio_header *hdr);
        const struct nfs_pgio_completion_ops *completion_ops;
        struct nfs_direct_req   *dreq;
+       void                    *layout_private;
        spinlock_t              lock;
        /* fields protected by lock */
        int                     pnfs_error;
index 5919ee33f2b7b2d930fa3f6dd877984be5ed5e0d..1b1163225f3b8ab1eafacbb21e83ab8f86d50d42 100644 (file)
@@ -190,10 +190,17 @@ extern struct device_node *of_get_parent(const struct device_node *node);
 extern struct device_node *of_get_next_parent(struct device_node *node);
 extern struct device_node *of_get_next_child(const struct device_node *node,
                                             struct device_node *prev);
+extern struct device_node *of_get_next_available_child(
+       const struct device_node *node, struct device_node *prev);
+
 #define for_each_child_of_node(parent, child) \
        for (child = of_get_next_child(parent, NULL); child != NULL; \
             child = of_get_next_child(parent, child))
 
+#define for_each_available_child_of_node(parent, child) \
+       for (child = of_get_next_available_child(parent, NULL); child != NULL; \
+            child = of_get_next_available_child(parent, child))
+
 static inline int of_get_child_count(const struct device_node *np)
 {
        struct device_node *child;
index 76c5c8b724a77253e3ca635c90e53ed6230b3c5f..7602ccb3f40ec672001be2eae9be3395604493f2 100644 (file)
@@ -1272,7 +1272,8 @@ static inline bool perf_paranoid_kernel(void)
 extern void perf_event_init(void);
 extern void perf_tp_event(u64 addr, u64 count, void *record,
                          int entry_size, struct pt_regs *regs,
-                         struct hlist_head *head, int rctx);
+                         struct hlist_head *head, int rctx,
+                         struct task_struct *task);
 extern void perf_bp_event(struct perf_event *event, void *data);
 
 #ifndef perf_misc_flags
index 6dd96fb45482b00b0ede76c92f83fc6bd76f0f2f..e9b7f4350844435daf050bd539de04d44fe4b6fa 100644 (file)
@@ -20,6 +20,7 @@
 /* This struct is private to the core and should be regarded as a cookie */
 struct pinctrl;
 struct pinctrl_state;
+struct device;
 
 #ifdef CONFIG_PINCTRL
 
index c147e7024f11f2859d8f648b1abac437bac941f1..b8c86648a2f95dc6f83aab668fd9a7e07f277b4e 100644 (file)
@@ -334,14 +334,6 @@ static inline void lockup_detector_init(void)
 }
 #endif
 
-#if defined(CONFIG_LOCKUP_DETECTOR) && defined(CONFIG_SUSPEND)
-void lockup_detector_bootcpu_resume(void);
-#else
-static inline void lockup_detector_bootcpu_resume(void)
-{
-}
-#endif
-
 #ifdef CONFIG_DETECT_HUNG_TASK
 extern unsigned int  sysctl_hung_task_panic;
 extern unsigned long sysctl_hung_task_check_count;
index 4e5a73cdbbef18463920022626931d02c0540eb9..3dea6a9d568f416ccd1b704eec1d4bff9dea6d90 100644 (file)
@@ -1242,8 +1242,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     Check that the @parent process has sufficient permission to trace the
  *     current process before allowing the current process to present itself
  *     to the @parent process for tracing.
- *     The parent process will still have to undergo the ptrace_access_check
- *     checks before it is allowed to trace this one.
  *     @parent contains the task_struct structure for debugger process.
  *     Return 0 if permission is granted.
  * @capget:
index ffe0442e18d2f4e2d7b8d8eb8f22ffbc532e67e4..b9178812d9df5f703b2e2126f1a4df2669f083cc 100644 (file)
@@ -144,8 +144,8 @@ static inline bool strstarts(const char *str, const char *prefix)
 {
        return strncmp(str, prefix, strlen(prefix)) == 0;
 }
-#endif
 
 extern size_t memweight(const void *ptr, size_t bytes);
 
+#endif /* __KERNEL__ */
 #endif /* _LINUX_STRING_H_ */
index c81c5e40fcb512dda61255ac7399fb818bcb0cec..b51e664c83e7237e17e02f0b5752ce586f87dbd4 100644 (file)
@@ -107,11 +107,36 @@ static inline struct timespec timespec_sub(struct timespec lhs,
        return ts_delta;
 }
 
+#define KTIME_MAX                      ((s64)~((u64)1 << 63))
+#if (BITS_PER_LONG == 64)
+# define KTIME_SEC_MAX                 (KTIME_MAX / NSEC_PER_SEC)
+#else
+# define KTIME_SEC_MAX                 LONG_MAX
+#endif
+
 /*
  * Returns true if the timespec is norm, false if denorm:
  */
-#define timespec_valid(ts) \
-       (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
+static inline bool timespec_valid(const struct timespec *ts)
+{
+       /* Dates before 1970 are bogus */
+       if (ts->tv_sec < 0)
+               return false;
+       /* Can't have more nanoseconds then a second */
+       if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
+               return false;
+       return true;
+}
+
+static inline bool timespec_valid_strict(const struct timespec *ts)
+{
+       if (!timespec_valid(ts))
+               return false;
+       /* Disallow values that could overflow ktime_t */
+       if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
+               return false;
+       return true;
+}
 
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);
index 99bc88b1fc02734a30619038d2f9a7f430b4a951..7c5ceb20e03a8cf2195ae114e1f78905668158e5 100644 (file)
@@ -232,7 +232,7 @@ struct timex {
  * estimated error = NTP dispersion.
  */
 extern unsigned long tick_usec;                /* USER_HZ period (usec) */
-extern unsigned long tick_nsec;                /* ACTHZ          period (nsec) */
+extern unsigned long tick_nsec;                /* SHIFTED_HZ period (nsec) */
 
 extern void ntp_init(void);
 extern void ntp_clear(void);
index e91cd43394dfa82f3926c356abb4543b2e14bf36..fec12d667211dd398ba07ed5127b9e3485bcdd49 100644 (file)
@@ -164,6 +164,7 @@ int arch_update_cpu_topology(void);
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_SHARE_PKG_RESOURCES              \
                                | 0*SD_SERIALIZE                        \
+                               | 1*SD_PREFER_SIBLING                   \
                                ,                                       \
        .last_balance           = jiffies,                              \
        .balance_interval       = 1,                                    \
index c66fe3332d8376ab4fd226d60d7afd16e94b1a9f..50c3e8fa06a865b439047f80a0ac9be9a26cfeeb 100644 (file)
@@ -104,7 +104,6 @@ static inline void wait_on_inode(struct inode *inode)
        wait_on_bit(&inode->i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE);
 }
 
-
 /*
  * mm/page-writeback.c
  */
index 493fa0c790051ecd10a41050e7c7a05d323a52b0..3d254e10ff30e7ab3c5a4fee2ee0b38f1309bd94 100644 (file)
@@ -96,6 +96,7 @@ enum ieee80211_band {
  *     is not permitted.
  * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel
  *     is not permitted.
+ * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel.
  */
 enum ieee80211_channel_flags {
        IEEE80211_CHAN_DISABLED         = 1<<0,
@@ -104,6 +105,7 @@ enum ieee80211_channel_flags {
        IEEE80211_CHAN_RADAR            = 1<<3,
        IEEE80211_CHAN_NO_HT40PLUS      = 1<<4,
        IEEE80211_CHAN_NO_HT40MINUS     = 1<<5,
+       IEEE80211_CHAN_NO_OFDM          = 1<<6,
 };
 
 #define IEEE80211_CHAN_NO_HT40 \
index 550debfc240384f529562e3cc10cafcd342725f4..389cf621161d6903510c023e04e57a4ccd03072c 100644 (file)
@@ -305,6 +305,8 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
                        }
                }
        } else if (drop) {
+               u32 delta;
+
                if (params->ecn && INET_ECN_set_ce(skb)) {
                        stats->ecn_mark++;
                } else {
@@ -320,9 +322,11 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
                 * assume that the drop rate that controlled the queue on the
                 * last cycle is a good starting point to control it now.
                 */
-               if (codel_time_before(now - vars->drop_next,
+               delta = vars->count - vars->lastcount;
+               if (delta > 1 &&
+                   codel_time_before(now - vars->drop_next,
                                      16 * params->interval)) {
-                       vars->count = (vars->count - vars->lastcount) | 1;
+                       vars->count = delta;
                        /* we dont care if rec_inv_sqrt approximation
                         * is not very precise :
                         * Next Newton steps will correct it quadratically.
index baf59789006427bc7c373449b62b271e6e777d15..621e3513ef5ed2c833a16902761b3d5c1ed2ebaf 100644 (file)
@@ -110,7 +110,7 @@ struct dst_entry {
 };
 
 extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
-extern const u32 dst_default_metrics[RTAX_MAX];
+extern const u32 dst_default_metrics[];
 
 #define DST_METRICS_READ_ONLY  0x1UL
 #define __DST_METRICS_PTR(Y)   \
index 5ee66f517b4f6c34734be9d5f6552439802a5a38..ba1d3615acbb7bc481e7b676d897140cea0213b6 100644 (file)
@@ -39,6 +39,7 @@ struct inet_connection_sock_af_ops {
        int         (*queue_xmit)(struct sk_buff *skb, struct flowi *fl);
        void        (*send_check)(struct sock *sk, struct sk_buff *skb);
        int         (*rebuild_header)(struct sock *sk);
+       void        (*sk_rx_dst_set)(struct sock *sk, const struct sk_buff *skb);
        int         (*conn_request)(struct sock *sk, struct sk_buff *skb);
        struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb,
                                      struct request_sock *req,
index 83b567fe194163b74f734cedaf1dffff28e914a6..613cfa4016728300da88a8fc6f1f664de99da5cc 100644 (file)
@@ -249,13 +249,4 @@ static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
        return flags;
 }
 
-static inline void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
-{
-       struct dst_entry *dst = skb_dst(skb);
-
-       dst_hold(dst);
-       sk->sk_rx_dst = dst;
-       inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
-}
-
 #endif /* _INET_SOCK_H */
index bd5e444a19ce43482f09f695c6e3b36a303302b3..5a5d84d3d2c6b6e3777035a631fb10e7479ab8de 100644 (file)
@@ -120,7 +120,7 @@ extern struct sk_buff  *__ip_make_skb(struct sock *sk,
                                      struct flowi4 *fl4,
                                      struct sk_buff_head *queue,
                                      struct inet_cork *cork);
-extern int             ip_send_skb(struct sk_buff *skb);
+extern int             ip_send_skb(struct net *net, struct sk_buff *skb);
 extern int             ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4);
 extern void            ip_flush_pending_frames(struct sock *sk);
 extern struct sk_buff  *ip_make_skb(struct sock *sk,
index 226c846cab08bdf84e0991aee83124c42e6aab0d..f2d0fc570527baf216f34cd364c0162330dcbd28 100644 (file)
@@ -133,7 +133,7 @@ extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
 extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
 extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
 
-extern int llc_station_init(void);
+extern void llc_station_init(void);
 extern void llc_station_exit(void);
 
 #ifdef CONFIG_PROC_FS
index 079d7887dac13697d0dfc5d0cc6ce256800151d0..7dc0854f0b3891992696002b7f75edf7a01233ab 100644 (file)
@@ -70,9 +70,11 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 }
 
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
-                              struct scm_cookie *scm)
+                              struct scm_cookie *scm, bool forcecreds)
 {
        memset(scm, 0, sizeof(*scm));
+       if (forcecreds)
+               scm_set_cred(scm, task_tgid(current), current_cred());
        unix_get_peersec_dgram(sock, scm);
        if (msg->msg_controllen <= 0)
                return 0;
index b3730239bf1828bd9fb618b8b8988b37832fe5c3..72132aef53fc61a721ce23c8fbc4fe17cb7a9699 100644 (file)
@@ -218,6 +218,7 @@ struct cg_proto;
   *    @sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK)
   *    @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
   *    @sk_gso_max_size: Maximum GSO segment size to build
+  *    @sk_gso_max_segs: Maximum number of GSO segments
   *    @sk_lingertime: %SO_LINGER l_linger setting
   *    @sk_backlog: always used with the per-socket spinlock held
   *    @sk_callback_lock: used with the callbacks in the end of this struct
@@ -338,6 +339,7 @@ struct sock {
        netdev_features_t       sk_route_nocaps;
        int                     sk_gso_type;
        unsigned int            sk_gso_max_size;
+       u16                     sk_gso_max_segs;
        int                     sk_rcvlowat;
        unsigned long           sk_lingertime;
        struct sk_buff_head     sk_error_queue;
index e19124b84cd2a299a28737e60e1e0346efe24c2f..1f000ffe70758c0596b8c4d18230e781b88f495f 100644 (file)
@@ -464,6 +464,7 @@ extern int tcp_disconnect(struct sock *sk, int flags);
 void tcp_connect_init(struct sock *sk);
 void tcp_finish_connect(struct sock *sk, struct sk_buff *skb);
 int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size);
+void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb);
 
 /* From syncookies.c */
 extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
index d9509eb29b80f989eb47531877279ae93f31f85c..976a81abe1a231de348085a92c8f3110a21fc3fa 100644 (file)
@@ -213,6 +213,9 @@ struct xfrm_state {
        struct xfrm_lifetime_cur curlft;
        struct tasklet_hrtimer  mtimer;
 
+       /* used to fix curlft->add_time when changing date */
+       long            saved_tmo;
+
        /* Last used time */
        unsigned long           lastused;
 
@@ -238,6 +241,7 @@ static inline struct net *xs_net(struct xfrm_state *x)
 
 /* xflags - make enum if more show up */
 #define XFRM_TIME_DEFER        1
+#define XFRM_SOFT_EXPIRE 2
 
 enum {
        XFRM_STATE_VOID,
@@ -288,6 +292,8 @@ struct xfrm_policy_afinfo {
                                                  struct flowi *fl,
                                                  int reverse);
        int                     (*get_tos)(const struct flowi *fl);
+       void                    (*init_dst)(struct net *net,
+                                           struct xfrm_dst *dst);
        int                     (*init_path)(struct xfrm_dst *path,
                                             struct dst_entry *dst,
                                             int nfheader_len);
index c75c0d1a85e2acabb2e30d43ba1e6150f1268c6a..cdca2ab1e7112f8e79156f39f318d5f3e4405cbd 100644 (file)
@@ -1075,7 +1075,8 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
 const char *snd_pcm_format_name(snd_pcm_format_t format);
 
 /**
- * Get a string naming the direction of a stream
+ * snd_pcm_stream_str - Get a string naming the direction of a stream
+ * @substream: the pcm substream instance
  */
 static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream)
 {
index 128ce46fa48a799fa9b3b332a07d2babfee01925..015cea01ae39bedd1a1bf796e23a8f90f061e5e2 100644 (file)
@@ -503,8 +503,6 @@ struct se_cmd {
        u32                     se_ordered_id;
        /* Total size in bytes associated with command */
        u32                     data_length;
-       /* SCSI Presented Data Transfer Length */
-       u32                     cmd_spdtl;
        u32                     residual_count;
        u32                     orig_fe_lun;
        /* Persistent Reservation key */
index ea7a2035456d4f913e15b9997696ab5ca4934ad1..5a8671e8a67ff8fa8f715311300901181555d78e 100644 (file)
@@ -73,6 +73,9 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,
                __entry->prio           = p->prio;
                __entry->success        = success;
                __entry->target_cpu     = task_cpu(p);
+       )
+       TP_perf_assign(
+               __perf_task(p);
        ),
 
        TP_printk("comm=%s pid=%d prio=%d success=%d target_cpu=%03d",
@@ -325,6 +328,7 @@ DECLARE_EVENT_CLASS(sched_stat_template,
        )
        TP_perf_assign(
                __perf_count(delay);
+               __perf_task(tsk);
        ),
 
        TP_printk("comm=%s pid=%d delay=%Lu [ns]",
index c6bc2faaf2611533b1b2a72e6d3e191fa6033616..a763888a36f961339d5a437190c1c944077f875f 100644 (file)
@@ -712,6 +712,9 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
 #undef __perf_count
 #define __perf_count(c) __count = (c)
 
+#undef __perf_task
+#define __perf_task(t) __task = (t)
+
 #undef TP_perf_assign
 #define TP_perf_assign(args...) args
 
@@ -725,6 +728,7 @@ perf_trace_##call(void *__data, proto)                                      \
        struct ftrace_raw_##call *entry;                                \
        struct pt_regs __regs;                                          \
        u64 __addr = 0, __count = 1;                                    \
+       struct task_struct *__task = NULL;                              \
        struct hlist_head *head;                                        \
        int __entry_size;                                               \
        int __data_size;                                                \
@@ -752,7 +756,7 @@ perf_trace_##call(void *__data, proto)                                      \
                                                                        \
        head = this_cpu_ptr(event_call->perf_events);                   \
        perf_trace_buf_submit(entry, __entry_size, rctx, __addr,        \
-               __count, &__regs, head);                                \
+               __count, &__regs, head, __task);                        \
 }
 
 /*
index 9c641deb65d2c62236343b4934d0db6ecb6c0dff..04399b28e821bf694a58d706e0b6c9f66e9c7d9f 100644 (file)
@@ -58,8 +58,6 @@ void notify_remote_via_irq(int irq);
 
 void xen_irq_resume(void);
 
-void xen_hvm_prepare_kexec(struct shared_info *sip, unsigned long pfn);
-
 /* Clear an irq's pending state, in preparation for polling on it */
 void xen_clear_irq_pending(int irq);
 void xen_set_irq_pending(int irq);
index e60679de61c3a050640554966d34542fcc13a7bd..b28673087ac006e79f4563b1a06d39eb1b163d37 100644 (file)
@@ -461,10 +461,6 @@ static void __init mm_init(void)
        percpu_init_late();
        pgtable_cache_init();
        vmalloc_init();
-#ifdef CONFIG_X86
-       if (efi_enabled)
-               efi_enter_virtual_mode();
-#endif
 }
 
 asmlinkage void __init start_kernel(void)
@@ -606,6 +602,10 @@ asmlinkage void __init start_kernel(void)
        calibrate_delay();
        pidmap_init();
        anon_vma_init();
+#ifdef CONFIG_X86
+       if (efi_enabled)
+               efi_enter_virtual_mode();
+#endif
        thread_info_cache_init();
        cred_init();
        fork_init(totalram_pages);
index f8e54f5b90804ea58309da551fcd40dd8cf12333..9a08acc9e64923ea8af5bb9286d6f2ddd48c052e 100644 (file)
@@ -726,7 +726,6 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir,
                        struct mq_attr *attr)
 {
        const struct cred *cred = current_cred();
-       struct file *result;
        int ret;
 
        if (attr) {
@@ -748,21 +747,11 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir,
        }
 
        mode &= ~current_umask();
-       ret = mnt_want_write(path->mnt);
-       if (ret)
-               return ERR_PTR(ret);
        ret = vfs_create(dir, path->dentry, mode, true);
        path->dentry->d_fsdata = NULL;
-       if (!ret)
-               result = dentry_open(path, oflag, cred);
-       else
-               result = ERR_PTR(ret);
-       /*
-        * dentry_open() took a persistent mnt_want_write(),
-        * so we can now drop this one.
-        */
-       mnt_drop_write(path->mnt);
-       return result;
+       if (ret)
+               return ERR_PTR(ret);
+       return dentry_open(path, oflag, cred);
 }
 
 /* Opens existing queue */
@@ -788,7 +777,9 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
        struct mq_attr attr;
        int fd, error;
        struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
-       struct dentry *root = ipc_ns->mq_mnt->mnt_root;
+       struct vfsmount *mnt = ipc_ns->mq_mnt;
+       struct dentry *root = mnt->mnt_root;
+       int ro;
 
        if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
                return -EFAULT;
@@ -802,6 +793,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
        if (fd < 0)
                goto out_putname;
 
+       ro = mnt_want_write(mnt);       /* we'll drop it in any case */
        error = 0;
        mutex_lock(&root->d_inode->i_mutex);
        path.dentry = lookup_one_len(name, root, strlen(name));
@@ -809,7 +801,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
                error = PTR_ERR(path.dentry);
                goto out_putfd;
        }
-       path.mnt = mntget(ipc_ns->mq_mnt);
+       path.mnt = mntget(mnt);
 
        if (oflag & O_CREAT) {
                if (path.dentry->d_inode) {     /* entry already exists */
@@ -820,6 +812,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
                        }
                        filp = do_open(&path, oflag);
                } else {
+                       if (ro) {
+                               error = ro;
+                               goto out;
+                       }
                        filp = do_create(ipc_ns, root->d_inode,
                                                &path, oflag, mode,
                                                u_attr ? &attr : NULL);
@@ -845,6 +841,7 @@ out_putfd:
                fd = error;
        }
        mutex_unlock(&root->d_inode->i_mutex);
+       mnt_drop_write(mnt);
 out_putname:
        putname(name);
        return fd;
@@ -857,40 +854,38 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
        struct dentry *dentry;
        struct inode *inode = NULL;
        struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
+       struct vfsmount *mnt = ipc_ns->mq_mnt;
 
        name = getname(u_name);
        if (IS_ERR(name))
                return PTR_ERR(name);
 
-       mutex_lock_nested(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex,
-                       I_MUTEX_PARENT);
-       dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
+       err = mnt_want_write(mnt);
+       if (err)
+               goto out_name;
+       mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT);
+       dentry = lookup_one_len(name, mnt->mnt_root, strlen(name));
        if (IS_ERR(dentry)) {
                err = PTR_ERR(dentry);
                goto out_unlock;
        }
 
-       if (!dentry->d_inode) {
-               err = -ENOENT;
-               goto out_err;
-       }
-
        inode = dentry->d_inode;
-       if (inode)
+       if (!inode) {
+               err = -ENOENT;
+       } else {
                ihold(inode);
-       err = mnt_want_write(ipc_ns->mq_mnt);
-       if (err)
-               goto out_err;
-       err = vfs_unlink(dentry->d_parent->d_inode, dentry);
-       mnt_drop_write(ipc_ns->mq_mnt);
-out_err:
+               err = vfs_unlink(dentry->d_parent->d_inode, dentry);
+       }
        dput(dentry);
 
 out_unlock:
-       mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
-       putname(name);
+       mutex_unlock(&mnt->mnt_root->d_inode->i_mutex);
        if (inode)
                iput(inode);
+       mnt_drop_write(mnt);
+out_name:
+       putname(name);
 
        return err;
 }
index 3a5ca582ba1ebe2373803bfbf1887357d05b523e..ed206fd88cca76e75a0d8866ab703a7f6fdf38d6 100644 (file)
@@ -250,7 +250,6 @@ static void untag_chunk(struct node *p)
                spin_unlock(&hash_lock);
                spin_unlock(&entry->lock);
                fsnotify_destroy_mark(entry);
-               fsnotify_put_mark(entry);
                goto out;
        }
 
@@ -259,7 +258,7 @@ static void untag_chunk(struct node *p)
 
        fsnotify_duplicate_mark(&new->mark, entry);
        if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) {
-               free_chunk(new);
+               fsnotify_put_mark(&new->mark);
                goto Fallback;
        }
 
@@ -293,7 +292,7 @@ static void untag_chunk(struct node *p)
        spin_unlock(&hash_lock);
        spin_unlock(&entry->lock);
        fsnotify_destroy_mark(entry);
-       fsnotify_put_mark(entry);
+       fsnotify_put_mark(&new->mark);  /* drop initial reference */
        goto out;
 
 Fallback:
@@ -322,7 +321,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
 
        entry = &chunk->mark;
        if (fsnotify_add_mark(entry, audit_tree_group, inode, NULL, 0)) {
-               free_chunk(chunk);
+               fsnotify_put_mark(entry);
                return -ENOSPC;
        }
 
@@ -347,6 +346,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
        insert_hash(chunk);
        spin_unlock(&hash_lock);
        spin_unlock(&entry->lock);
+       fsnotify_put_mark(entry);       /* drop initial reference */
        return 0;
 }
 
@@ -396,7 +396,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
        fsnotify_duplicate_mark(chunk_entry, old_entry);
        if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) {
                spin_unlock(&old_entry->lock);
-               free_chunk(chunk);
+               fsnotify_put_mark(chunk_entry);
                fsnotify_put_mark(old_entry);
                return -ENOSPC;
        }
@@ -444,8 +444,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
        spin_unlock(&chunk_entry->lock);
        spin_unlock(&old_entry->lock);
        fsnotify_destroy_mark(old_entry);
+       fsnotify_put_mark(chunk_entry); /* drop initial reference */
        fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
-       fsnotify_put_mark(old_entry); /* and kill it */
        return 0;
 }
 
@@ -916,7 +916,12 @@ static void audit_tree_freeing_mark(struct fsnotify_mark *entry, struct fsnotify
        struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark);
 
        evict_chunk(chunk);
-       fsnotify_put_mark(entry);
+
+       /*
+        * We are guaranteed to have at least one reference to the mark from
+        * either the inode or the caller of fsnotify_destroy_mark().
+        */
+       BUG_ON(atomic_read(&entry->refcnt) < 1);
 }
 
 static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode,
index 8b68ce78ff170b8777be887a3bc8407c59863ba5..be7b33b73d3001eef1b676ad1efde4f318824902 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kdb.h>
 #include <linux/kdebug.h>
 #include <linux/export.h>
+#include <linux/hardirq.h>
 #include "kdb_private.h"
 #include "../debug_core.h"
 
@@ -52,6 +53,9 @@ int kdb_stub(struct kgdb_state *ks)
        if (atomic_read(&kgdb_setting_breakpoint))
                reason = KDB_REASON_KEYBOARD;
 
+       if (in_nmi())
+               reason = KDB_REASON_NMI;
+
        for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) {
                if ((bp->bp_enabled) && (bp->bp_addr == addr)) {
                        reason = KDB_REASON_BREAK;
index bb9520f0f6ff8e607d0b08b2561efa62f4ba3b8d..0a69d2adc4f3cb7fb49a14c3ccefb87cfe0084bd 100644 (file)
@@ -715,9 +715,6 @@ kdb_printit:
        /* check for having reached the LINES number of printed lines */
        if (kdb_nextline == linecount) {
                char buf1[16] = "";
-#if defined(CONFIG_SMP)
-               char buf2[32];
-#endif
 
                /* Watch out for recursion here.  Any routine that calls
                 * kdb_printf will come back through here.  And kdb_read
@@ -732,14 +729,6 @@ kdb_printit:
                if (moreprompt == NULL)
                        moreprompt = "more> ";
 
-#if defined(CONFIG_SMP)
-               if (strchr(moreprompt, '%')) {
-                       sprintf(buf2, moreprompt, get_cpu());
-                       put_cpu();
-                       moreprompt = buf2;
-               }
-#endif
-
                kdb_input_flush();
                c = console_drivers;
 
index 1f91413edb87d0c9b77efc4e84c9b2f9729e9b8c..31df1706b9a9344bf3d63a1b0146987378060ed4 100644 (file)
@@ -139,11 +139,10 @@ static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t);
 static char *__env[] = {
 #if defined(CONFIG_SMP)
  "PROMPT=[%d]kdb> ",
- "MOREPROMPT=[%d]more> ",
 #else
  "PROMPT=kdb> ",
- "MOREPROMPT=more> ",
 #endif
+ "MOREPROMPT=more> ",
  "RADIX=16",
  "MDCOUNT=8",                  /* lines of md output */
  KDB_PLATFORM_ENV,
@@ -1236,18 +1235,6 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
                *cmdbuf = '\0';
                *(cmd_hist[cmd_head]) = '\0';
 
-               if (KDB_FLAG(ONLY_DO_DUMP)) {
-                       /* kdb is off but a catastrophic error requires a dump.
-                        * Take the dump and reboot.
-                        * Turn on logging so the kdb output appears in the log
-                        * buffer in the dump.
-                        */
-                       const char *setargs[] = { "set", "LOGGING", "1" };
-                       kdb_set(2, setargs);
-                       kdb_reboot(0, NULL);
-                       /*NOTREACHED*/
-               }
-
 do_full_getstr:
 #if defined(CONFIG_SMP)
                snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"),
index 6581a040f39926dd46878640413bfd180922415a..98d4597f43d69e35a76535fac7d0bb6821ebdf7f 100644 (file)
@@ -153,7 +153,8 @@ put_callchain_entry(int rctx)
        put_recursion_context(__get_cpu_var(callchain_recursion), rctx);
 }
 
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+struct perf_callchain_entry *
+perf_callchain(struct perf_event *event, struct pt_regs *regs)
 {
        int rctx;
        struct perf_callchain_entry *entry;
@@ -178,6 +179,12 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
        }
 
        if (regs) {
+               /*
+                * Disallow cross-task user callchains.
+                */
+               if (event->ctx->task && event->ctx->task != current)
+                       goto exit_put;
+
                perf_callchain_store(entry, PERF_CONTEXT_USER);
                perf_callchain_user(entry, regs);
        }
index f1cf0edeb39afa1a3f6543a2f383ac8c4828127b..b7935fcec7d923b0b0b89fe0fe7dfdf61967b447 100644 (file)
@@ -4039,7 +4039,7 @@ void perf_prepare_sample(struct perf_event_header *header,
        if (sample_type & PERF_SAMPLE_CALLCHAIN) {
                int size = 1;
 
-               data->callchain = perf_callchain(regs);
+               data->callchain = perf_callchain(event, regs);
 
                if (data->callchain)
                        size += data->callchain->nr;
@@ -5209,7 +5209,8 @@ static int perf_tp_event_match(struct perf_event *event,
 }
 
 void perf_tp_event(u64 addr, u64 count, void *record, int entry_size,
-                  struct pt_regs *regs, struct hlist_head *head, int rctx)
+                  struct pt_regs *regs, struct hlist_head *head, int rctx,
+                  struct task_struct *task)
 {
        struct perf_sample_data data;
        struct perf_event *event;
@@ -5228,6 +5229,31 @@ void perf_tp_event(u64 addr, u64 count, void *record, int entry_size,
                        perf_swevent_event(event, count, &data, regs);
        }
 
+       /*
+        * If we got specified a target task, also iterate its context and
+        * deliver this event there too.
+        */
+       if (task && task != current) {
+               struct perf_event_context *ctx;
+               struct trace_entry *entry = record;
+
+               rcu_read_lock();
+               ctx = rcu_dereference(task->perf_event_ctxp[perf_sw_context]);
+               if (!ctx)
+                       goto unlock;
+
+               list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+                       if (event->attr.type != PERF_TYPE_TRACEPOINT)
+                               continue;
+                       if (event->attr.config != entry->type)
+                               continue;
+                       if (perf_tp_event_match(event, &data, regs))
+                               perf_swevent_event(event, count, &data, regs);
+               }
+unlock:
+               rcu_read_unlock();
+       }
+
        perf_swevent_put_recursion_context(rctx);
 }
 EXPORT_SYMBOL_GPL(perf_tp_event);
index b0b107f90afc983a0a7abd4b2f0f9519670f2275..a096c19f2c2a1aba50b62df4b91618cdcdb276d9 100644 (file)
@@ -101,7 +101,8 @@ __output_copy(struct perf_output_handle *handle,
 }
 
 /* Callchain handling */
-extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs);
+extern struct perf_callchain_entry *
+perf_callchain(struct perf_event *event, struct pt_regs *regs);
 extern int get_callchain_buffers(void);
 extern void put_callchain_buffers(void);
 
index 3bd2280d79f6b5507537c3e294e05c77a69d678f..2c8857e12855393759562b3c6eeec2d23de6f080 100644 (file)
@@ -455,8 +455,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
                if (retval)
                        goto out;
 
-               if (file && uprobe_mmap(tmp))
-                       goto out;
+               if (file)
+                       uprobe_mmap(tmp);
        }
        /* a new mm has just been created */
        arch_dup_mmap(oldmm, mm);
index e2b0fb9a0b3b3d0d5871ee37bf08618a6bf052e7..3717e7b306e08c0e8c2d3a66219c3cae13176d99 100644 (file)
@@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  * @uaddr2:    the pi futex we will take prior to returning to user-space
  *
  * The caller will wait on uaddr and will be requeued by futex_requeue() to
- * uaddr2 which must be PI aware.  Normal wakeup will wake on uaddr2 and
- * complete the acquisition of the rt_mutex prior to returning to userspace.
- * This ensures the rt_mutex maintains an owner when it has waiters; without
- * one, the pi logic wouldn't know which task to boost/deboost, if there was a
- * need to.
+ * uaddr2 which must be PI aware and unique from uaddr.  Normal wakeup will wake
+ * on uaddr2 and complete the acquisition of the rt_mutex prior to returning to
+ * userspace.  This ensures the rt_mutex maintains an owner when it has waiters;
+ * without one, the pi logic would not know which task to boost/deboost, if
+ * there was a need to.
  *
  * We call schedule in futex_wait_queue_me() when we enqueue and return there
  * via the following:
@@ -2272,6 +2272,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
        struct futex_q q = futex_q_init;
        int res, ret;
 
+       if (uaddr == uaddr2)
+               return -EINVAL;
+
        if (!bitset)
                return -EINVAL;
 
@@ -2343,7 +2346,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
                 * signal.  futex_unlock_pi() will not destroy the lock_ptr nor
                 * the pi_state.
                 */
-               WARN_ON(!&q.pi_state);
+               WARN_ON(!q.pi_state);
                pi_mutex = &q.pi_state->pi_mutex;
                ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1);
                debug_rt_mutex_free_waiter(&rt_waiter);
@@ -2370,7 +2373,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
         * fault, unlock the rt_mutex and return the fault to userspace.
         */
        if (ret == -EFAULT) {
-               if (rt_mutex_owner(pi_mutex) == current)
+               if (pi_mutex && rt_mutex_owner(pi_mutex) == current)
                        rt_mutex_unlock(pi_mutex);
        } else if (ret == -EINTR) {
                /*
index 0a8e8f059627dec4ee56bab79849e0f86372d3b5..4c69326aa773f6469b7170d66814d7480ea12ea7 100644 (file)
@@ -943,6 +943,18 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                goto out_thread;
        }
 
+       /*
+        * Drivers are often written to work w/o knowledge about the
+        * underlying irq chip implementation, so a request for a
+        * threaded irq without a primary hard irq context handler
+        * requires the ONESHOT flag to be set. Some irq chips like
+        * MSI based interrupts are per se one shot safe. Check the
+        * chip flags, so we can avoid the unmask dance at the end of
+        * the threaded handler for those.
+        */
+       if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)
+               new->flags &= ~IRQF_ONESHOT;
+
        /*
         * The following block of code has to be executed atomically
         */
@@ -1017,7 +1029,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                 */
                new->thread_mask = 1 << ffz(thread_mask);
 
-       } else if (new->handler == irq_default_primary_handler) {
+       } else if (new->handler == irq_default_primary_handler &&
+                  !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) {
                /*
                 * The interrupt was requested with handler = NULL, so
                 * we use the default primary handler for it. But it
index 1da39ea248fdf3bee6f16f536693b0daad10afbe..c8b7446b27dfc21add10f610e1692a2f3acee7ed 100644 (file)
@@ -178,9 +178,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
        arch_suspend_enable_irqs();
        BUG_ON(irqs_disabled());
 
-       /* Kick the lockup detector */
-       lockup_detector_bootcpu_resume();
-
  Enable_cpus:
        enable_nonboot_cpus();
 
index 6a76ab9d4476466b5ba3b3e37d38aadbb2e02644..66a2ea37b5763b450929a5f955e3bc81ad130a1c 100644 (file)
@@ -1034,6 +1034,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
                        struct log *msg = log_from_idx(idx);
 
                        len += msg_print_text(msg, prev, true, NULL, 0);
+                       prev = msg->flags;
                        idx = log_next(idx);
                        seq++;
                }
@@ -1046,6 +1047,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
                        struct log *msg = log_from_idx(idx);
 
                        len -= msg_print_text(msg, prev, true, NULL, 0);
+                       prev = msg->flags;
                        idx = log_next(idx);
                        seq++;
                }
index d325c4b2dcbb0c5995a903d76e3035129d1590c3..fbf1fd098dc6cca687f0e9296a931aa0425c6fee 100644 (file)
@@ -3142,6 +3142,20 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
 # define nsecs_to_cputime(__nsecs)     nsecs_to_jiffies(__nsecs)
 #endif
 
+static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total)
+{
+       u64 temp = (__force u64) rtime;
+
+       temp *= (__force u64) utime;
+
+       if (sizeof(cputime_t) == 4)
+               temp = div_u64(temp, (__force u32) total);
+       else
+               temp = div64_u64(temp, (__force u64) total);
+
+       return (__force cputime_t) temp;
+}
+
 void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
 {
        cputime_t rtime, utime = p->utime, total = utime + p->stime;
@@ -3151,13 +3165,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
         */
        rtime = nsecs_to_cputime(p->se.sum_exec_runtime);
 
-       if (total) {
-               u64 temp = (__force u64) rtime;
-
-               temp *= (__force u64) utime;
-               do_div(temp, (__force u32) total);
-               utime = (__force cputime_t) temp;
-       } else
+       if (total)
+               utime = scale_utime(utime, rtime, total);
+       else
                utime = rtime;
 
        /*
@@ -3184,13 +3194,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
        total = cputime.utime + cputime.stime;
        rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
 
-       if (total) {
-               u64 temp = (__force u64) rtime;
-
-               temp *= (__force u64) cputime.utime;
-               do_div(temp, (__force u32) total);
-               utime = (__force cputime_t) temp;
-       } else
+       if (total)
+               utime = scale_utime(cputime.utime, rtime, total);
+       else
                utime = rtime;
 
        sig->prev_utime = max(sig->prev_utime, utime);
@@ -4340,9 +4346,7 @@ recheck:
         */
        if (unlikely(policy == p->policy && (!rt_policy(policy) ||
                        param->sched_priority == p->rt_priority))) {
-
-               __task_rq_unlock(rq);
-               raw_spin_unlock_irqrestore(&p->pi_lock, flags);
+               task_rq_unlock(rq, p, &flags);
                return 0;
        }
 
@@ -7248,6 +7252,7 @@ int in_sched_functions(unsigned long addr)
 
 #ifdef CONFIG_CGROUP_SCHED
 struct task_group root_task_group;
+LIST_HEAD(task_groups);
 #endif
 
 DECLARE_PER_CPU(cpumask_var_t, load_balance_tmpmask);
index d72586fdf6607db63c5f43a2e1fbbb32ff0ac2c7..23aa789c53ee5c6e061c6bf2b0f8181292695044 100644 (file)
@@ -65,8 +65,8 @@ static int convert_prio(int prio)
 int cpupri_find(struct cpupri *cp, struct task_struct *p,
                struct cpumask *lowest_mask)
 {
-       int                  idx      = 0;
-       int                  task_pri = convert_prio(p->prio);
+       int idx = 0;
+       int task_pri = convert_prio(p->prio);
 
        if (task_pri >= MAX_RT_PRIO)
                return 0;
@@ -137,9 +137,9 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p,
  */
 void cpupri_set(struct cpupri *cp, int cpu, int newpri)
 {
-       int                 *currpri = &cp->cpu_to_pri[cpu];
-       int                  oldpri  = *currpri;
-       int                  do_mb = 0;
+       int *currpri = &cp->cpu_to_pri[cpu];
+       int oldpri = *currpri;
+       int do_mb = 0;
 
        newpri = convert_prio(newpri);
 
index 22321db64952f9461b9e03a3e90bd99217478f8f..c219bf8d704c5460291abee8416264ee32d36e22 100644 (file)
@@ -3069,6 +3069,9 @@ struct lb_env {
        int                     new_dst_cpu;
        enum cpu_idle_type      idle;
        long                    imbalance;
+       /* The set of CPUs under consideration for load-balancing */
+       struct cpumask          *cpus;
+
        unsigned int            flags;
 
        unsigned int            loop;
@@ -3384,6 +3387,14 @@ static int tg_load_down(struct task_group *tg, void *data)
 
 static void update_h_load(long cpu)
 {
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long now = jiffies;
+
+       if (rq->h_load_throttle == now)
+               return;
+
+       rq->h_load_throttle = now;
+
        rcu_read_lock();
        walk_tg_tree(tg_load_down, tg_nop, (void *)cpu);
        rcu_read_unlock();
@@ -3653,8 +3664,7 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group)
  */
 static inline void update_sg_lb_stats(struct lb_env *env,
                        struct sched_group *group, int load_idx,
-                       int local_group, const struct cpumask *cpus,
-                       int *balance, struct sg_lb_stats *sgs)
+                       int local_group, int *balance, struct sg_lb_stats *sgs)
 {
        unsigned long nr_running, max_nr_running, min_nr_running;
        unsigned long load, max_cpu_load, min_cpu_load;
@@ -3671,7 +3681,7 @@ static inline void update_sg_lb_stats(struct lb_env *env,
        max_nr_running = 0;
        min_nr_running = ~0UL;
 
-       for_each_cpu_and(i, sched_group_cpus(group), cpus) {
+       for_each_cpu_and(i, sched_group_cpus(group), env->cpus) {
                struct rq *rq = cpu_rq(i);
 
                nr_running = rq->nr_running;
@@ -3800,8 +3810,7 @@ static bool update_sd_pick_busiest(struct lb_env *env,
  * @sds: variable to hold the statistics for this sched_domain.
  */
 static inline void update_sd_lb_stats(struct lb_env *env,
-                                     const struct cpumask *cpus,
-                                     int *balance, struct sd_lb_stats *sds)
+                                       int *balance, struct sd_lb_stats *sds)
 {
        struct sched_domain *child = env->sd->child;
        struct sched_group *sg = env->sd->groups;
@@ -3818,8 +3827,7 @@ static inline void update_sd_lb_stats(struct lb_env *env,
 
                local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg));
                memset(&sgs, 0, sizeof(sgs));
-               update_sg_lb_stats(env, sg, load_idx, local_group,
-                                  cpus, balance, &sgs);
+               update_sg_lb_stats(env, sg, load_idx, local_group, balance, &sgs);
 
                if (local_group && !(*balance))
                        return;
@@ -4055,7 +4063,6 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
  * to restore balance.
  *
  * @env: The load balancing environment.
- * @cpus: The set of CPUs under consideration for load-balancing.
  * @balance: Pointer to a variable indicating if this_cpu
  *     is the appropriate cpu to perform load balancing at this_level.
  *
@@ -4065,7 +4072,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
  *                put to idle by rebalancing its tasks onto our group.
  */
 static struct sched_group *
-find_busiest_group(struct lb_env *env, const struct cpumask *cpus, int *balance)
+find_busiest_group(struct lb_env *env, int *balance)
 {
        struct sd_lb_stats sds;
 
@@ -4075,7 +4082,7 @@ find_busiest_group(struct lb_env *env, const struct cpumask *cpus, int *balance)
         * Compute the various statistics relavent for load balancing at
         * this level.
         */
-       update_sd_lb_stats(env, cpus, balance, &sds);
+       update_sd_lb_stats(env, balance, &sds);
 
        /*
         * this_cpu is not the appropriate cpu to perform load balancing at
@@ -4155,8 +4162,7 @@ ret:
  * find_busiest_queue - find the busiest runqueue among the cpus in group.
  */
 static struct rq *find_busiest_queue(struct lb_env *env,
-                                    struct sched_group *group,
-                                    const struct cpumask *cpus)
+                                    struct sched_group *group)
 {
        struct rq *busiest = NULL, *rq;
        unsigned long max_load = 0;
@@ -4171,7 +4177,7 @@ static struct rq *find_busiest_queue(struct lb_env *env,
                if (!capacity)
                        capacity = fix_small_capacity(env->sd, group);
 
-               if (!cpumask_test_cpu(i, cpus))
+               if (!cpumask_test_cpu(i, env->cpus))
                        continue;
 
                rq = cpu_rq(i);
@@ -4252,6 +4258,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,
                .dst_grpmask    = sched_group_cpus(sd->groups),
                .idle           = idle,
                .loop_break     = sched_nr_migrate_break,
+               .cpus           = cpus,
        };
 
        cpumask_copy(cpus, cpu_active_mask);
@@ -4260,7 +4267,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,
        schedstat_inc(sd, lb_count[idle]);
 
 redo:
-       group = find_busiest_group(&env, cpus, balance);
+       group = find_busiest_group(&env, balance);
 
        if (*balance == 0)
                goto out_balanced;
@@ -4270,7 +4277,7 @@ redo:
                goto out_balanced;
        }
 
-       busiest = find_busiest_queue(&env, group, cpus);
+       busiest = find_busiest_queue(&env, group);
        if (!busiest) {
                schedstat_inc(sd, lb_nobusyq[idle]);
                goto out_balanced;
@@ -4294,11 +4301,10 @@ redo:
                env.src_rq    = busiest;
                env.loop_max  = min(sysctl_sched_nr_migrate, busiest->nr_running);
 
+               update_h_load(env.src_cpu);
 more_balance:
                local_irq_save(flags);
                double_rq_lock(this_rq, busiest);
-               if (!env.loop)
-                       update_h_load(env.src_cpu);
 
                /*
                 * cur_ld_moved - load moved in current iteration
index 573e1ca01102066468e65aee96c57ea30cccd6de..944cb68420e957cbde71f9cacaaa4e81c4b1de20 100644 (file)
@@ -788,6 +788,19 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
        const struct cpumask *span;
 
        span = sched_rt_period_mask();
+#ifdef CONFIG_RT_GROUP_SCHED
+       /*
+        * FIXME: isolated CPUs should really leave the root task group,
+        * whether they are isolcpus or were isolated via cpusets, lest
+        * the timer run on a CPU which does not service all runqueues,
+        * potentially leaving other CPUs indefinitely throttled.  If
+        * isolation is really required, the user will turn the throttle
+        * off to kill the perturbations it causes anyway.  Meanwhile,
+        * this maintains functionality for boot and/or troubleshooting.
+        */
+       if (rt_b == &root_task_group.rt_bandwidth)
+               span = cpu_online_mask;
+#endif
        for_each_cpu(i, span) {
                int enqueue = 0;
                struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i);
index c35a1a7dd4d67f4654e1d4dd9236d6c4d910f258..f6714d009e779a225ef295d33ceff7f2f8573be8 100644 (file)
@@ -80,7 +80,7 @@ extern struct mutex sched_domains_mutex;
 struct cfs_rq;
 struct rt_rq;
 
-static LIST_HEAD(task_groups);
+extern struct list_head task_groups;
 
 struct cfs_bandwidth {
 #ifdef CONFIG_CFS_BANDWIDTH
@@ -374,7 +374,11 @@ struct rq {
 #ifdef CONFIG_FAIR_GROUP_SCHED
        /* list of leaf cfs_rq on this cpu: */
        struct list_head leaf_cfs_rq_list;
-#endif
+#ifdef CONFIG_SMP
+       unsigned long h_load_throttle;
+#endif /* CONFIG_SMP */
+#endif /* CONFIG_FAIR_GROUP_SCHED */
+
 #ifdef CONFIG_RT_GROUP_SCHED
        struct list_head leaf_rt_rq_list;
 #endif
index 7b386e86fd2352c1a0fef2be23672a9c8ef194db..da5eb5bed84a2ca8db2443ccb71817d48f06c1f5 100644 (file)
@@ -27,8 +27,10 @@ static struct task_struct *pick_next_task_stop(struct rq *rq)
 {
        struct task_struct *stop = rq->stop;
 
-       if (stop && stop->on_rq)
+       if (stop && stop->on_rq) {
+               stop->se.exec_start = rq->clock_task;
                return stop;
+       }
 
        return NULL;
 }
@@ -52,6 +54,21 @@ static void yield_task_stop(struct rq *rq)
 
 static void put_prev_task_stop(struct rq *rq, struct task_struct *prev)
 {
+       struct task_struct *curr = rq->curr;
+       u64 delta_exec;
+
+       delta_exec = rq->clock_task - curr->se.exec_start;
+       if (unlikely((s64)delta_exec < 0))
+               delta_exec = 0;
+
+       schedstat_set(curr->se.statistics.exec_max,
+                       max(curr->se.statistics.exec_max, delta_exec));
+
+       curr->se.sum_exec_runtime += delta_exec;
+       account_group_exec_runtime(curr, delta_exec);
+
+       curr->se.exec_start = rq->clock_task;
+       cpuacct_charge(curr, delta_exec);
 }
 
 static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued)
@@ -60,6 +77,9 @@ static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued)
 
 static void set_curr_task_stop(struct rq *rq)
 {
+       struct task_struct *stop = rq->stop;
+
+       stop->se.exec_start = rq->clock_task;
 }
 
 static void switched_to_stop(struct rq *rq, struct task_struct *p)
index 91d4e1742a0c4ec1cd8805b6663f5a95b5d42b3b..d320d44903bd0ab8ce3a1dc3e40dee28a26e714f 100644 (file)
@@ -75,6 +75,7 @@ void task_work_run(void)
                        p = q->next;
                        q->func(q);
                        q = p;
+                       cond_resched();
                }
        }
 }
index a470154e040826f9549e5faf9ed4aefd174de698..46da0537c10b4d78e3c5645d8b709bb3503cc2af 100644 (file)
@@ -37,7 +37,7 @@
  * requested HZ value. It is also not recommended
  * for "tick-less" systems.
  */
-#define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/ACTHZ))
+#define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/SHIFTED_HZ))
 
 /* Since jiffies uses a simple NSEC_PER_JIFFY multiplier
  * conversion, the .shift value could be zero. However
index b7fbadc5c973c928e531cf6d701f1520e4809812..24174b4d669b1280c632d4ed0126dc2f1bb297ef 100644 (file)
@@ -28,7 +28,7 @@ DEFINE_SPINLOCK(ntp_lock);
 /* USER_HZ period (usecs): */
 unsigned long                  tick_usec = TICK_USEC;
 
-/* ACTHZ period (nsecs): */
+/* SHIFTED_HZ period (nsecs): */
 unsigned long                  tick_nsec;
 
 static u64                     tick_length;
index f045cc50832d0fc8aee045755d3ba60d655f2647..34e5eac81424d98738246415a85d1a98a042bef1 100644 (file)
@@ -65,14 +65,14 @@ struct timekeeper {
         * used instead.
         */
        struct timespec         wall_to_monotonic;
-       /* time spent in suspend */
-       struct timespec         total_sleep_time;
-       /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */
-       struct timespec         raw_time;
        /* Offset clock monotonic -> clock realtime */
        ktime_t                 offs_real;
+       /* time spent in suspend */
+       struct timespec         total_sleep_time;
        /* Offset clock monotonic -> clock boottime */
        ktime_t                 offs_boot;
+       /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */
+       struct timespec         raw_time;
        /* Seqlock for all timekeeper values */
        seqlock_t               lock;
 };
@@ -108,13 +108,39 @@ static struct timespec tk_xtime(struct timekeeper *tk)
 static void tk_set_xtime(struct timekeeper *tk, const struct timespec *ts)
 {
        tk->xtime_sec = ts->tv_sec;
-       tk->xtime_nsec = ts->tv_nsec << tk->shift;
+       tk->xtime_nsec = (u64)ts->tv_nsec << tk->shift;
 }
 
 static void tk_xtime_add(struct timekeeper *tk, const struct timespec *ts)
 {
        tk->xtime_sec += ts->tv_sec;
-       tk->xtime_nsec += ts->tv_nsec << tk->shift;
+       tk->xtime_nsec += (u64)ts->tv_nsec << tk->shift;
+       tk_normalize_xtime(tk);
+}
+
+static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec wtm)
+{
+       struct timespec tmp;
+
+       /*
+        * Verify consistency of: offset_real = -wall_to_monotonic
+        * before modifying anything
+        */
+       set_normalized_timespec(&tmp, -tk->wall_to_monotonic.tv_sec,
+                                       -tk->wall_to_monotonic.tv_nsec);
+       WARN_ON_ONCE(tk->offs_real.tv64 != timespec_to_ktime(tmp).tv64);
+       tk->wall_to_monotonic = wtm;
+       set_normalized_timespec(&tmp, -wtm.tv_sec, -wtm.tv_nsec);
+       tk->offs_real = timespec_to_ktime(tmp);
+}
+
+static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t)
+{
+       /* Verify consistency before modifying */
+       WARN_ON_ONCE(tk->offs_boot.tv64 != timespec_to_ktime(tk->total_sleep_time).tv64);
+
+       tk->total_sleep_time    = t;
+       tk->offs_boot           = timespec_to_ktime(t);
 }
 
 /**
@@ -217,14 +243,6 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
        return nsec + arch_gettimeoffset();
 }
 
-static void update_rt_offset(struct timekeeper *tk)
-{
-       struct timespec tmp, *wtm = &tk->wall_to_monotonic;
-
-       set_normalized_timespec(&tmp, -wtm->tv_sec, -wtm->tv_nsec);
-       tk->offs_real = timespec_to_ktime(tmp);
-}
-
 /* must hold write on timekeeper.lock */
 static void timekeeping_update(struct timekeeper *tk, bool clearntp)
 {
@@ -234,12 +252,10 @@ static void timekeeping_update(struct timekeeper *tk, bool clearntp)
                tk->ntp_error = 0;
                ntp_clear();
        }
-       update_rt_offset(tk);
        xt = tk_xtime(tk);
        update_vsyscall(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult);
 }
 
-
 /**
  * timekeeping_forward_now - update clock to the current time
  *
@@ -261,7 +277,7 @@ static void timekeeping_forward_now(struct timekeeper *tk)
        tk->xtime_nsec += cycle_delta * tk->mult;
 
        /* If arch requires, add in gettimeoffset() */
-       tk->xtime_nsec += arch_gettimeoffset() << tk->shift;
+       tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift;
 
        tk_normalize_xtime(tk);
 
@@ -277,18 +293,19 @@ static void timekeeping_forward_now(struct timekeeper *tk)
  */
 void getnstimeofday(struct timespec *ts)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long seq;
        s64 nsecs = 0;
 
        WARN_ON(timekeeping_suspended);
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
+               seq = read_seqbegin(&tk->lock);
 
-               ts->tv_sec = timekeeper.xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(&timekeeper);
+               ts->tv_sec = tk->xtime_sec;
+               ts->tv_nsec = timekeeping_get_ns(tk);
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
 
        timespec_add_ns(ts, nsecs);
 }
@@ -296,19 +313,18 @@ EXPORT_SYMBOL(getnstimeofday);
 
 ktime_t ktime_get(void)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned int seq;
        s64 secs, nsecs;
 
        WARN_ON(timekeeping_suspended);
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
-               secs = timekeeper.xtime_sec +
-                               timekeeper.wall_to_monotonic.tv_sec;
-               nsecs = timekeeping_get_ns(&timekeeper) +
-                               timekeeper.wall_to_monotonic.tv_nsec;
+               seq = read_seqbegin(&tk->lock);
+               secs = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
+               nsecs = timekeeping_get_ns(tk) + tk->wall_to_monotonic.tv_nsec;
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
        /*
         * Use ktime_set/ktime_add_ns to create a proper ktime on
         * 32-bit architectures without CONFIG_KTIME_SCALAR.
@@ -327,18 +343,19 @@ EXPORT_SYMBOL_GPL(ktime_get);
  */
 void ktime_get_ts(struct timespec *ts)
 {
+       struct timekeeper *tk = &timekeeper;
        struct timespec tomono;
        unsigned int seq;
 
        WARN_ON(timekeeping_suspended);
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
-               ts->tv_sec = timekeeper.xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(&timekeeper);
-               tomono = timekeeper.wall_to_monotonic;
+               seq = read_seqbegin(&tk->lock);
+               ts->tv_sec = tk->xtime_sec;
+               ts->tv_nsec = timekeeping_get_ns(tk);
+               tomono = tk->wall_to_monotonic;
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
 
        set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
                                ts->tv_nsec + tomono.tv_nsec);
@@ -358,22 +375,23 @@ EXPORT_SYMBOL_GPL(ktime_get_ts);
  */
 void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long seq;
        s64 nsecs_raw, nsecs_real;
 
        WARN_ON_ONCE(timekeeping_suspended);
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
+               seq = read_seqbegin(&tk->lock);
 
-               *ts_raw = timekeeper.raw_time;
-               ts_real->tv_sec = timekeeper.xtime_sec;
+               *ts_raw = tk->raw_time;
+               ts_real->tv_sec = tk->xtime_sec;
                ts_real->tv_nsec = 0;
 
-               nsecs_raw = timekeeping_get_ns_raw(&timekeeper);
-               nsecs_real = timekeeping_get_ns(&timekeeper);
+               nsecs_raw = timekeeping_get_ns_raw(tk);
+               nsecs_real = timekeeping_get_ns(tk);
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
 
        timespec_add_ns(ts_raw, nsecs_raw);
        timespec_add_ns(ts_real, nsecs_real);
@@ -406,28 +424,28 @@ EXPORT_SYMBOL(do_gettimeofday);
  */
 int do_settimeofday(const struct timespec *tv)
 {
+       struct timekeeper *tk = &timekeeper;
        struct timespec ts_delta, xt;
        unsigned long flags;
 
-       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+       if (!timespec_valid_strict(tv))
                return -EINVAL;
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
+       write_seqlock_irqsave(&tk->lock, flags);
 
-       timekeeping_forward_now(&timekeeper);
+       timekeeping_forward_now(tk);
 
-       xt = tk_xtime(&timekeeper);
+       xt = tk_xtime(tk);
        ts_delta.tv_sec = tv->tv_sec - xt.tv_sec;
        ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec;
 
-       timekeeper.wall_to_monotonic =
-                       timespec_sub(timekeeper.wall_to_monotonic, ts_delta);
+       tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, ts_delta));
 
-       tk_set_xtime(&timekeeper, tv);
+       tk_set_xtime(tk, tv);
 
-       timekeeping_update(&timekeeper, true);
+       timekeeping_update(tk, true);
 
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+       write_sequnlock_irqrestore(&tk->lock, flags);
 
        /* signal hrtimers about time change */
        clock_was_set();
@@ -436,7 +454,6 @@ int do_settimeofday(const struct timespec *tv)
 }
 EXPORT_SYMBOL(do_settimeofday);
 
-
 /**
  * timekeeping_inject_offset - Adds or subtracts from the current time.
  * @tv:                pointer to the timespec variable containing the offset
@@ -445,28 +462,37 @@ EXPORT_SYMBOL(do_settimeofday);
  */
 int timekeeping_inject_offset(struct timespec *ts)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long flags;
+       struct timespec tmp;
+       int ret = 0;
 
        if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
                return -EINVAL;
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
+       write_seqlock_irqsave(&tk->lock, flags);
 
-       timekeeping_forward_now(&timekeeper);
+       timekeeping_forward_now(tk);
 
+       /* Make sure the proposed value is valid */
+       tmp = timespec_add(tk_xtime(tk),  *ts);
+       if (!timespec_valid_strict(&tmp)) {
+               ret = -EINVAL;
+               goto error;
+       }
 
-       tk_xtime_add(&timekeeper, ts);
-       timekeeper.wall_to_monotonic =
-                               timespec_sub(timekeeper.wall_to_monotonic, *ts);
+       tk_xtime_add(tk, ts);
+       tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts));
 
-       timekeeping_update(&timekeeper, true);
+error: /* even if we error out, we forwarded the time, so call update */
+       timekeeping_update(tk, true);
 
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+       write_sequnlock_irqrestore(&tk->lock, flags);
 
        /* signal hrtimers about time change */
        clock_was_set();
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL(timekeeping_inject_offset);
 
@@ -477,23 +503,24 @@ EXPORT_SYMBOL(timekeeping_inject_offset);
  */
 static int change_clocksource(void *data)
 {
+       struct timekeeper *tk = &timekeeper;
        struct clocksource *new, *old;
        unsigned long flags;
 
        new = (struct clocksource *) data;
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
+       write_seqlock_irqsave(&tk->lock, flags);
 
-       timekeeping_forward_now(&timekeeper);
+       timekeeping_forward_now(tk);
        if (!new->enable || new->enable(new) == 0) {
-               old = timekeeper.clock;
-               tk_setup_internals(&timekeeper, new);
+               old = tk->clock;
+               tk_setup_internals(tk, new);
                if (old->disable)
                        old->disable(old);
        }
-       timekeeping_update(&timekeeper, true);
+       timekeeping_update(tk, true);
 
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+       write_sequnlock_irqrestore(&tk->lock, flags);
 
        return 0;
 }
@@ -507,7 +534,9 @@ static int change_clocksource(void *data)
  */
 void timekeeping_notify(struct clocksource *clock)
 {
-       if (timekeeper.clock == clock)
+       struct timekeeper *tk = &timekeeper;
+
+       if (tk->clock == clock)
                return;
        stop_machine(change_clocksource, clock, NULL);
        tick_clock_notify();
@@ -536,35 +565,36 @@ EXPORT_SYMBOL_GPL(ktime_get_real);
  */
 void getrawmonotonic(struct timespec *ts)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long seq;
        s64 nsecs;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
-               nsecs = timekeeping_get_ns_raw(&timekeeper);
-               *ts = timekeeper.raw_time;
+               seq = read_seqbegin(&tk->lock);
+               nsecs = timekeeping_get_ns_raw(tk);
+               *ts = tk->raw_time;
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
 
        timespec_add_ns(ts, nsecs);
 }
 EXPORT_SYMBOL(getrawmonotonic);
 
-
 /**
  * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
  */
 int timekeeping_valid_for_hres(void)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long seq;
        int ret;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
+               seq = read_seqbegin(&tk->lock);
 
-               ret = timekeeper.clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
+               ret = tk->clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
 
        return ret;
 }
@@ -574,15 +604,16 @@ int timekeeping_valid_for_hres(void)
  */
 u64 timekeeping_max_deferment(void)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long seq;
        u64 ret;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
+               seq = read_seqbegin(&tk->lock);
 
-               ret = timekeeper.clock->max_idle_ns;
+               ret = tk->clock->max_idle_ns;
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
 
        return ret;
 }
@@ -622,46 +653,56 @@ void __attribute__((weak)) read_boot_clock(struct timespec *ts)
  */
 void __init timekeeping_init(void)
 {
+       struct timekeeper *tk = &timekeeper;
        struct clocksource *clock;
        unsigned long flags;
-       struct timespec now, boot;
+       struct timespec now, boot, tmp;
 
        read_persistent_clock(&now);
+       if (!timespec_valid_strict(&now)) {
+               pr_warn("WARNING: Persistent clock returned invalid value!\n"
+                       "         Check your CMOS/BIOS settings.\n");
+               now.tv_sec = 0;
+               now.tv_nsec = 0;
+       }
+
        read_boot_clock(&boot);
+       if (!timespec_valid_strict(&boot)) {
+               pr_warn("WARNING: Boot clock returned invalid value!\n"
+                       "         Check your CMOS/BIOS settings.\n");
+               boot.tv_sec = 0;
+               boot.tv_nsec = 0;
+       }
 
-       seqlock_init(&timekeeper.lock);
+       seqlock_init(&tk->lock);
 
        ntp_init();
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
+       write_seqlock_irqsave(&tk->lock, flags);
        clock = clocksource_default_clock();
        if (clock->enable)
                clock->enable(clock);
-       tk_setup_internals(&timekeeper, clock);
+       tk_setup_internals(tk, clock);
 
-       tk_set_xtime(&timekeeper, &now);
-       timekeeper.raw_time.tv_sec = 0;
-       timekeeper.raw_time.tv_nsec = 0;
+       tk_set_xtime(tk, &now);
+       tk->raw_time.tv_sec = 0;
+       tk->raw_time.tv_nsec = 0;
        if (boot.tv_sec == 0 && boot.tv_nsec == 0)
-               boot = tk_xtime(&timekeeper);
-
-       set_normalized_timespec(&timekeeper.wall_to_monotonic,
-                               -boot.tv_sec, -boot.tv_nsec);
-       update_rt_offset(&timekeeper);
-       timekeeper.total_sleep_time.tv_sec = 0;
-       timekeeper.total_sleep_time.tv_nsec = 0;
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+               boot = tk_xtime(tk);
+
+       set_normalized_timespec(&tmp, -boot.tv_sec, -boot.tv_nsec);
+       tk_set_wall_to_mono(tk, tmp);
+
+       tmp.tv_sec = 0;
+       tmp.tv_nsec = 0;
+       tk_set_sleep_time(tk, tmp);
+
+       write_sequnlock_irqrestore(&tk->lock, flags);
 }
 
 /* time in seconds when suspend began */
 static struct timespec timekeeping_suspend_time;
 
-static void update_sleep_time(struct timespec t)
-{
-       timekeeper.total_sleep_time = t;
-       timekeeper.offs_boot = timespec_to_ktime(t);
-}
-
 /**
  * __timekeeping_inject_sleeptime - Internal function to add sleep interval
  * @delta: pointer to a timespec delta value
@@ -672,18 +713,16 @@ static void update_sleep_time(struct timespec t)
 static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
                                                        struct timespec *delta)
 {
-       if (!timespec_valid(delta)) {
+       if (!timespec_valid_strict(delta)) {
                printk(KERN_WARNING "__timekeeping_inject_sleeptime: Invalid "
                                        "sleep delta value!\n");
                return;
        }
-
        tk_xtime_add(tk, delta);
-       tk->wall_to_monotonic = timespec_sub(tk->wall_to_monotonic, *delta);
-       update_sleep_time(timespec_add(tk->total_sleep_time, *delta));
+       tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *delta));
+       tk_set_sleep_time(tk, timespec_add(tk->total_sleep_time, *delta));
 }
 
-
 /**
  * timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values
  * @delta: pointer to a timespec delta value
@@ -696,6 +735,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
  */
 void timekeeping_inject_sleeptime(struct timespec *delta)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long flags;
        struct timespec ts;
 
@@ -704,21 +744,20 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
        if (!(ts.tv_sec == 0 && ts.tv_nsec == 0))
                return;
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
+       write_seqlock_irqsave(&tk->lock, flags);
 
-       timekeeping_forward_now(&timekeeper);
+       timekeeping_forward_now(tk);
 
-       __timekeeping_inject_sleeptime(&timekeeper, delta);
+       __timekeeping_inject_sleeptime(tk, delta);
 
-       timekeeping_update(&timekeeper, true);
+       timekeeping_update(tk, true);
 
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+       write_sequnlock_irqrestore(&tk->lock, flags);
 
        /* signal hrtimers about time change */
        clock_was_set();
 }
 
-
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
  *
@@ -728,6 +767,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
  */
 static void timekeeping_resume(void)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long flags;
        struct timespec ts;
 
@@ -735,18 +775,18 @@ static void timekeeping_resume(void)
 
        clocksource_resume();
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
+       write_seqlock_irqsave(&tk->lock, flags);
 
        if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
                ts = timespec_sub(ts, timekeeping_suspend_time);
-               __timekeeping_inject_sleeptime(&timekeeper, &ts);
+               __timekeeping_inject_sleeptime(tk, &ts);
        }
        /* re-base the last cycle value */
-       timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
-       timekeeper.ntp_error = 0;
+       tk->clock->cycle_last = tk->clock->read(tk->clock);
+       tk->ntp_error = 0;
        timekeeping_suspended = 0;
-       timekeeping_update(&timekeeper, false);
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+       timekeeping_update(tk, false);
+       write_sequnlock_irqrestore(&tk->lock, flags);
 
        touch_softlockup_watchdog();
 
@@ -758,14 +798,15 @@ static void timekeeping_resume(void)
 
 static int timekeeping_suspend(void)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long flags;
        struct timespec         delta, delta_delta;
        static struct timespec  old_delta;
 
        read_persistent_clock(&timekeeping_suspend_time);
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
-       timekeeping_forward_now(&timekeeper);
+       write_seqlock_irqsave(&tk->lock, flags);
+       timekeeping_forward_now(tk);
        timekeeping_suspended = 1;
 
        /*
@@ -774,7 +815,7 @@ static int timekeeping_suspend(void)
         * try to compensate so the difference in system time
         * and persistent_clock time stays close to constant.
         */
-       delta = timespec_sub(tk_xtime(&timekeeper), timekeeping_suspend_time);
+       delta = timespec_sub(tk_xtime(tk), timekeeping_suspend_time);
        delta_delta = timespec_sub(delta, old_delta);
        if (abs(delta_delta.tv_sec)  >= 2) {
                /*
@@ -787,7 +828,7 @@ static int timekeeping_suspend(void)
                timekeeping_suspend_time =
                        timespec_add(timekeeping_suspend_time, delta_delta);
        }
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+       write_sequnlock_irqrestore(&tk->lock, flags);
 
        clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
        clocksource_suspend();
@@ -898,27 +939,29 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
                 * the error. This causes the likely below to be unlikely.
                 *
                 * The proper fix is to avoid rounding up by using
-                * the high precision timekeeper.xtime_nsec instead of
+                * the high precision tk->xtime_nsec instead of
                 * xtime.tv_nsec everywhere. Fixing this will take some
                 * time.
                 */
                if (likely(error <= interval))
                        adj = 1;
                else
-                       adj = timekeeping_bigadjust(tk, error, &interval,
-                                                       &offset);
-       } else if (error < -interval) {
-               /* See comment above, this is just switched for the negative */
-               error >>= 2;
-               if (likely(error >= -interval)) {
-                       adj = -1;
-                       interval = -interval;
-                       offset = -offset;
-               } else
-                       adj = timekeeping_bigadjust(tk, error, &interval,
-                                                       &offset);
-       } else
-               return;
+                       adj = timekeeping_bigadjust(tk, error, &interval, &offset);
+       } else {
+               if (error < -interval) {
+                       /* See comment above, this is just switched for the negative */
+                       error >>= 2;
+                       if (likely(error >= -interval)) {
+                               adj = -1;
+                               interval = -interval;
+                               offset = -offset;
+                       } else {
+                               adj = timekeeping_bigadjust(tk, error, &interval, &offset);
+                       }
+               } else {
+                       goto out_adjust;
+               }
+       }
 
        if (unlikely(tk->clock->maxadj &&
                (tk->mult + adj > tk->clock->mult + tk->clock->maxadj))) {
@@ -981,6 +1024,7 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
        tk->xtime_nsec -= offset;
        tk->ntp_error -= (interval - offset) << tk->ntp_error_shift;
 
+out_adjust:
        /*
         * It may be possible that when we entered this function, xtime_nsec
         * was very small.  Further, if we're slightly speeding the clocksource
@@ -1003,7 +1047,6 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
 
 }
 
-
 /**
  * accumulate_nsecs_to_secs - Accumulates nsecs into secs
  *
@@ -1024,15 +1067,21 @@ static inline void accumulate_nsecs_to_secs(struct timekeeper *tk)
 
                /* Figure out if its a leap sec and apply if needed */
                leap = second_overflow(tk->xtime_sec);
-               tk->xtime_sec += leap;
-               tk->wall_to_monotonic.tv_sec -= leap;
-               if (leap)
-                       clock_was_set_delayed();
+               if (unlikely(leap)) {
+                       struct timespec ts;
+
+                       tk->xtime_sec += leap;
+
+                       ts.tv_sec = leap;
+                       ts.tv_nsec = 0;
+                       tk_set_wall_to_mono(tk,
+                               timespec_sub(tk->wall_to_monotonic, ts));
 
+                       clock_was_set_delayed();
+               }
        }
 }
 
-
 /**
  * logarithmic_accumulation - shifted accumulation of cycles
  *
@@ -1076,7 +1125,6 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset,
        return offset;
 }
 
-
 /**
  * update_wall_time - Uses the current clocksource to increment the wall time
  *
@@ -1084,25 +1132,30 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset,
 static void update_wall_time(void)
 {
        struct clocksource *clock;
+       struct timekeeper *tk = &timekeeper;
        cycle_t offset;
        int shift = 0, maxshift;
        unsigned long flags;
        s64 remainder;
 
-       write_seqlock_irqsave(&timekeeper.lock, flags);
+       write_seqlock_irqsave(&tk->lock, flags);
 
        /* Make sure we're fully resumed: */
        if (unlikely(timekeeping_suspended))
                goto out;
 
-       clock = timekeeper.clock;
+       clock = tk->clock;
 
 #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
-       offset = timekeeper.cycle_interval;
+       offset = tk->cycle_interval;
 #else
        offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
 #endif
 
+       /* Check if there's really nothing to do */
+       if (offset < tk->cycle_interval)
+               goto out;
+
        /*
         * With NO_HZ we may have to accumulate many cycle_intervals
         * (think "ticks") worth of time at once. To do this efficiently,
@@ -1111,19 +1164,19 @@ static void update_wall_time(void)
         * chunk in one go, and then try to consume the next smaller
         * doubled multiple.
         */
-       shift = ilog2(offset) - ilog2(timekeeper.cycle_interval);
+       shift = ilog2(offset) - ilog2(tk->cycle_interval);
        shift = max(0, shift);
        /* Bound shift to one less than what overflows tick_length */
        maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1;
        shift = min(shift, maxshift);
-       while (offset >= timekeeper.cycle_interval) {
-               offset = logarithmic_accumulation(&timekeeper, offset, shift);
-               if(offset < timekeeper.cycle_interval<<shift)
+       while (offset >= tk->cycle_interval) {
+               offset = logarithmic_accumulation(tk, offset, shift);
+               if (offset < tk->cycle_interval<<shift)
                        shift--;
        }
 
        /* correct the clock when NTP error is too big */
-       timekeeping_adjust(&timekeeper, offset);
+       timekeeping_adjust(tk, offset);
 
 
        /*
@@ -1135,21 +1188,21 @@ static void update_wall_time(void)
        * the vsyscall implementations are converted to use xtime_nsec
        * (shifted nanoseconds), this can be killed.
        */
-       remainder = timekeeper.xtime_nsec & ((1 << timekeeper.shift) - 1);
-       timekeeper.xtime_nsec -= remainder;
-       timekeeper.xtime_nsec += 1 << timekeeper.shift;
-       timekeeper.ntp_error += remainder << timekeeper.ntp_error_shift;
+       remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1);
+       tk->xtime_nsec -= remainder;
+       tk->xtime_nsec += 1ULL << tk->shift;
+       tk->ntp_error += remainder << tk->ntp_error_shift;
 
        /*
         * Finally, make sure that after the rounding
         * xtime_nsec isn't larger than NSEC_PER_SEC
         */
-       accumulate_nsecs_to_secs(&timekeeper);
+       accumulate_nsecs_to_secs(tk);
 
-       timekeeping_update(&timekeeper, false);
+       timekeeping_update(tk, false);
 
 out:
-       write_sequnlock_irqrestore(&timekeeper.lock, flags);
+       write_sequnlock_irqrestore(&tk->lock, flags);
 
 }
 
@@ -1166,18 +1219,18 @@ out:
  */
 void getboottime(struct timespec *ts)
 {
+       struct timekeeper *tk = &timekeeper;
        struct timespec boottime = {
-               .tv_sec = timekeeper.wall_to_monotonic.tv_sec +
-                               timekeeper.total_sleep_time.tv_sec,
-               .tv_nsec = timekeeper.wall_to_monotonic.tv_nsec +
-                               timekeeper.total_sleep_time.tv_nsec
+               .tv_sec = tk->wall_to_monotonic.tv_sec +
+                               tk->total_sleep_time.tv_sec,
+               .tv_nsec = tk->wall_to_monotonic.tv_nsec +
+                               tk->total_sleep_time.tv_nsec
        };
 
        set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec);
 }
 EXPORT_SYMBOL_GPL(getboottime);
 
-
 /**
  * get_monotonic_boottime - Returns monotonic time since boot
  * @ts:                pointer to the timespec to be set
@@ -1189,19 +1242,20 @@ EXPORT_SYMBOL_GPL(getboottime);
  */
 void get_monotonic_boottime(struct timespec *ts)
 {
+       struct timekeeper *tk = &timekeeper;
        struct timespec tomono, sleep;
        unsigned int seq;
 
        WARN_ON(timekeeping_suspended);
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
-               ts->tv_sec = timekeeper.xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(&timekeeper);
-               tomono = timekeeper.wall_to_monotonic;
-               sleep = timekeeper.total_sleep_time;
+               seq = read_seqbegin(&tk->lock);
+               ts->tv_sec = tk->xtime_sec;
+               ts->tv_nsec = timekeeping_get_ns(tk);
+               tomono = tk->wall_to_monotonic;
+               sleep = tk->total_sleep_time;
 
-       } while (read_seqretry(&timekeeper.lock, seq));
+       } while (read_seqretry(&tk->lock, seq));
 
        set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec,
                        ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec);
@@ -1231,31 +1285,38 @@ EXPORT_SYMBOL_GPL(ktime_get_boottime);
  */
 void monotonic_to_bootbased(struct timespec *ts)
 {
-       *ts = timespec_add(*ts, timekeeper.total_sleep_time);
+       struct timekeeper *tk = &timekeeper;
+
+       *ts = timespec_add(*ts, tk->total_sleep_time);
 }
 EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
 
 unsigned long get_seconds(void)
 {
-       return timekeeper.xtime_sec;
+       struct timekeeper *tk = &timekeeper;
+
+       return tk->xtime_sec;
 }
 EXPORT_SYMBOL(get_seconds);
 
 struct timespec __current_kernel_time(void)
 {
-       return tk_xtime(&timekeeper);
+       struct timekeeper *tk = &timekeeper;
+
+       return tk_xtime(tk);
 }
 
 struct timespec current_kernel_time(void)
 {
+       struct timekeeper *tk = &timekeeper;
        struct timespec now;
        unsigned long seq;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
+               seq = read_seqbegin(&tk->lock);
 
-               now = tk_xtime(&timekeeper);
-       } while (read_seqretry(&timekeeper.lock, seq));
+               now = tk_xtime(tk);
+       } while (read_seqretry(&tk->lock, seq));
 
        return now;
 }
@@ -1263,15 +1324,16 @@ EXPORT_SYMBOL(current_kernel_time);
 
 struct timespec get_monotonic_coarse(void)
 {
+       struct timekeeper *tk = &timekeeper;
        struct timespec now, mono;
        unsigned long seq;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
+               seq = read_seqbegin(&tk->lock);
 
-               now = tk_xtime(&timekeeper);
-               mono = timekeeper.wall_to_monotonic;
-       } while (read_seqretry(&timekeeper.lock, seq));
+               now = tk_xtime(tk);
+               mono = tk->wall_to_monotonic;
+       } while (read_seqretry(&tk->lock, seq));
 
        set_normalized_timespec(&now, now.tv_sec + mono.tv_sec,
                                now.tv_nsec + mono.tv_nsec);
@@ -1300,14 +1362,15 @@ void do_timer(unsigned long ticks)
 void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
                                struct timespec *wtom, struct timespec *sleep)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long seq;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
-               *xtim = tk_xtime(&timekeeper);
-               *wtom = timekeeper.wall_to_monotonic;
-               *sleep = timekeeper.total_sleep_time;
-       } while (read_seqretry(&timekeeper.lock, seq));
+               seq = read_seqbegin(&tk->lock);
+               *xtim = tk_xtime(tk);
+               *wtom = tk->wall_to_monotonic;
+               *sleep = tk->total_sleep_time;
+       } while (read_seqretry(&tk->lock, seq));
 }
 
 #ifdef CONFIG_HIGH_RES_TIMERS
@@ -1321,19 +1384,20 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
  */
 ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot)
 {
+       struct timekeeper *tk = &timekeeper;
        ktime_t now;
        unsigned int seq;
        u64 secs, nsecs;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
+               seq = read_seqbegin(&tk->lock);
 
-               secs = timekeeper.xtime_sec;
-               nsecs = timekeeping_get_ns(&timekeeper);
+               secs = tk->xtime_sec;
+               nsecs = timekeeping_get_ns(tk);
 
-               *offs_real = timekeeper.offs_real;
-               *offs_boot = timekeeper.offs_boot;
-       } while (read_seqretry(&timekeeper.lock, seq));
+               *offs_real = tk->offs_real;
+               *offs_boot = tk->offs_boot;
+       } while (read_seqretry(&tk->lock, seq));
 
        now = ktime_add_ns(ktime_set(secs, 0), nsecs);
        now = ktime_sub(now, *offs_real);
@@ -1346,19 +1410,19 @@ ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot)
  */
 ktime_t ktime_get_monotonic_offset(void)
 {
+       struct timekeeper *tk = &timekeeper;
        unsigned long seq;
        struct timespec wtom;
 
        do {
-               seq = read_seqbegin(&timekeeper.lock);
-               wtom = timekeeper.wall_to_monotonic;
-       } while (read_seqretry(&timekeeper.lock, seq));
+               seq = read_seqbegin(&tk->lock);
+               wtom = tk->wall_to_monotonic;
+       } while (read_seqretry(&tk->lock, seq));
 
        return timespec_to_ktime(wtom);
 }
 EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset);
 
-
 /**
  * xtime_update() - advances the timekeeping infrastructure
  * @ticks:     number of ticks, that have elapsed since the last call.
index a61c09374ebab1fdba0bdd370b56cf70018de62d..8c5e7b908c6814ed5342e63c65b69d4acb9ea037 100644 (file)
@@ -1407,13 +1407,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, seconds)
 
 #endif
 
-#ifndef __alpha__
-
-/*
- * The Alpha uses getxpid, getxuid, and getxgid instead.  Maybe this
- * should be moved into arch/i386 instead?
- */
-
 /**
  * sys_getpid - return the thread group id of the current process
  *
@@ -1469,8 +1462,6 @@ SYSCALL_DEFINE0(getegid)
        return from_kgid_munged(current_user_ns(), current_egid());
 }
 
-#endif
-
 static void process_timeout(unsigned long __data)
 {
        wake_up_process((struct task_struct *)__data);
index fee3752ae8f66f5348199c67b6ad05c5a41346f5..8a6d2ee2086c2cd721dc29ae92d23082370e10db 100644 (file)
@@ -281,7 +281,7 @@ perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip)
 
        head = this_cpu_ptr(event_function.perf_events);
        perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, 0,
-                             1, &regs, head);
+                             1, &regs, head, NULL);
 
 #undef ENTRY_SIZE
 }
index b31d3d5699fea09c235ace4c47e16fc8fb8785e0..1a2117043bb140d06b366d8d6e0798bb69fcad26 100644 (file)
@@ -1002,7 +1002,8 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
        store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
        head = this_cpu_ptr(call->perf_events);
-       perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head);
+       perf_trace_buf_submit(entry, size, rctx,
+                                       entry->ip, 1, regs, head, NULL);
 }
 
 /* Kretprobe profile handler */
@@ -1033,7 +1034,8 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
        store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
        head = this_cpu_ptr(call->perf_events);
-       perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head);
+       perf_trace_buf_submit(entry, size, rctx,
+                                       entry->ret_ip, 1, regs, head, NULL);
 }
 #endif /* CONFIG_PERF_EVENTS */
 
index 96fc733690992bf97dc610c87ff2a6b0ecbb97d8..6b245f64c8dd850bbbd7a16132d997fccd25206e 100644 (file)
@@ -506,6 +506,8 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
        int size;
 
        syscall_nr = syscall_get_nr(current, regs);
+       if (syscall_nr < 0)
+               return;
        if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
                return;
 
@@ -532,7 +534,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
                               (unsigned long *)&rec->args);
 
        head = this_cpu_ptr(sys_data->enter_event->perf_events);
-       perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head);
+       perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL);
 }
 
 int perf_sysenter_enable(struct ftrace_event_call *call)
@@ -580,6 +582,8 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
        int size;
 
        syscall_nr = syscall_get_nr(current, regs);
+       if (syscall_nr < 0)
+               return;
        if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
                return;
 
@@ -608,7 +612,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
        rec->ret = syscall_get_return_value(current, regs);
 
        head = this_cpu_ptr(sys_data->exit_event->perf_events);
-       perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head);
+       perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL);
 }
 
 int perf_sysexit_enable(struct ftrace_event_call *call)
index 2b36ac68549e2e23d148c81b7905407d344fdc80..03003cd7dd962d1ca31b2574f9d09f77a74f47a4 100644 (file)
@@ -670,7 +670,7 @@ static void uprobe_perf_func(struct trace_uprobe *tu, struct pt_regs *regs)
                call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset);
 
        head = this_cpu_ptr(call->perf_events);
-       perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head);
+       perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head, NULL);
 
  out:
        preempt_enable();
index 69add8a9da686a326be90e45aa09ab8427a24875..4b1dfba70f7cf8ae7397623656a9b695028f702a 100644 (file)
@@ -575,7 +575,7 @@ out:
 /*
  * Create/destroy watchdog threads as CPUs come and go:
  */
-static int
+static int __cpuinit
 cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
        int hotcpu = (unsigned long)hcpu;
@@ -610,27 +610,10 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
        return NOTIFY_OK;
 }
 
-static struct notifier_block cpu_nfb = {
+static struct notifier_block __cpuinitdata cpu_nfb = {
        .notifier_call = cpu_callback
 };
 
-#ifdef CONFIG_SUSPEND
-/*
- * On exit from suspend we force an offline->online transition on the boot CPU
- * so that the PMU state that was lost while in suspended state gets set up
- * properly for the boot CPU.  This information is required for restarting the
- * NMI watchdog.
- */
-void lockup_detector_bootcpu_resume(void)
-{
-       void *cpu = (void *)(long)smp_processor_id();
-
-       cpu_callback(&cpu_nfb, CPU_DEAD_FROZEN, cpu);
-       cpu_callback(&cpu_nfb, CPU_UP_PREPARE_FROZEN, cpu);
-       cpu_callback(&cpu_nfb, CPU_ONLINE_FROZEN, cpu);
-}
-#endif
-
 void __init lockup_detector_init(void)
 {
        void *cpu = (void *)(long)smp_processor_id();
index 6b4718e2ee341d7fd7f068d83e31da014d1a5ef0..b41823cc05e61caf4b862418fde58a5025bfb748 100644 (file)
@@ -39,12 +39,6 @@ DEFINE_SPINLOCK(bdi_lock);
 LIST_HEAD(bdi_list);
 LIST_HEAD(bdi_pending_list);
 
-static struct task_struct *sync_supers_tsk;
-static struct timer_list sync_supers_timer;
-
-static int bdi_sync_supers(void *);
-static void sync_supers_timer_fn(unsigned long);
-
 void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2)
 {
        if (wb1 < wb2) {
@@ -250,12 +244,6 @@ static int __init default_bdi_init(void)
 {
        int err;
 
-       sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
-       BUG_ON(IS_ERR(sync_supers_tsk));
-
-       setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
-       bdi_arm_supers_timer();
-
        err = bdi_init(&default_backing_dev_info);
        if (!err)
                bdi_register(&default_backing_dev_info, NULL, "default");
@@ -270,46 +258,6 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi)
        return wb_has_dirty_io(&bdi->wb);
 }
 
-/*
- * kupdated() used to do this. We cannot do it from the bdi_forker_thread()
- * or we risk deadlocking on ->s_umount. The longer term solution would be
- * to implement sync_supers_bdi() or similar and simply do it from the
- * bdi writeback thread individually.
- */
-static int bdi_sync_supers(void *unused)
-{
-       set_user_nice(current, 0);
-
-       while (!kthread_should_stop()) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule();
-
-               /*
-                * Do this periodically, like kupdated() did before.
-                */
-               sync_supers();
-       }
-
-       return 0;
-}
-
-void bdi_arm_supers_timer(void)
-{
-       unsigned long next;
-
-       if (!dirty_writeback_interval)
-               return;
-
-       next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
-       mod_timer(&sync_supers_timer, round_jiffies_up(next));
-}
-
-static void sync_supers_timer_fn(unsigned long unused)
-{
-       wake_up_process(sync_supers_tsk);
-       bdi_arm_supers_timer();
-}
-
 static void wakeup_timer_fn(unsigned long data)
 {
        struct backing_dev_info *bdi = (struct backing_dev_info *)data;
index e78cb968842163ff65154346e6721aac91070319..7fcd3a52e68d4b2a9bfc07c1056b7db3a2b154b1 100644 (file)
@@ -50,6 +50,47 @@ static inline bool migrate_async_suitable(int migratetype)
        return is_migrate_cma(migratetype) || migratetype == MIGRATE_MOVABLE;
 }
 
+/*
+ * Compaction requires the taking of some coarse locks that are potentially
+ * very heavily contended. Check if the process needs to be scheduled or
+ * if the lock is contended. For async compaction, back out in the event
+ * if contention is severe. For sync compaction, schedule.
+ *
+ * Returns true if the lock is held.
+ * Returns false if the lock is released and compaction should abort
+ */
+static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
+                                     bool locked, struct compact_control *cc)
+{
+       if (need_resched() || spin_is_contended(lock)) {
+               if (locked) {
+                       spin_unlock_irqrestore(lock, *flags);
+                       locked = false;
+               }
+
+               /* async aborts if taking too long or contended */
+               if (!cc->sync) {
+                       if (cc->contended)
+                               *cc->contended = true;
+                       return false;
+               }
+
+               cond_resched();
+               if (fatal_signal_pending(current))
+                       return false;
+       }
+
+       if (!locked)
+               spin_lock_irqsave(lock, *flags);
+       return true;
+}
+
+static inline bool compact_trylock_irqsave(spinlock_t *lock,
+                       unsigned long *flags, struct compact_control *cc)
+{
+       return compact_checklock_irqsave(lock, flags, false, cc);
+}
+
 /*
  * Isolate free pages onto a private freelist. Caller must hold zone->lock.
  * If @strict is true, will abort returning 0 on any invalid PFNs or non-free
@@ -173,7 +214,7 @@ isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn)
 }
 
 /* Update the number of anon and file isolated pages in the zone */
-static void acct_isolated(struct zone *zone, struct compact_control *cc)
+static void acct_isolated(struct zone *zone, bool locked, struct compact_control *cc)
 {
        struct page *page;
        unsigned int count[2] = { 0, };
@@ -181,8 +222,14 @@ static void acct_isolated(struct zone *zone, struct compact_control *cc)
        list_for_each_entry(page, &cc->migratepages, lru)
                count[!!page_is_file_cache(page)]++;
 
-       __mod_zone_page_state(zone, NR_ISOLATED_ANON, count[0]);
-       __mod_zone_page_state(zone, NR_ISOLATED_FILE, count[1]);
+       /* If locked we can use the interrupt unsafe versions */
+       if (locked) {
+               __mod_zone_page_state(zone, NR_ISOLATED_ANON, count[0]);
+               __mod_zone_page_state(zone, NR_ISOLATED_FILE, count[1]);
+       } else {
+               mod_zone_page_state(zone, NR_ISOLATED_ANON, count[0]);
+               mod_zone_page_state(zone, NR_ISOLATED_FILE, count[1]);
+       }
 }
 
 /* Similar to reclaim, but different enough that they don't share logic */
@@ -228,6 +275,8 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
        struct list_head *migratelist = &cc->migratepages;
        isolate_mode_t mode = 0;
        struct lruvec *lruvec;
+       unsigned long flags;
+       bool locked;
 
        /*
         * Ensure that there are not too many pages isolated from the LRU
@@ -247,25 +296,22 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
 
        /* Time to isolate some pages for migration */
        cond_resched();
-       spin_lock_irq(&zone->lru_lock);
+       spin_lock_irqsave(&zone->lru_lock, flags);
+       locked = true;
        for (; low_pfn < end_pfn; low_pfn++) {
                struct page *page;
-               bool locked = true;
 
                /* give a chance to irqs before checking need_resched() */
                if (!((low_pfn+1) % SWAP_CLUSTER_MAX)) {
-                       spin_unlock_irq(&zone->lru_lock);
+                       spin_unlock_irqrestore(&zone->lru_lock, flags);
                        locked = false;
                }
-               if (need_resched() || spin_is_contended(&zone->lru_lock)) {
-                       if (locked)
-                               spin_unlock_irq(&zone->lru_lock);
-                       cond_resched();
-                       spin_lock_irq(&zone->lru_lock);
-                       if (fatal_signal_pending(current))
-                               break;
-               } else if (!locked)
-                       spin_lock_irq(&zone->lru_lock);
+
+               /* Check if it is ok to still hold the lock */
+               locked = compact_checklock_irqsave(&zone->lru_lock, &flags,
+                                                               locked, cc);
+               if (!locked)
+                       break;
 
                /*
                 * migrate_pfn does not necessarily start aligned to a
@@ -349,9 +395,10 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                }
        }
 
-       acct_isolated(zone, cc);
+       acct_isolated(zone, locked, cc);
 
-       spin_unlock_irq(&zone->lru_lock);
+       if (locked)
+               spin_unlock_irqrestore(&zone->lru_lock, flags);
 
        trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated);
 
@@ -383,6 +430,20 @@ static bool suitable_migration_target(struct page *page)
        return false;
 }
 
+/*
+ * Returns the start pfn of the last page block in a zone.  This is the starting
+ * point for full compaction of a zone.  Compaction searches for free pages from
+ * the end of each zone, while isolate_freepages_block scans forward inside each
+ * page block.
+ */
+static unsigned long start_free_pfn(struct zone *zone)
+{
+       unsigned long free_pfn;
+       free_pfn = zone->zone_start_pfn + zone->spanned_pages;
+       free_pfn &= ~(pageblock_nr_pages-1);
+       return free_pfn;
+}
+
 /*
  * Based on information in the current compact_control, find blocks
  * suitable for isolating free pages from and then isolate them.
@@ -422,17 +483,6 @@ static void isolate_freepages(struct zone *zone,
                                        pfn -= pageblock_nr_pages) {
                unsigned long isolated;
 
-               /*
-                * Skip ahead if another thread is compacting in the area
-                * simultaneously. If we wrapped around, we can only skip
-                * ahead if zone->compact_cached_free_pfn also wrapped to
-                * above our starting point.
-                */
-               if (cc->order > 0 && (!cc->wrapped ||
-                                     zone->compact_cached_free_pfn >
-                                     cc->start_free_pfn))
-                       pfn = min(pfn, zone->compact_cached_free_pfn);
-
                if (!pfn_valid(pfn))
                        continue;
 
@@ -458,7 +508,16 @@ static void isolate_freepages(struct zone *zone,
                 * are disabled
                 */
                isolated = 0;
-               spin_lock_irqsave(&zone->lock, flags);
+
+               /*
+                * The zone lock must be held to isolate freepages. This
+                * unfortunately this is a very coarse lock and can be
+                * heavily contended if there are parallel allocations
+                * or parallel compactions. For async compaction do not
+                * spin on the lock
+                */
+               if (!compact_trylock_irqsave(&zone->lock, &flags, cc))
+                       break;
                if (suitable_migration_target(page)) {
                        end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn);
                        isolated = isolate_freepages_block(pfn, end_pfn,
@@ -474,7 +533,15 @@ static void isolate_freepages(struct zone *zone,
                 */
                if (isolated) {
                        high_pfn = max(high_pfn, pfn);
-                       if (cc->order > 0)
+
+                       /*
+                        * If the free scanner has wrapped, update
+                        * compact_cached_free_pfn to point to the highest
+                        * pageblock with free pages. This reduces excessive
+                        * scanning of full pageblocks near the end of the
+                        * zone
+                        */
+                       if (cc->order > 0 && cc->wrapped)
                                zone->compact_cached_free_pfn = high_pfn;
                }
        }
@@ -484,6 +551,11 @@ static void isolate_freepages(struct zone *zone,
 
        cc->free_pfn = high_pfn;
        cc->nr_freepages = nr_freepages;
+
+       /* If compact_cached_free_pfn is reset then set it now */
+       if (cc->order > 0 && !cc->wrapped &&
+                       zone->compact_cached_free_pfn == start_free_pfn(zone))
+               zone->compact_cached_free_pfn = high_pfn;
 }
 
 /*
@@ -570,20 +642,6 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
        return ISOLATE_SUCCESS;
 }
 
-/*
- * Returns the start pfn of the last page block in a zone.  This is the starting
- * point for full compaction of a zone.  Compaction searches for free pages from
- * the end of each zone, while isolate_freepages_block scans forward inside each
- * page block.
- */
-static unsigned long start_free_pfn(struct zone *zone)
-{
-       unsigned long free_pfn;
-       free_pfn = zone->zone_start_pfn + zone->spanned_pages;
-       free_pfn &= ~(pageblock_nr_pages-1);
-       return free_pfn;
-}
-
 static int compact_finished(struct zone *zone,
                            struct compact_control *cc)
 {
@@ -771,7 +829,7 @@ out:
 
 static unsigned long compact_zone_order(struct zone *zone,
                                 int order, gfp_t gfp_mask,
-                                bool sync)
+                                bool sync, bool *contended)
 {
        struct compact_control cc = {
                .nr_freepages = 0,
@@ -780,6 +838,7 @@ static unsigned long compact_zone_order(struct zone *zone,
                .migratetype = allocflags_to_migratetype(gfp_mask),
                .zone = zone,
                .sync = sync,
+               .contended = contended,
        };
        INIT_LIST_HEAD(&cc.freepages);
        INIT_LIST_HEAD(&cc.migratepages);
@@ -801,7 +860,7 @@ int sysctl_extfrag_threshold = 500;
  */
 unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *nodemask,
-                       bool sync)
+                       bool sync, bool *contended)
 {
        enum zone_type high_zoneidx = gfp_zone(gfp_mask);
        int may_enter_fs = gfp_mask & __GFP_FS;
@@ -825,7 +884,8 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist,
                                                                nodemask) {
                int status;
 
-               status = compact_zone_order(zone, order, gfp_mask, sync);
+               status = compact_zone_order(zone, order, gfp_mask, sync,
+                                               contended);
                rc = max(status, rc);
 
                /* If a normal allocation would succeed, stop compacting */
@@ -861,7 +921,7 @@ static int __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
                if (cc->order > 0) {
                        int ok = zone_watermark_ok(zone, cc->order,
                                                low_wmark_pages(zone), 0, 0);
-                       if (ok && cc->order > zone->compact_order_failed)
+                       if (ok && cc->order >= zone->compact_order_failed)
                                zone->compact_order_failed = cc->order + 1;
                        /* Currently async compaction is never deferred. */
                        else if (!ok && cc->sync)
index fa5ca304148e7b4756bf2e52cd6afde1dba2b5c3..384344575c375e1a1464734670218557c31e0e27 100644 (file)
@@ -1412,12 +1412,8 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                        retval = filemap_write_and_wait_range(mapping, pos,
                                        pos + iov_length(iov, nr_segs) - 1);
                        if (!retval) {
-                               struct blk_plug plug;
-
-                               blk_start_plug(&plug);
                                retval = mapping->a_ops->direct_IO(READ, iocb,
                                                        iov, pos, nr_segs);
-                               blk_finish_plug(&plug);
                        }
                        if (retval > 0) {
                                *ppos = pos + retval;
@@ -2527,14 +2523,12 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_mapping->host;
-       struct blk_plug plug;
        ssize_t ret;
 
        BUG_ON(iocb->ki_pos != pos);
 
        sb_start_write(inode->i_sb);
        mutex_lock(&inode->i_mutex);
-       blk_start_plug(&plug);
        ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
        mutex_unlock(&inode->i_mutex);
 
@@ -2545,7 +2539,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
                if (err < 0 && ret > 0)
                        ret = err;
        }
-       blk_finish_plug(&plug);
        sb_end_write(inode->i_sb);
        return ret;
 }
index 3314f79d775a5f90c84e3250d8b93b7bd6f99933..b8c91b342e244153ec9b24b4673e6dd2575af267 100644 (file)
@@ -130,6 +130,7 @@ struct compact_control {
        int order;                      /* order a direct compactor needs */
        int migratetype;                /* MOVABLE, RECLAIMABLE etc */
        struct zone *zone;
+       bool *contended;                /* True if a lock was contended */
 };
 
 unsigned long
index e3e86914f11ad7d664ec73e08c98ee5670ef8e16..ae18a48e7e4e7944af308bbff226217ae7d1601e 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1356,9 +1356,8 @@ out:
        } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
                make_pages_present(addr, addr + len);
 
-       if (file && uprobe_mmap(vma))
-               /* matching probes but cannot insert */
-               goto unmap_and_free_vma;
+       if (file)
+               uprobe_mmap(vma);
 
        return addr;
 
@@ -2309,7 +2308,7 @@ void exit_mmap(struct mm_struct *mm)
        }
        vm_unacct_memory(nr_accounted);
 
-       BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
+       WARN_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
 }
 
 /* Insert vm structure into process list sorted by address
index e5363f34e0250656c357d965a2e8949577cfb607..5ad5ce23c1e082bc999222f42e542d942794c7c7 100644 (file)
@@ -1532,7 +1532,6 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write,
        void __user *buffer, size_t *length, loff_t *ppos)
 {
        proc_dointvec(table, write, buffer, length, ppos);
-       bdi_arm_supers_timer();
        return 0;
 }
 
index 009ac285fea79faca555fc074df33e60b3dc7827..c66fb875104ab99feccb0e116b48b9d54a6011e4 100644 (file)
@@ -1928,6 +1928,17 @@ this_zone_full:
                zlc_active = 0;
                goto zonelist_scan;
        }
+
+       if (page)
+               /*
+                * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was
+                * necessary to allocate the page. The expectation is
+                * that the caller is taking steps that will free more
+                * memory. The caller should avoid the page being used
+                * for !PFMEMALLOC purposes.
+                */
+               page->pfmemalloc = !!(alloc_flags & ALLOC_NO_WATERMARKS);
+
        return page;
 }
 
@@ -2091,7 +2102,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
        struct zonelist *zonelist, enum zone_type high_zoneidx,
        nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone,
        int migratetype, bool sync_migration,
-       bool *deferred_compaction,
+       bool *contended_compaction, bool *deferred_compaction,
        unsigned long *did_some_progress)
 {
        struct page *page;
@@ -2106,7 +2117,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
 
        current->flags |= PF_MEMALLOC;
        *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask,
-                                               nodemask, sync_migration);
+                                               nodemask, sync_migration,
+                                               contended_compaction);
        current->flags &= ~PF_MEMALLOC;
        if (*did_some_progress != COMPACT_SKIPPED) {
 
@@ -2152,7 +2164,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
        struct zonelist *zonelist, enum zone_type high_zoneidx,
        nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone,
        int migratetype, bool sync_migration,
-       bool *deferred_compaction,
+       bool *contended_compaction, bool *deferred_compaction,
        unsigned long *did_some_progress)
 {
        return NULL;
@@ -2325,6 +2337,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
        unsigned long did_some_progress;
        bool sync_migration = false;
        bool deferred_compaction = false;
+       bool contended_compaction = false;
 
        /*
         * In the slowpath, we sanity check order to avoid ever trying to
@@ -2389,14 +2402,6 @@ rebalance:
                                zonelist, high_zoneidx, nodemask,
                                preferred_zone, migratetype);
                if (page) {
-                       /*
-                        * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was
-                        * necessary to allocate the page. The expectation is
-                        * that the caller is taking steps that will free more
-                        * memory. The caller should avoid the page being used
-                        * for !PFMEMALLOC purposes.
-                        */
-                       page->pfmemalloc = true;
                        goto got_pg;
                }
        }
@@ -2422,6 +2427,7 @@ rebalance:
                                        nodemask,
                                        alloc_flags, preferred_zone,
                                        migratetype, sync_migration,
+                                       &contended_compaction,
                                        &deferred_compaction,
                                        &did_some_progress);
        if (page)
@@ -2431,10 +2437,11 @@ rebalance:
        /*
         * If compaction is deferred for high-order allocations, it is because
         * sync compaction recently failed. In this is the case and the caller
-        * has requested the system not be heavily disrupted, fail the
-        * allocation now instead of entering direct reclaim
+        * requested a movable allocation that does not heavily disrupt the
+        * system then fail the allocation instead of entering direct reclaim.
         */
-       if (deferred_compaction && (gfp_mask & __GFP_NO_KSWAPD))
+       if ((deferred_compaction || contended_compaction) &&
+                                               (gfp_mask & __GFP_NO_KSWAPD))
                goto nopage;
 
        /* Try direct reclaim and then allocating */
@@ -2505,6 +2512,7 @@ rebalance:
                                        nodemask,
                                        alloc_flags, preferred_zone,
                                        migratetype, sync_migration,
+                                       &contended_compaction,
                                        &deferred_compaction,
                                        &did_some_progress);
                if (page)
@@ -2569,8 +2577,6 @@ retry_cpuset:
                page = __alloc_pages_slowpath(gfp_mask, order,
                                zonelist, high_zoneidx, nodemask,
                                preferred_zone, migratetype);
-       else
-               page->pfmemalloc = false;
 
        trace_mm_page_alloc(page, order, gfp_mask, migratetype);
 
index f8b0d539b4822af7812c8f9edcb51224450f3f64..811af03a14ef168ca8e6ba90ec0af60b2dffa305 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3260,6 +3260,7 @@ force_grow:
 
                /* cache_grow can reenable interrupts, then ac could change. */
                ac = cpu_cache_get(cachep);
+               node = numa_mem_id();
 
                /* no objects in sight? abort */
                if (!x && (ac->avail == 0 || force_refill))
index 73a2a83ee2da51333731c4bb5f8307a78c2c5496..402442402af710d5acedf500347cca48f89a6be4 100644 (file)
@@ -137,9 +137,21 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
        return rc;
 }
 
+static inline netdev_tx_t vlan_netpoll_send_skb(struct vlan_dev_priv *vlan, struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       if (vlan->netpoll)
+               netpoll_send_skb(vlan->netpoll, skb);
+#else
+       BUG();
+#endif
+       return NETDEV_TX_OK;
+}
+
 static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
                                            struct net_device *dev)
 {
+       struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
        unsigned int len;
        int ret;
@@ -150,29 +162,30 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
         * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
         */
        if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
-           vlan_dev_priv(dev)->flags & VLAN_FLAG_REORDER_HDR) {
+           vlan->flags & VLAN_FLAG_REORDER_HDR) {
                u16 vlan_tci;
-               vlan_tci = vlan_dev_priv(dev)->vlan_id;
+               vlan_tci = vlan->vlan_id;
                vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
                skb = __vlan_hwaccel_put_tag(skb, vlan_tci);
        }
 
-       skb->dev = vlan_dev_priv(dev)->real_dev;
+       skb->dev = vlan->real_dev;
        len = skb->len;
-       if (netpoll_tx_running(dev))
-               return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
+       if (unlikely(netpoll_tx_running(dev)))
+               return vlan_netpoll_send_skb(vlan, skb);
+
        ret = dev_queue_xmit(skb);
 
        if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
                struct vlan_pcpu_stats *stats;
 
-               stats = this_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats);
+               stats = this_cpu_ptr(vlan->vlan_pcpu_stats);
                u64_stats_update_begin(&stats->syncp);
                stats->tx_packets++;
                stats->tx_bytes += len;
                u64_stats_update_end(&stats->syncp);
        } else {
-               this_cpu_inc(vlan_dev_priv(dev)->vlan_pcpu_stats->tx_dropped);
+               this_cpu_inc(vlan->vlan_pcpu_stats->tx_dropped);
        }
 
        return ret;
@@ -669,25 +682,26 @@ static void vlan_dev_poll_controller(struct net_device *dev)
        return;
 }
 
-static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo)
+static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo,
+                                 gfp_t gfp)
 {
-       struct vlan_dev_priv *info = vlan_dev_priv(dev);
-       struct net_device *real_dev = info->real_dev;
+       struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
+       struct net_device *real_dev = vlan->real_dev;
        struct netpoll *netpoll;
        int err = 0;
 
-       netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL);
+       netpoll = kzalloc(sizeof(*netpoll), gfp);
        err = -ENOMEM;
        if (!netpoll)
                goto out;
 
-       err = __netpoll_setup(netpoll, real_dev);
+       err = __netpoll_setup(netpoll, real_dev, gfp);
        if (err) {
                kfree(netpoll);
                goto out;
        }
 
-       info->netpoll = netpoll;
+       vlan->netpoll = netpoll;
 
 out:
        return err;
@@ -695,19 +709,15 @@ out:
 
 static void vlan_dev_netpoll_cleanup(struct net_device *dev)
 {
-       struct vlan_dev_priv *info = vlan_dev_priv(dev);
-       struct netpoll *netpoll = info->netpoll;
+       struct vlan_dev_priv *vlan= vlan_dev_priv(dev);
+       struct netpoll *netpoll = vlan->netpoll;
 
        if (!netpoll)
                return;
 
-       info->netpoll = NULL;
-
-        /* Wait for transmitting packets to finish before freeing. */
-        synchronize_rcu_bh();
+       vlan->netpoll = NULL;
 
-        __netpoll_cleanup(netpoll);
-        kfree(netpoll);
+       __netpoll_free_rcu(netpoll);
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 
index b4b44dbed645f74046ae4663a31b805a0ed72b52..0c0ad930a632f23e4c0661a20684c5d572e3dc15 100644 (file)
@@ -812,6 +812,7 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
 
                if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags))
                        return -ENOTCONN;
+               memset(&pvc, 0, sizeof(pvc));
                pvc.sap_family = AF_ATMPVC;
                pvc.sap_addr.itf = vcc->dev->number;
                pvc.sap_addr.vpi = vcc->vpi;
index 3a734919c36cbeac2e59e923225096f76380620b..ae0324021407c2b61aaf7c45a39bebb9d419972c 100644 (file)
@@ -95,6 +95,7 @@ static int pvc_getname(struct socket *sock, struct sockaddr *sockaddr,
                return -ENOTCONN;
        *sockaddr_len = sizeof(struct sockaddr_atmpvc);
        addr = (struct sockaddr_atmpvc *)sockaddr;
+       memset(addr, 0, sizeof(*addr));
        addr->sap_family = AF_ATMPVC;
        addr->sap_addr.itf = vcc->dev->number;
        addr->sap_addr.vpi = vcc->vpi;
index b421cc49d2cd1f83a88b905047df40e2853c4b0b..fc866f2e4528c71c82ba125c23fb48fbd430b390 100644 (file)
@@ -200,11 +200,11 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
        if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
                goto out;
 
-       if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect))
-               goto out;
-
        curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
 
+       if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw)
+               goto out;
+
        next_gw = batadv_gw_get_best_gw_node(bat_priv);
 
        if (curr_gw == next_gw)
index a438f4b582fc8adccba3a67dfb33326b1ecf4606..99dd8f75b3ff20f0d2a277e1f65ffc284b002f2e 100644 (file)
@@ -197,6 +197,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
 del:
                list_del(&entry->list);
                kfree(entry);
+               kfree(tt_change_node);
                event_removed = true;
                goto unlock;
        }
index 41ff978a33f9078b3e23b7cc3fed67c78921b5c7..715d7e33fba0639d1556088e5ea84a08f6b4ccd4 100644 (file)
@@ -1365,6 +1365,9 @@ static bool hci_resolve_next_name(struct hci_dev *hdev)
                return false;
 
        e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
+       if (!e)
+               return false;
+
        if (hci_resolve_name(hdev, e) == 0) {
                e->name_state = NAME_PENDING;
                return true;
@@ -1393,12 +1396,20 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
                return;
 
        e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
-       if (e) {
+       /* If the device was not found in a list of found devices names of which
+        * are pending. there is no need to continue resolving a next name as it
+        * will be done upon receiving another Remote Name Request Complete
+        * Event */
+       if (!e)
+               return;
+
+       list_del(&e->list);
+       if (name) {
                e->name_state = NAME_KNOWN;
-               list_del(&e->list);
-               if (name)
-                       mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
-                                        e->data.rssi, name, name_len);
+               mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
+                                e->data.rssi, name, name_len);
+       } else {
+               e->name_state = NAME_NOT_KNOWN;
        }
 
        if (hci_resolve_next_name(hdev))
@@ -1762,7 +1773,12 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                if (conn->type == ACL_LINK) {
                        conn->state = BT_CONFIG;
                        hci_conn_hold(conn);
-                       conn->disc_timeout = HCI_DISCONN_TIMEOUT;
+
+                       if (!conn->out && !hci_conn_ssp_enabled(conn) &&
+                           !hci_find_link_key(hdev, &ev->bdaddr))
+                               conn->disc_timeout = HCI_PAIRING_TIMEOUT;
+                       else
+                               conn->disc_timeout = HCI_DISCONN_TIMEOUT;
                } else
                        conn->state = BT_CONNECTED;
 
index a7f04de03d7916add5a20cf44d8e88e5daad495d..19fdac78e555b97c44dd6826bc60ef89a888395b 100644 (file)
@@ -694,6 +694,7 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
        *addr_len = sizeof(*haddr);
        haddr->hci_family = AF_BLUETOOTH;
        haddr->hci_dev    = hdev->id;
+       haddr->hci_channel= 0;
 
        release_sock(sk);
        return 0;
@@ -1009,6 +1010,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
                {
                        struct hci_filter *f = &hci_pi(sk)->filter;
 
+                       memset(&uf, 0, sizeof(uf));
                        uf.type_mask = f->type_mask;
                        uf.opcode    = f->opcode;
                        uf.event_mask[0] = *((u32 *) f->event_mask + 0);
index a8964db04bfb5cd1d0d348ed96c472e4786f3f44..daa149b7003cdd659120e79225a50c6216a6dce4 100644 (file)
@@ -1181,6 +1181,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
        sk = chan->sk;
 
        hci_conn_hold(conn->hcon);
+       conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
 
        bacpy(&bt_sk(sk)->src, conn->src);
        bacpy(&bt_sk(sk)->dst, conn->dst);
index a4bb27e8427e9aabaa48b90727cb23bcf5568f96..1497edd191a2e04ee3121624db92547059f24369 100644 (file)
@@ -245,6 +245,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
+       memset(la, 0, sizeof(struct sockaddr_l2));
        addr->sa_family = AF_BLUETOOTH;
        *len = sizeof(struct sockaddr_l2);
 
@@ -1174,7 +1175,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
 
        chan = l2cap_chan_create();
        if (!chan) {
-               l2cap_sock_kill(sk);
+               sk_free(sk);
                return NULL;
        }
 
index 7e1e59645c056f71400ad9ed4dc0444548c41951..1a17850d093cd652621ac54833c53b8dabd395bc 100644 (file)
@@ -528,6 +528,7 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
+       memset(sa, 0, sizeof(*sa));
        sa->rc_family  = AF_BLUETOOTH;
        sa->rc_channel = rfcomm_pi(sk)->channel;
        if (peer)
@@ -822,6 +823,7 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
                }
 
                sec.level = rfcomm_pi(sk)->sec_level;
+               sec.key_size = 0;
 
                len = min_t(unsigned int, len, sizeof(sec));
                if (copy_to_user(optval, (char *) &sec, len))
index cb960773c002efafeb45b888ee8f3ba3e9208490..56f182393c4c7d278a391c1cbf0cccc7ed4424e3 100644 (file)
@@ -456,7 +456,7 @@ static int rfcomm_get_dev_list(void __user *arg)
 
        size = sizeof(*dl) + dev_num * sizeof(*di);
 
-       dl = kmalloc(size, GFP_KERNEL);
+       dl = kzalloc(size, GFP_KERNEL);
        if (!dl)
                return -ENOMEM;
 
index 40bbe25dcff7f97c9a279c6d087eaed078563364..3589e21edb09817bace527336fd4880e24137ada 100644 (file)
@@ -131,6 +131,15 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
                sco_sock_clear_timer(sk);
                sco_chan_del(sk, err);
                bh_unlock_sock(sk);
+
+               sco_conn_lock(conn);
+               conn->sk = NULL;
+               sco_pi(sk)->conn = NULL;
+               sco_conn_unlock(conn);
+
+               if (conn->hcon)
+                       hci_conn_put(conn->hcon);
+
                sco_sock_kill(sk);
        }
 
@@ -821,16 +830,6 @@ static void sco_chan_del(struct sock *sk, int err)
 
        BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
 
-       if (conn) {
-               sco_conn_lock(conn);
-               conn->sk = NULL;
-               sco_pi(sk)->conn = NULL;
-               sco_conn_unlock(conn);
-
-               if (conn->hcon)
-                       hci_conn_put(conn->hcon);
-       }
-
        sk->sk_state = BT_CLOSED;
        sk->sk_err   = err;
        sk->sk_state_change(sk);
index 16ef0dc85a0a87580c311563028cc567fa826bce..901a616c8083e22f5163f8bbd1613b1529c63519 100644 (file)
@@ -579,8 +579,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
        if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
                smp = smp_chan_create(conn);
+       else
+               smp = conn->smp_chan;
 
-       smp = conn->smp_chan;
+       if (!smp)
+               return SMP_UNSPECIFIED;
 
        smp->preq[0] = SMP_CMD_PAIRING_REQ;
        memcpy(&smp->preq[1], req, sizeof(*req));
index 3334845376005cdba3a3b6b2d0b4013da4617446..070e8a68cfc63f856b281b4f19e08181cbd5172f 100644 (file)
@@ -31,9 +31,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        struct net_bridge_mdb_entry *mdst;
        struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
 
+       rcu_read_lock();
 #ifdef CONFIG_BRIDGE_NETFILTER
        if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) {
                br_nf_pre_routing_finish_bridge_slow(skb);
+               rcu_read_unlock();
                return NETDEV_TX_OK;
        }
 #endif
@@ -48,7 +50,6 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        skb_reset_mac_header(skb);
        skb_pull(skb, ETH_HLEN);
 
-       rcu_read_lock();
        if (is_broadcast_ether_addr(dest))
                br_flood_deliver(br, skb);
        else if (is_multicast_ether_addr(dest)) {
@@ -206,24 +207,23 @@ static void br_poll_controller(struct net_device *br_dev)
 static void br_netpoll_cleanup(struct net_device *dev)
 {
        struct net_bridge *br = netdev_priv(dev);
-       struct net_bridge_port *p, *n;
+       struct net_bridge_port *p;
 
-       list_for_each_entry_safe(p, n, &br->port_list, list) {
+       list_for_each_entry(p, &br->port_list, list)
                br_netpoll_disable(p);
-       }
 }
 
-static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
+static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni,
+                           gfp_t gfp)
 {
        struct net_bridge *br = netdev_priv(dev);
-       struct net_bridge_port *p, *n;
+       struct net_bridge_port *p;
        int err = 0;
 
-       list_for_each_entry_safe(p, n, &br->port_list, list) {
+       list_for_each_entry(p, &br->port_list, list) {
                if (!p->dev)
                        continue;
-
-               err = br_netpoll_enable(p);
+               err = br_netpoll_enable(p, gfp);
                if (err)
                        goto fail;
        }
@@ -236,17 +236,17 @@ fail:
        goto out;
 }
 
-int br_netpoll_enable(struct net_bridge_port *p)
+int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp)
 {
        struct netpoll *np;
        int err = 0;
 
-       np = kzalloc(sizeof(*p->np), GFP_KERNEL);
+       np = kzalloc(sizeof(*p->np), gfp);
        err = -ENOMEM;
        if (!np)
                goto out;
 
-       err = __netpoll_setup(np, p->dev);
+       err = __netpoll_setup(np, p->dev, gfp);
        if (err) {
                kfree(np);
                goto out;
@@ -267,11 +267,7 @@ void br_netpoll_disable(struct net_bridge_port *p)
 
        p->np = NULL;
 
-       /* Wait for transmitting packets to finish before freeing. */
-       synchronize_rcu_bh();
-
-       __netpoll_cleanup(np);
-       kfree(np);
+       __netpoll_free_rcu(np);
 }
 
 #endif
index e9466d412707849b17b01200240cbb67e66b20af..02015a505d2a41ddbf5c6abea3867613fe7030e8 100644 (file)
@@ -65,7 +65,7 @@ static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 {
        skb->dev = to->dev;
 
-       if (unlikely(netpoll_tx_running(to->dev))) {
+       if (unlikely(netpoll_tx_running(to->br->dev))) {
                if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
                        kfree_skb(skb);
                else {
index e1144e1617be38814ebb2fb497755cb10b646559..1c8fdc3558cd48e9ad5d7be9c3981ebf80878364 100644 (file)
@@ -361,7 +361,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
        if (err)
                goto err2;
 
-       if (br_netpoll_info(br) && ((err = br_netpoll_enable(p))))
+       if (br_netpoll_info(br) && ((err = br_netpoll_enable(p, GFP_KERNEL))))
                goto err3;
 
        err = netdev_set_master(dev, br->dev);
@@ -427,6 +427,10 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
        if (!p || p->br != br)
                return -EINVAL;
 
+       /* Since more than one interface can be attached to a bridge,
+        * there still maybe an alternate path for netconsole to use;
+        * therefore there is no reason for a NETDEV_RELEASE event.
+        */
        del_nbp(p);
 
        spin_lock_bh(&br->lock);
index a768b2408edff64890dde477df5918c102630a5e..f507d2af9646bcb273cf1f50f98feb065027e14a 100644 (file)
@@ -316,7 +316,7 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
                netpoll_send_skb(np, skb);
 }
 
-extern int br_netpoll_enable(struct net_bridge_port *p);
+extern int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp);
 extern void br_netpoll_disable(struct net_bridge_port *p);
 #else
 static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
@@ -329,7 +329,7 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
 {
 }
 
-static inline int br_netpoll_enable(struct net_bridge_port *p)
+static inline int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp)
 {
        return 0;
 }
index 69771c04ba8fc96a2718f841b6e3d159ee000112..e597733affb82f088203bab569644f312e8d5463 100644 (file)
@@ -94,6 +94,10 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
 
        /* check the version of IP */
        ip_version = skb_header_pointer(skb, 0, 1, &buf);
+       if (!ip_version) {
+               kfree_skb(skb);
+               return -EINVAL;
+       }
 
        switch (*ip_version >> 4) {
        case 4:
index 69e38db28e5f3efcda5ce871ac5682408eb5aa9e..a8020293f34210620eff72f6193ee35e064f5d69 100644 (file)
@@ -84,7 +84,6 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
                        return -1;
                }
        } else {
-               pr_info("client%lld fsid %pU\n", ceph_client_id(client), fsid);
                memcpy(&client->fsid, fsid, sizeof(*fsid));
        }
        return 0;
index 54b531a01121aafdbc31a9ba33fd60027280d32e..38b5dc1823d44961e6bbf7d52d36991920f5ddc1 100644 (file)
@@ -189,6 +189,9 @@ int ceph_debugfs_client_init(struct ceph_client *client)
        snprintf(name, sizeof(name), "%pU.client%lld", &client->fsid,
                 client->monc.auth->global_id);
 
+       dout("ceph_debugfs_client_init %p %s\n", client, name);
+
+       BUG_ON(client->debugfs_dir);
        client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
        if (!client->debugfs_dir)
                goto out;
@@ -234,6 +237,7 @@ out:
 
 void ceph_debugfs_client_cleanup(struct ceph_client *client)
 {
+       dout("ceph_debugfs_client_cleanup %p\n", client);
        debugfs_remove(client->debugfs_osdmap);
        debugfs_remove(client->debugfs_monmap);
        debugfs_remove(client->osdc.debugfs_file);
index b9796750034afc093c172dc9ac92b2e864d87271..24c5eea8c45bb1233edfad141baf6a6391e023c6 100644 (file)
@@ -915,7 +915,6 @@ static int prepare_write_connect(struct ceph_connection *con)
        con->out_connect.authorizer_len = auth ?
                cpu_to_le32(auth->authorizer_buf_len) : 0;
 
-       con_out_kvec_reset(con);
        con_out_kvec_add(con, sizeof (con->out_connect),
                                        &con->out_connect);
        if (auth && auth->authorizer_buf_len)
@@ -1557,6 +1556,7 @@ static int process_connect(struct ceph_connection *con)
                        return -1;
                }
                con->auth_retry = 1;
+               con_out_kvec_reset(con);
                ret = prepare_write_connect(con);
                if (ret < 0)
                        return ret;
@@ -1577,6 +1577,7 @@ static int process_connect(struct ceph_connection *con)
                       ENTITY_NAME(con->peer_name),
                       ceph_pr_addr(&con->peer_addr.in_addr));
                reset_connection(con);
+               con_out_kvec_reset(con);
                ret = prepare_write_connect(con);
                if (ret < 0)
                        return ret;
@@ -1601,6 +1602,7 @@ static int process_connect(struct ceph_connection *con)
                     le32_to_cpu(con->out_connect.connect_seq),
                     le32_to_cpu(con->in_reply.connect_seq));
                con->connect_seq = le32_to_cpu(con->in_reply.connect_seq);
+               con_out_kvec_reset(con);
                ret = prepare_write_connect(con);
                if (ret < 0)
                        return ret;
@@ -1617,6 +1619,7 @@ static int process_connect(struct ceph_connection *con)
                     le32_to_cpu(con->in_reply.global_seq));
                get_global_seq(con->msgr,
                               le32_to_cpu(con->in_reply.global_seq));
+               con_out_kvec_reset(con);
                ret = prepare_write_connect(con);
                if (ret < 0)
                        return ret;
@@ -2135,7 +2138,11 @@ more:
                BUG_ON(con->state != CON_STATE_CONNECTING);
                con->state = CON_STATE_NEGOTIATING;
 
-               /* Banner is good, exchange connection info */
+               /*
+                * Received banner is good, exchange connection info.
+                * Do not reset out_kvec, as sending our banner raced
+                * with receiving peer banner after connect completed.
+                */
                ret = prepare_write_connect(con);
                if (ret < 0)
                        goto out;
index 105d533b55f3bcc3e8a2e7a82b80a6459cbb9363..900ea0f043fc0d5cfd7c68b7abc37e607d822165 100644 (file)
@@ -310,6 +310,17 @@ int ceph_monc_open_session(struct ceph_mon_client *monc)
 }
 EXPORT_SYMBOL(ceph_monc_open_session);
 
+/*
+ * We require the fsid and global_id in order to initialize our
+ * debugfs dir.
+ */
+static bool have_debugfs_info(struct ceph_mon_client *monc)
+{
+       dout("have_debugfs_info fsid %d globalid %lld\n",
+            (int)monc->client->have_fsid, monc->auth->global_id);
+       return monc->client->have_fsid && monc->auth->global_id > 0;
+}
+
 /*
  * The monitor responds with mount ack indicate mount success.  The
  * included client ticket allows the client to talk to MDSs and OSDs.
@@ -320,9 +331,12 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
        struct ceph_client *client = monc->client;
        struct ceph_monmap *monmap = NULL, *old = monc->monmap;
        void *p, *end;
+       int had_debugfs_info, init_debugfs = 0;
 
        mutex_lock(&monc->mutex);
 
+       had_debugfs_info = have_debugfs_info(monc);
+
        dout("handle_monmap\n");
        p = msg->front.iov_base;
        end = p + msg->front.iov_len;
@@ -344,12 +358,22 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
 
        if (!client->have_fsid) {
                client->have_fsid = true;
+               if (!had_debugfs_info && have_debugfs_info(monc)) {
+                       pr_info("client%lld fsid %pU\n",
+                               ceph_client_id(monc->client),
+                               &monc->client->fsid);
+                       init_debugfs = 1;
+               }
                mutex_unlock(&monc->mutex);
-               /*
-                * do debugfs initialization without mutex to avoid
-                * creating a locking dependency
-                */
-               ceph_debugfs_client_init(client);
+
+               if (init_debugfs) {
+                       /*
+                        * do debugfs initialization without mutex to avoid
+                        * creating a locking dependency
+                        */
+                       ceph_debugfs_client_init(monc->client);
+               }
+
                goto out_unlocked;
        }
 out:
@@ -865,8 +889,10 @@ static void handle_auth_reply(struct ceph_mon_client *monc,
 {
        int ret;
        int was_auth = 0;
+       int had_debugfs_info, init_debugfs = 0;
 
        mutex_lock(&monc->mutex);
+       had_debugfs_info = have_debugfs_info(monc);
        if (monc->auth->ops)
                was_auth = monc->auth->ops->is_authenticated(monc->auth);
        monc->pending_auth = 0;
@@ -889,7 +915,22 @@ static void handle_auth_reply(struct ceph_mon_client *monc,
                __send_subscribe(monc);
                __resend_generic_request(monc);
        }
+
+       if (!had_debugfs_info && have_debugfs_info(monc)) {
+               pr_info("client%lld fsid %pU\n",
+                       ceph_client_id(monc->client),
+                       &monc->client->fsid);
+               init_debugfs = 1;
+       }
        mutex_unlock(&monc->mutex);
+
+       if (init_debugfs) {
+               /*
+                * do debugfs initialization without mutex to avoid
+                * creating a locking dependency
+                */
+               ceph_debugfs_client_init(monc->client);
+       }
 }
 
 static int __validate_auth(struct ceph_mon_client *monc)
index 0cb3fe8d8e7248c1618829673041135a606b36ff..83988362805ef1453efb37bfcb3692f59f4edd21 100644 (file)
@@ -1055,6 +1055,8 @@ rollback:
  */
 int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
 {
+       char *new_ifalias;
+
        ASSERT_RTNL();
 
        if (len >= IFALIASZ)
@@ -1068,9 +1070,10 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
                return 0;
        }
 
-       dev->ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL);
-       if (!dev->ifalias)
+       new_ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL);
+       if (!new_ifalias)
                return -ENOMEM;
+       dev->ifalias = new_ifalias;
 
        strlcpy(dev->ifalias, alias, len+1);
        return len;
@@ -1639,6 +1642,19 @@ static inline int deliver_skb(struct sk_buff *skb,
        return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
 }
 
+static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb)
+{
+       if (ptype->af_packet_priv == NULL)
+               return false;
+
+       if (ptype->id_match)
+               return ptype->id_match(ptype, skb->sk);
+       else if ((struct sock *)ptype->af_packet_priv == skb->sk)
+               return true;
+
+       return false;
+}
+
 /*
  *     Support routine. Sends outgoing frames to any network
  *     taps currently in use.
@@ -1656,8 +1672,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
                 * they originated from - MvS (miquels@drinkel.ow.org)
                 */
                if ((ptype->dev == dev || !ptype->dev) &&
-                   (ptype->af_packet_priv == NULL ||
-                    (struct sock *)ptype->af_packet_priv != skb->sk)) {
+                   (!skb_loop_sk(ptype, skb))) {
                        if (pt_prev) {
                                deliver_skb(skb2, pt_prev, skb->dev);
                                pt_prev = ptype;
@@ -2134,6 +2149,9 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
        __be16 protocol = skb->protocol;
        netdev_features_t features = skb->dev->features;
 
+       if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs)
+               features &= ~NETIF_F_GSO_MASK;
+
        if (protocol == htons(ETH_P_8021Q)) {
                struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
                protocol = veh->h_vlan_encapsulated_proto;
@@ -5726,6 +5744,7 @@ EXPORT_SYMBOL(netdev_refcnt_read);
 
 /**
  * netdev_wait_allrefs - wait until all references are gone.
+ * @dev: target net_device
  *
  * This is called when unregistering network devices.
  *
@@ -5986,6 +6005,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
        dev_net_set(dev, &init_net);
 
        dev->gso_max_size = GSO_MAX_SIZE;
+       dev->gso_max_segs = GSO_MAX_SEGS;
 
        INIT_LIST_HEAD(&dev->napi_list);
        INIT_LIST_HEAD(&dev->unreg_list);
index 069d51d29414a3245f9b60b66c534f78ce3b1752..56d63612e1e4b9a1ebfc04ddfa1bcd50333e0118 100644 (file)
@@ -149,7 +149,15 @@ int dst_discard(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(dst_discard);
 
-const u32 dst_default_metrics[RTAX_MAX];
+const u32 dst_default_metrics[RTAX_MAX + 1] = {
+       /* This initializer is needed to force linker to place this variable
+        * into const section. Otherwise it might end into bss section.
+        * We really want to avoid false sharing on this variable, and catch
+        * any writes on it.
+        */
+       [RTAX_MAX] = 0xdeadbeef,
+};
+
 
 void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
                int initial_ref, int initial_obsolete, unsigned short flags)
index b4c90e42b4434455c8205f4483991326a85eedb6..346b1eb83a1f0336ed1e9dcf4f5905b733022dff 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/workqueue.h>
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/if_vlan.h>
 #include <net/tcp.h>
 #include <net/udp.h>
 #include <asm/unaligned.h>
@@ -54,7 +55,7 @@ static atomic_t trapped;
         MAX_UDP_CHUNK)
 
 static void zap_completion_queue(void);
-static void arp_reply(struct sk_buff *skb);
+static void netpoll_arp_reply(struct sk_buff *skb, struct netpoll_info *npinfo);
 
 static unsigned int carrier_timeout = 4;
 module_param(carrier_timeout, uint, 0644);
@@ -167,15 +168,24 @@ static void poll_napi(struct net_device *dev)
        struct napi_struct *napi;
        int budget = 16;
 
+       WARN_ON_ONCE(!irqs_disabled());
+
        list_for_each_entry(napi, &dev->napi_list, dev_list) {
+               local_irq_enable();
                if (napi->poll_owner != smp_processor_id() &&
                    spin_trylock(&napi->poll_lock)) {
-                       budget = poll_one_napi(dev->npinfo, napi, budget);
+                       rcu_read_lock_bh();
+                       budget = poll_one_napi(rcu_dereference_bh(dev->npinfo),
+                                              napi, budget);
+                       rcu_read_unlock_bh();
                        spin_unlock(&napi->poll_lock);
 
-                       if (!budget)
+                       if (!budget) {
+                               local_irq_disable();
                                break;
+                       }
                }
+               local_irq_disable();
        }
 }
 
@@ -185,13 +195,14 @@ static void service_arp_queue(struct netpoll_info *npi)
                struct sk_buff *skb;
 
                while ((skb = skb_dequeue(&npi->arp_tx)))
-                       arp_reply(skb);
+                       netpoll_arp_reply(skb, npi);
        }
 }
 
 static void netpoll_poll_dev(struct net_device *dev)
 {
        const struct net_device_ops *ops;
+       struct netpoll_info *ni = rcu_dereference_bh(dev->npinfo);
 
        if (!dev || !netif_running(dev))
                return;
@@ -206,17 +217,18 @@ static void netpoll_poll_dev(struct net_device *dev)
        poll_napi(dev);
 
        if (dev->flags & IFF_SLAVE) {
-               if (dev->npinfo) {
+               if (ni) {
                        struct net_device *bond_dev = dev->master;
                        struct sk_buff *skb;
-                       while ((skb = skb_dequeue(&dev->npinfo->arp_tx))) {
+                       struct netpoll_info *bond_ni = rcu_dereference_bh(bond_dev->npinfo);
+                       while ((skb = skb_dequeue(&ni->arp_tx))) {
                                skb->dev = bond_dev;
-                               skb_queue_tail(&bond_dev->npinfo->arp_tx, skb);
+                               skb_queue_tail(&bond_ni->arp_tx, skb);
                        }
                }
        }
 
-       service_arp_queue(dev->npinfo);
+       service_arp_queue(ni);
 
        zap_completion_queue();
 }
@@ -302,6 +314,7 @@ static int netpoll_owner_active(struct net_device *dev)
        return 0;
 }
 
+/* call with IRQ disabled */
 void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
                             struct net_device *dev)
 {
@@ -309,8 +322,11 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
        unsigned long tries;
        const struct net_device_ops *ops = dev->netdev_ops;
        /* It is up to the caller to keep npinfo alive. */
-       struct netpoll_info *npinfo = np->dev->npinfo;
+       struct netpoll_info *npinfo;
+
+       WARN_ON_ONCE(!irqs_disabled());
 
+       npinfo = rcu_dereference_bh(np->dev->npinfo);
        if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) {
                __kfree_skb(skb);
                return;
@@ -319,16 +335,22 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
        /* don't get messages out of order, and no recursion */
        if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) {
                struct netdev_queue *txq;
-               unsigned long flags;
 
                txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
 
-               local_irq_save(flags);
                /* try until next clock tick */
                for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
                     tries > 0; --tries) {
                        if (__netif_tx_trylock(txq)) {
                                if (!netif_xmit_stopped(txq)) {
+                                       if (vlan_tx_tag_present(skb) &&
+                                           !(netif_skb_features(skb) & NETIF_F_HW_VLAN_TX)) {
+                                               skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
+                                               if (unlikely(!skb))
+                                                       break;
+                                               skb->vlan_tci = 0;
+                                       }
+
                                        status = ops->ndo_start_xmit(skb, dev);
                                        if (status == NETDEV_TX_OK)
                                                txq_trans_update(txq);
@@ -347,10 +369,9 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
                }
 
                WARN_ONCE(!irqs_disabled(),
-                       "netpoll_send_skb(): %s enabled interrupts in poll (%pF)\n",
+                       "netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n",
                        dev->name, ops->ndo_start_xmit);
 
-               local_irq_restore(flags);
        }
 
        if (status != NETDEV_TX_OK) {
@@ -423,9 +444,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
 }
 EXPORT_SYMBOL(netpoll_send_udp);
 
-static void arp_reply(struct sk_buff *skb)
+static void netpoll_arp_reply(struct sk_buff *skb, struct netpoll_info *npinfo)
 {
-       struct netpoll_info *npinfo = skb->dev->npinfo;
        struct arphdr *arp;
        unsigned char *arp_ptr;
        int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
@@ -543,13 +563,12 @@ static void arp_reply(struct sk_buff *skb)
        spin_unlock_irqrestore(&npinfo->rx_lock, flags);
 }
 
-int __netpoll_rx(struct sk_buff *skb)
+int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
 {
        int proto, len, ulen;
        int hits = 0;
        const struct iphdr *iph;
        struct udphdr *uh;
-       struct netpoll_info *npinfo = skb->dev->npinfo;
        struct netpoll *np, *tmp;
 
        if (list_empty(&npinfo->rx_np))
@@ -565,6 +584,12 @@ int __netpoll_rx(struct sk_buff *skb)
                return 1;
        }
 
+       if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+               skb = vlan_untag(skb);
+               if (unlikely(!skb))
+                       goto out;
+       }
+
        proto = ntohs(eth_hdr(skb)->h_proto);
        if (proto != ETH_P_IP)
                goto out;
@@ -715,7 +740,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
 }
 EXPORT_SYMBOL(netpoll_parse_options);
 
-int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
+int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp)
 {
        struct netpoll_info *npinfo;
        const struct net_device_ops *ops;
@@ -734,7 +759,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
        }
 
        if (!ndev->npinfo) {
-               npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
+               npinfo = kmalloc(sizeof(*npinfo), gfp);
                if (!npinfo) {
                        err = -ENOMEM;
                        goto out;
@@ -752,7 +777,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
 
                ops = np->dev->netdev_ops;
                if (ops->ndo_netpoll_setup) {
-                       err = ops->ndo_netpoll_setup(ndev, npinfo);
+                       err = ops->ndo_netpoll_setup(ndev, npinfo, gfp);
                        if (err)
                                goto free_npinfo;
                }
@@ -857,7 +882,7 @@ int netpoll_setup(struct netpoll *np)
        refill_skbs();
 
        rtnl_lock();
-       err = __netpoll_setup(np, ndev);
+       err = __netpoll_setup(np, ndev, GFP_KERNEL);
        rtnl_unlock();
 
        if (err)
@@ -878,6 +903,24 @@ static int __init netpoll_init(void)
 }
 core_initcall(netpoll_init);
 
+static void rcu_cleanup_netpoll_info(struct rcu_head *rcu_head)
+{
+       struct netpoll_info *npinfo =
+                       container_of(rcu_head, struct netpoll_info, rcu);
+
+       skb_queue_purge(&npinfo->arp_tx);
+       skb_queue_purge(&npinfo->txq);
+
+       /* we can't call cancel_delayed_work_sync here, as we are in softirq */
+       cancel_delayed_work(&npinfo->tx_work);
+
+       /* clean after last, unfinished work */
+       __skb_queue_purge(&npinfo->txq);
+       /* now cancel it again */
+       cancel_delayed_work(&npinfo->tx_work);
+       kfree(npinfo);
+}
+
 void __netpoll_cleanup(struct netpoll *np)
 {
        struct netpoll_info *npinfo;
@@ -903,20 +946,24 @@ void __netpoll_cleanup(struct netpoll *np)
                        ops->ndo_netpoll_cleanup(np->dev);
 
                RCU_INIT_POINTER(np->dev->npinfo, NULL);
+               call_rcu_bh(&npinfo->rcu, rcu_cleanup_netpoll_info);
+       }
+}
+EXPORT_SYMBOL_GPL(__netpoll_cleanup);
 
-               /* avoid racing with NAPI reading npinfo */
-               synchronize_rcu_bh();
+static void rcu_cleanup_netpoll(struct rcu_head *rcu_head)
+{
+       struct netpoll *np = container_of(rcu_head, struct netpoll, rcu);
 
-               skb_queue_purge(&npinfo->arp_tx);
-               skb_queue_purge(&npinfo->txq);
-               cancel_delayed_work_sync(&npinfo->tx_work);
+       __netpoll_cleanup(np);
+       kfree(np);
+}
 
-               /* clean after last, unfinished work */
-               __skb_queue_purge(&npinfo->txq);
-               kfree(npinfo);
-       }
+void __netpoll_free_rcu(struct netpoll *np)
+{
+       call_rcu_bh(&np->rcu, rcu_cleanup_netpoll);
 }
-EXPORT_SYMBOL_GPL(__netpoll_cleanup);
+EXPORT_SYMBOL_GPL(__netpoll_free_rcu);
 
 void netpoll_cleanup(struct netpoll *np)
 {
index ed0c0431fcd8ff225842ec8de8537f54f0a3294f..c75e3f9d060f8e3d086b747255ab65c8104f7dde 100644 (file)
@@ -101,12 +101,10 @@ static int write_update_netdev_table(struct net_device *dev)
        u32 max_len;
        struct netprio_map *map;
 
-       rtnl_lock();
        max_len = atomic_read(&max_prioidx) + 1;
        map = rtnl_dereference(dev->priomap);
        if (!map || map->priomap_len < max_len)
                ret = extend_netdev_table(dev, max_len);
-       rtnl_unlock();
 
        return ret;
 }
@@ -256,17 +254,17 @@ static int write_priomap(struct cgroup *cgrp, struct cftype *cft,
        if (!dev)
                goto out_free_devname;
 
+       rtnl_lock();
        ret = write_update_netdev_table(dev);
        if (ret < 0)
                goto out_put_dev;
 
-       rcu_read_lock();
-       map = rcu_dereference(dev->priomap);
+       map = rtnl_dereference(dev->priomap);
        if (map)
                map->priomap[prioidx] = priority;
-       rcu_read_unlock();
 
 out_put_dev:
+       rtnl_unlock();
        dev_put(dev);
 
 out_free_devname:
@@ -277,12 +275,6 @@ out_free_devname:
 void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 {
        struct task_struct *p;
-       char *tmp = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL);
-
-       if (!tmp) {
-               pr_warn("Unable to attach cgrp due to alloc failure!\n");
-               return;
-       }
 
        cgroup_taskset_for_each(p, cgrp, tset) {
                unsigned int fd;
@@ -296,32 +288,24 @@ void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
                        continue;
                }
 
-               rcu_read_lock();
+               spin_lock(&files->file_lock);
                fdt = files_fdtable(files);
                for (fd = 0; fd < fdt->max_fds; fd++) {
-                       char *path;
                        struct file *file;
                        struct socket *sock;
-                       unsigned long s;
-                       int rv, err = 0;
+                       int err;
 
                        file = fcheck_files(files, fd);
                        if (!file)
                                continue;
 
-                       path = d_path(&file->f_path, tmp, PAGE_SIZE);
-                       rv = sscanf(path, "socket:[%lu]", &s);
-                       if (rv <= 0)
-                               continue;
-
                        sock = sock_from_file(file, &err);
-                       if (!err)
+                       if (sock)
                                sock_update_netprioidx(sock->sk, p);
                }
-               rcu_read_unlock();
+               spin_unlock(&files->file_lock);
                task_unlock(p);
        }
-       kfree(tmp);
 }
 
 static struct cftype ss_files[] = {
index 8f6ccfd68ef4fb6625652f0b34f7f3fdb4b4a91e..040cebeed45b810cf9dd7d85c6ac2cbade98ee77 100644 (file)
@@ -265,6 +265,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
        for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax;
             i++, cmfptr++)
        {
+               struct socket *sock;
                int new_fd;
                err = security_file_receive(fp[i]);
                if (err)
@@ -281,6 +282,9 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
                }
                /* Bump the usage count and install the file. */
                get_file(fp[i]);
+               sock = sock_from_file(fp[i], &err);
+               if (sock)
+                       sock_update_netprioidx(sock->sk, current);
                fd_install(new_fd, fp[i]);
        }
 
index 6b654b3ddfda2a9a03f77bc1d2a5476a2c25e9d4..8f67ced8d6a808689255435dd412df132138af65 100644 (file)
@@ -1458,6 +1458,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
                } else {
                        sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
                        sk->sk_gso_max_size = dst->dev->gso_max_size;
+                       sk->sk_gso_max_segs = dst->dev->gso_max_segs;
                }
        }
 }
index 75c3582a7678ab418771b2a5ad5fd3c069a9e512..fb85d371a8dec875a01205b22ef6ddef5e99d511 100644 (file)
@@ -246,7 +246,7 @@ static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk,
                                        u32 __user *optval, int __user *optlen)
 {
        int rc = -ENOPROTOOPT;
-       if (ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL)
+       if (ccid != NULL && ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL)
                rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len,
                                                 optval, optlen);
        return rc;
@@ -257,7 +257,7 @@ static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk,
                                        u32 __user *optval, int __user *optlen)
 {
        int rc = -ENOPROTOOPT;
-       if (ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL)
+       if (ccid != NULL && ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL)
                rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len,
                                                 optval, optlen);
        return rc;
index d65e98798ecaff29110a2ff303d500482162df66..119c04317d48eed4abcb2bbf6071062c8d9784fd 100644 (file)
@@ -535,6 +535,7 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
        case DCCP_SOCKOPT_CCID_TX_INFO:
                if (len < sizeof(tfrc))
                        return -EINVAL;
+               memset(&tfrc, 0, sizeof(tfrc));
                tfrc.tfrctx_x      = hc->tx_x;
                tfrc.tfrctx_x_recv = hc->tx_x_recv;
                tfrc.tfrctx_x_calc = hc->tx_x_calc;
index f0cdb30921c0bdb5b1639e15d05908dfde6586f9..57bd978483e1fe47a96c964f356432e51e62d6b7 100644 (file)
@@ -367,7 +367,7 @@ static void __leaf_free_rcu(struct rcu_head *head)
 
 static inline void free_leaf(struct leaf *l)
 {
-       call_rcu_bh(&l->rcu, __leaf_free_rcu);
+       call_rcu(&l->rcu, __leaf_free_rcu);
 }
 
 static inline void free_leaf_info(struct leaf_info *leaf)
index db0cf17c00f7048030d4dcea41e2d8f088391cc1..7f75f21d7b8346e0279364c511117582f3c1f342 100644 (file)
@@ -404,12 +404,15 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
 {
        const struct inet_request_sock *ireq = inet_rsk(req);
        struct inet_sock *newinet = inet_sk(newsk);
-       struct ip_options_rcu *opt = ireq->opt;
+       struct ip_options_rcu *opt;
        struct net *net = sock_net(sk);
        struct flowi4 *fl4;
        struct rtable *rt;
 
        fl4 = &newinet->cork.fl.u.ip4;
+
+       rcu_read_lock();
+       opt = rcu_dereference(newinet->inet_opt);
        flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
                           RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
                           sk->sk_protocol, inet_sk_flowi_flags(sk),
@@ -421,11 +424,13 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
                goto no_route;
        if (opt && opt->opt.is_strictroute && rt->rt_gateway)
                goto route_err;
+       rcu_read_unlock();
        return &rt->dst;
 
 route_err:
        ip_rt_put(rt);
 no_route:
+       rcu_read_unlock();
        IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
        return NULL;
 }
index ba39a52d18c1966209b02127ad7a4335479fcbdc..c196d749daf23b3823ffe012495ea5d9411be99a 100644 (file)
@@ -197,7 +197,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
        neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
        if (unlikely(!neigh))
                neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
-       if (neigh) {
+       if (!IS_ERR(neigh)) {
                int res = dst_neigh_output(dst, neigh, skb);
 
                rcu_read_unlock_bh();
@@ -1338,10 +1338,10 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
        iph->ihl = 5;
        iph->tos = inet->tos;
        iph->frag_off = df;
-       ip_select_ident(iph, &rt->dst, sk);
        iph->ttl = ttl;
        iph->protocol = sk->sk_protocol;
        ip_copy_addrs(iph, fl4);
+       ip_select_ident(iph, &rt->dst, sk);
 
        if (opt) {
                iph->ihl += opt->optlen>>2;
@@ -1366,9 +1366,8 @@ out:
        return skb;
 }
 
-int ip_send_skb(struct sk_buff *skb)
+int ip_send_skb(struct net *net, struct sk_buff *skb)
 {
-       struct net *net = sock_net(skb->sk);
        int err;
 
        err = ip_local_out(skb);
@@ -1391,7 +1390,7 @@ int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4)
                return 0;
 
        /* Netfilter gets whole the not fragmented skb. */
-       return ip_send_skb(skb);
+       return ip_send_skb(sock_net(sk), skb);
 }
 
 /*
@@ -1536,6 +1535,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
                          arg->csumoffset) = csum_fold(csum_add(nskb->csum,
                                                                arg->csum));
                nskb->ip_summed = CHECKSUM_NONE;
+               skb_orphan(nskb);
                skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb));
                ip_push_pending_frames(sk, &fl4);
        }
index ea4a23813d26e66bf3c5e1513dbdb247b53a06dd..4ad9cf1739922cfb4b13d3135d01381dd70bf0be 100644 (file)
@@ -148,7 +148,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
        if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
                                    hdr, NULL, &matchoff, &matchlen,
                                    &addr, &port) > 0) {
-               unsigned int matchend, poff, plen, buflen, n;
+               unsigned int olen, matchend, poff, plen, buflen, n;
                char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
 
                /* We're only interested in headers related to this
@@ -163,17 +163,18 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
                                goto next;
                }
 
+               olen = *datalen;
                if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen,
                              &addr, port))
                        return NF_DROP;
 
-               matchend = matchoff + matchlen;
+               matchend = matchoff + matchlen + *datalen - olen;
 
                /* The maddr= parameter (RFC 2361) specifies where to send
                 * the reply. */
                if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
                                               "maddr=", &poff, &plen,
-                                              &addr) > 0 &&
+                                              &addr, true) > 0 &&
                    addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
                    addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
                        buflen = sprintf(buffer, "%pI4",
@@ -187,7 +188,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,
                 * from which the server received the request. */
                if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
                                               "received=", &poff, &plen,
-                                              &addr) > 0 &&
+                                              &addr, false) > 0 &&
                    addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
                    addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
                        buflen = sprintf(buffer, "%pI4",
index c035251beb070bb7f4220324a90e0ffeee8e103c..fd9ecb52c66bf8815c09e678c452017e9a7e2122 100644 (file)
@@ -70,7 +70,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
@@ -80,7 +79,6 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
-#include <linux/workqueue.h>
 #include <linux/skbuff.h>
 #include <linux/inetdevice.h>
 #include <linux/igmp.h>
 #include <linux/mroute.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/random.h>
-#include <linux/jhash.h>
 #include <linux/rcupdate.h>
 #include <linux/times.h>
 #include <linux/slab.h>
-#include <linux/prefetch.h>
 #include <net/dst.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
@@ -2032,7 +2028,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
                }
                dev_out = net->loopback_dev;
                fl4->flowi4_oif = dev_out->ifindex;
-               res.fi = NULL;
                flags |= RTCF_LOCAL;
                goto make_route;
        }
index e7e6eeae49c0123d392fa16c7687c333b30b79b8..2109ff4a1dafd489fbe0e2240075432df4517374 100644 (file)
@@ -811,7 +811,9 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
                           old_size_goal + mss_now > xmit_size_goal)) {
                        xmit_size_goal = old_size_goal;
                } else {
-                       tp->xmit_size_goal_segs = xmit_size_goal / mss_now;
+                       tp->xmit_size_goal_segs =
+                               min_t(u16, xmit_size_goal / mss_now,
+                                     sk->sk_gso_max_segs);
                        xmit_size_goal = tp->xmit_size_goal_segs * mss_now;
                }
        }
index 4d4db16e336ea63c2b581079e5295a4a74924aab..1432cdb0644c2b16f893de842bcd3b9fdd3c5538 100644 (file)
@@ -291,7 +291,8 @@ bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
        left = tp->snd_cwnd - in_flight;
        if (sk_can_gso(sk) &&
            left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&
-           left * tp->mss_cache < sk->sk_gso_max_size)
+           left * tp->mss_cache < sk->sk_gso_max_size &&
+           left < sk->sk_gso_max_segs)
                return true;
        return left <= tcp_max_tso_deferred_mss(tp);
 }
index 2fd2bc9e3c644d650282ea8c66a41fab9683167f..85308b90df80a844119a8cc773783f78aab5de04 100644 (file)
@@ -5392,6 +5392,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
+       if (unlikely(sk->sk_rx_dst == NULL))
+               inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb);
        /*
         *      Header prediction.
         *      The code loosely follows the one in the famous
@@ -5605,7 +5607,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
        tcp_set_state(sk, TCP_ESTABLISHED);
 
        if (skb != NULL) {
-               inet_sk_rx_dst_set(sk, skb);
+               icsk->icsk_af_ops->sk_rx_dst_set(sk, skb);
                security_inet_conn_established(sk, skb);
        }
 
index 42b2a6a73092a9a75bd96239af003269575328f5..00a748d14062d5f0410568be79aa6dc609a201be 100644 (file)
@@ -417,10 +417,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
 
                if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
                        tp->mtu_info = info;
-                       if (!sock_owned_by_user(sk))
+                       if (!sock_owned_by_user(sk)) {
                                tcp_v4_mtu_reduced(sk);
-                       else
-                               set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags);
+                       } else {
+                               if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags))
+                                       sock_hold(sk);
+                       }
                        goto out;
                }
 
@@ -1462,6 +1464,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
                goto exit_nonewsk;
 
        newsk->sk_gso_type = SKB_GSO_TCPV4;
+       inet_sk_rx_dst_set(newsk, skb);
 
        newtp                 = tcp_sk(newsk);
        newinet               = inet_sk(newsk);
@@ -1627,9 +1630,6 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
                                sk->sk_rx_dst = NULL;
                        }
                }
-               if (unlikely(sk->sk_rx_dst == NULL))
-                       inet_sk_rx_dst_set(sk, skb);
-
                if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
                        rsk = sk;
                        goto reset;
@@ -1872,10 +1872,21 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = {
        .twsk_destructor= tcp_twsk_destructor,
 };
 
+void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
+{
+       struct dst_entry *dst = skb_dst(skb);
+
+       dst_hold(dst);
+       sk->sk_rx_dst = dst;
+       inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
+}
+EXPORT_SYMBOL(inet_sk_rx_dst_set);
+
 const struct inet_connection_sock_af_ops ipv4_specific = {
        .queue_xmit        = ip_queue_xmit,
        .send_check        = tcp_v4_send_check,
        .rebuild_header    = inet_sk_rebuild_header,
+       .sk_rx_dst_set     = inet_sk_rx_dst_set,
        .conn_request      = tcp_v4_conn_request,
        .syn_recv_sock     = tcp_v4_syn_recv_sock,
        .net_header_len    = sizeof(struct iphdr),
index 2288a6399e1e4fee43beebdc2817d38bea140bfb..0abe67bb4d3a3adb0d9df820b1fe64b6ef9da591 100644 (file)
@@ -731,6 +731,18 @@ static int __net_init tcp_net_metrics_init(struct net *net)
 
 static void __net_exit tcp_net_metrics_exit(struct net *net)
 {
+       unsigned int i;
+
+       for (i = 0; i < (1U << net->ipv4.tcp_metrics_hash_log) ; i++) {
+               struct tcp_metrics_block *tm, *next;
+
+               tm = rcu_dereference_protected(net->ipv4.tcp_metrics_hash[i].chain, 1);
+               while (tm) {
+                       next = rcu_dereference_protected(tm->tcpm_next, 1);
+                       kfree(tm);
+                       tm = next;
+               }
+       }
        kfree(net->ipv4.tcp_metrics_hash);
 }
 
index 232a90c3ec8695dfa740fe141ba113074f99a289..6ff7f10dce9d56c2f99f0cb13dab38f69eec4619 100644 (file)
@@ -387,8 +387,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                struct tcp_sock *oldtp = tcp_sk(sk);
                struct tcp_cookie_values *oldcvp = oldtp->cookie_values;
 
-               inet_sk_rx_dst_set(newsk, skb);
-
                /* TCP Cookie Transactions require space for the cookie pair,
                 * as it differs for each connection.  There is no need to
                 * copy any s_data_payload stored at the original socket.
index 3f1bcff0b10b5d2daa0307de4ff29f0ba6ddb5cc..d04632673a9e5f27725731e420d0997d91259aef 100644 (file)
@@ -910,14 +910,18 @@ void tcp_release_cb(struct sock *sk)
        if (flags & (1UL << TCP_TSQ_DEFERRED))
                tcp_tsq_handler(sk);
 
-       if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED))
+       if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) {
                tcp_write_timer_handler(sk);
-
-       if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED))
+               __sock_put(sk);
+       }
+       if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) {
                tcp_delack_timer_handler(sk);
-
-       if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED))
+               __sock_put(sk);
+       }
+       if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) {
                sk->sk_prot->mtu_reduced(sk);
+               __sock_put(sk);
+       }
 }
 EXPORT_SYMBOL(tcp_release_cb);
 
@@ -940,7 +944,7 @@ void __init tcp_tasklet_init(void)
  * We cant xmit new skbs from this context, as we might already
  * hold qdisc lock.
  */
-void tcp_wfree(struct sk_buff *skb)
+static void tcp_wfree(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
        struct tcp_sock *tp = tcp_sk(sk);
@@ -1522,21 +1526,21 @@ static void tcp_cwnd_validate(struct sock *sk)
  * when we would be allowed to send the split-due-to-Nagle skb fully.
  */
 static unsigned int tcp_mss_split_point(const struct sock *sk, const struct sk_buff *skb,
-                                       unsigned int mss_now, unsigned int cwnd)
+                                       unsigned int mss_now, unsigned int max_segs)
 {
        const struct tcp_sock *tp = tcp_sk(sk);
-       u32 needed, window, cwnd_len;
+       u32 needed, window, max_len;
 
        window = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
-       cwnd_len = mss_now * cwnd;
+       max_len = mss_now * max_segs;
 
-       if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk)))
-               return cwnd_len;
+       if (likely(max_len <= window && skb != tcp_write_queue_tail(sk)))
+               return max_len;
 
        needed = min(skb->len, window);
 
-       if (cwnd_len <= needed)
-               return cwnd_len;
+       if (max_len <= needed)
+               return max_len;
 
        return needed - needed % mss_now;
 }
@@ -1765,7 +1769,8 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        limit = min(send_win, cong_win);
 
        /* If a full-sized TSO skb can be sent, do it. */
-       if (limit >= sk->sk_gso_max_size)
+       if (limit >= min_t(unsigned int, sk->sk_gso_max_size,
+                          sk->sk_gso_max_segs * tp->mss_cache))
                goto send_now;
 
        /* Middle in queue won't get any more data, full sendable already? */
@@ -1999,7 +2004,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
                limit = mss_now;
                if (tso_segs > 1 && !tcp_urg_mode(tp))
                        limit = tcp_mss_split_point(sk, skb, mss_now,
-                                                   cwnd_quota);
+                                                   min_t(unsigned int,
+                                                         cwnd_quota,
+                                                         sk->sk_gso_max_segs));
 
                if (skb->len > limit &&
                    unlikely(tso_fragment(sk, skb, limit, mss_now, gfp)))
index 6df36ad55a38714bb9def423661066bd798cf7b4..b774a03bd1dcc1ccafa245a892ac0b312511a900 100644 (file)
@@ -252,7 +252,8 @@ static void tcp_delack_timer(unsigned long data)
                inet_csk(sk)->icsk_ack.blocked = 1;
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED);
                /* deleguate our work to tcp_release_cb() */
-               set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags);
+               if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags))
+                       sock_hold(sk);
        }
        bh_unlock_sock(sk);
        sock_put(sk);
@@ -481,7 +482,8 @@ static void tcp_write_timer(unsigned long data)
                tcp_write_timer_handler(sk);
        } else {
                /* deleguate our work to tcp_release_cb() */
-               set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags);
+               if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags))
+                       sock_hold(sk);
        }
        bh_unlock_sock(sk);
        sock_put(sk);
index b4c3582a991f94db7f6047d5b514b062ccf7e43d..6f6d1aca3c3de0e21036c075c0a13c429ef4f8ae 100644 (file)
@@ -758,7 +758,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
                uh->check = CSUM_MANGLED_0;
 
 send:
-       err = ip_send_skb(skb);
+       err = ip_send_skb(sock_net(sk), skb);
        if (err) {
                if (err == -ENOBUFS && !inet->recverr) {
                        UDP_INC_STATS_USER(sock_net(sk),
index 79181819a24fa7d3ed67b5a4c22d44e51945da63..6bc85f7c31e3c58a01a6d1aa351cd827584fad24 100644 (file)
@@ -494,8 +494,7 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
        struct net_device *dev;
        struct inet6_dev *idev;
 
-       rcu_read_lock();
-       for_each_netdev_rcu(net, dev) {
+       for_each_netdev(net, dev) {
                idev = __in6_dev_get(dev);
                if (idev) {
                        int changed = (!idev->cnf.forwarding) ^ (!newf);
@@ -504,7 +503,6 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
                                dev_forward_change(idev);
                }
        }
-       rcu_read_unlock();
 }
 
 static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
index da2e92d05c15a5052ea2cc19ba9bfc5751c23cf6..745a32042950127f3509781b6247b6434743d1d7 100644 (file)
@@ -307,10 +307,10 @@ static int __net_init ipv6_proc_init_net(struct net *net)
                goto proc_dev_snmp6_fail;
        return 0;
 
+proc_dev_snmp6_fail:
+       proc_net_remove(net, "snmp6");
 proc_snmp6_fail:
        proc_net_remove(net, "sockstat6");
-proc_dev_snmp6_fail:
-       proc_net_remove(net, "dev_snmp6");
        return -ENOMEM;
 }
 
index c66b90f71c9b9610b5dec49c038b80dffd836058..a3e60cc04a8a17e229afb44f38643ed86ac0c63e 100644 (file)
@@ -94,6 +94,18 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
 }
 #endif
 
+static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
+{
+       struct dst_entry *dst = skb_dst(skb);
+       const struct rt6_info *rt = (const struct rt6_info *)dst;
+
+       dst_hold(dst);
+       sk->sk_rx_dst = dst;
+       inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
+       if (rt->rt6i_node)
+               inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum;
+}
+
 static void tcp_v6_hash(struct sock *sk)
 {
        if (sk->sk_state != TCP_CLOSE) {
@@ -1270,6 +1282,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
        newsk->sk_gso_type = SKB_GSO_TCPV6;
        __ip6_dst_store(newsk, dst, NULL, NULL);
+       inet6_sk_rx_dst_set(newsk, skb);
 
        newtcp6sk = (struct tcp6_sock *)newsk;
        inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
@@ -1447,7 +1460,17 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
                opt_skb = skb_clone(skb, sk_gfp_atomic(sk, GFP_ATOMIC));
 
        if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
+               struct dst_entry *dst = sk->sk_rx_dst;
+
                sock_rps_save_rxhash(sk, skb);
+               if (dst) {
+                       if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif ||
+                           dst->ops->check(dst, np->rx_dst_cookie) == NULL) {
+                               dst_release(dst);
+                               sk->sk_rx_dst = NULL;
+                       }
+               }
+
                if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len))
                        goto reset;
                if (opt_skb)
@@ -1705,9 +1728,9 @@ static void tcp_v6_early_demux(struct sk_buff *skb)
                        struct dst_entry *dst = sk->sk_rx_dst;
                        struct inet_sock *icsk = inet_sk(sk);
                        if (dst)
-                               dst = dst_check(dst, 0);
+                               dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie);
                        if (dst &&
-                           icsk->rx_dst_ifindex == inet6_iif(skb))
+                           icsk->rx_dst_ifindex == skb->skb_iif)
                                skb_dst_set_noref(skb, dst);
                }
        }
@@ -1723,6 +1746,7 @@ static const struct inet_connection_sock_af_ops ipv6_specific = {
        .queue_xmit        = inet6_csk_xmit,
        .send_check        = tcp_v6_send_check,
        .rebuild_header    = inet6_sk_rebuild_header,
+       .sk_rx_dst_set     = inet6_sk_rx_dst_set,
        .conn_request      = tcp_v6_conn_request,
        .syn_recv_sock     = tcp_v6_syn_recv_sock,
        .net_header_len    = sizeof(struct ipv6hdr),
@@ -1754,6 +1778,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = {
        .queue_xmit        = ip_queue_xmit,
        .send_check        = tcp_v4_send_check,
        .rebuild_header    = inet_sk_rebuild_header,
+       .sk_rx_dst_set     = inet_sk_rx_dst_set,
        .conn_request      = tcp_v6_conn_request,
        .syn_recv_sock     = tcp_v6_syn_recv_sock,
        .net_header_len    = sizeof(struct iphdr),
index ef39812107b17c2c90c38e24df363e76008dd745..f8c4c08ffb609d2840adb721e395fcbe99a636d7 100644 (file)
@@ -73,6 +73,13 @@ static int xfrm6_get_tos(const struct flowi *fl)
        return 0;
 }
 
+static void xfrm6_init_dst(struct net *net, struct xfrm_dst *xdst)
+{
+       struct rt6_info *rt = (struct rt6_info *)xdst;
+
+       rt6_init_peer(rt, net->ipv6.peers);
+}
+
 static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
                           int nfheader_len)
 {
@@ -286,6 +293,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
        .get_saddr =            xfrm6_get_saddr,
        .decode_session =       _decode_session6,
        .get_tos =              xfrm6_get_tos,
+       .init_dst =             xfrm6_init_dst,
        .init_path =            xfrm6_init_path,
        .fill_dst =             xfrm6_fill_dst,
        .blackhole_route =      ip6_blackhole_route,
index 35e1e4bde58730d8395e2870d552230bca3a9c3d..927547171bc7119f57a7b8afecf453ec5eeabf61 100644 (file)
@@ -410,6 +410,7 @@ static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr,
        lsa->l2tp_family = AF_INET6;
        lsa->l2tp_flowinfo = 0;
        lsa->l2tp_scope_id = 0;
+       lsa->l2tp_unused = 0;
        if (peer) {
                if (!lsk->peer_conn_id)
                        return -ENOTCONN;
index f6fe4d400502df780e1f57e574e5b4a1574b7f8d..c2190005a11410e2f95141fb841dadc051157a8b 100644 (file)
@@ -969,14 +969,13 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
        struct sockaddr_llc sllc;
        struct sock *sk = sock->sk;
        struct llc_sock *llc = llc_sk(sk);
-       int rc = 0;
+       int rc = -EBADF;
 
        memset(&sllc, 0, sizeof(sllc));
        lock_sock(sk);
        if (sock_flag(sk, SOCK_ZAPPED))
                goto out;
        *uaddrlen = sizeof(sllc);
-       memset(uaddr, 0, *uaddrlen);
        if (peer) {
                rc = -ENOTCONN;
                if (sk->sk_state != TCP_ESTABLISHED)
@@ -1206,7 +1205,7 @@ static int __init llc2_init(void)
        rc = llc_proc_init();
        if (rc != 0) {
                printk(llc_proc_err_msg);
-               goto out_unregister_llc_proto;
+               goto out_station;
        }
        rc = llc_sysctl_init();
        if (rc) {
@@ -1226,7 +1225,8 @@ out_sysctl:
        llc_sysctl_exit();
 out_proc:
        llc_proc_exit();
-out_unregister_llc_proto:
+out_station:
+       llc_station_exit();
        proto_unregister(&llc_proto);
        goto out;
 }
index e32cab44ea959d8f49781d46580b4204afb7e3cb..dd3e83328ad544d3183233da61fa40289975de51 100644 (file)
@@ -42,6 +42,7 @@ static void (*llc_type_handlers[2])(struct llc_sap *sap,
 void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
                                            struct sk_buff *skb))
 {
+       smp_wmb(); /* ensure initialisation is complete before it's called */
        if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
                llc_type_handlers[type - 1] = handler;
 }
@@ -50,11 +51,19 @@ void llc_remove_pack(int type)
 {
        if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
                llc_type_handlers[type - 1] = NULL;
+       synchronize_net();
 }
 
 void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
 {
+       /* Ensure initialisation is complete before it's called */
+       if (handler)
+               smp_wmb();
+
        llc_station_handler = handler;
+
+       if (!handler)
+               synchronize_net();
 }
 
 /**
@@ -150,6 +159,8 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
        int dest;
        int (*rcv)(struct sk_buff *, struct net_device *,
                   struct packet_type *, struct net_device *);
+       void (*sta_handler)(struct sk_buff *skb);
+       void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb);
 
        if (!net_eq(dev_net(dev), &init_net))
                goto drop;
@@ -182,7 +193,8 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
         */
        rcv = rcu_dereference(sap->rcv_func);
        dest = llc_pdu_type(skb);
-       if (unlikely(!dest || !llc_type_handlers[dest - 1])) {
+       sap_handler = dest ? ACCESS_ONCE(llc_type_handlers[dest - 1]) : NULL;
+       if (unlikely(!sap_handler)) {
                if (rcv)
                        rcv(skb, dev, pt, orig_dev);
                else
@@ -193,7 +205,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
                        if (cskb)
                                rcv(cskb, dev, pt, orig_dev);
                }
-               llc_type_handlers[dest - 1](sap, skb);
+               sap_handler(sap, skb);
        }
        llc_sap_put(sap);
 out:
@@ -202,9 +214,10 @@ drop:
        kfree_skb(skb);
        goto out;
 handle_station:
-       if (!llc_station_handler)
+       sta_handler = ACCESS_ONCE(llc_station_handler);
+       if (!sta_handler)
                goto drop;
-       llc_station_handler(skb);
+       sta_handler(skb);
        goto out;
 }
 
index 39a8d8924b9c989747502774a4360b78e98d6ba4..b2f2bac2c2a2397b5fd6f6b79659996270b96377 100644 (file)
@@ -268,7 +268,7 @@ static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
 out:
        return rc;
 free:
-       kfree_skb(skb);
+       kfree_skb(nskb);
        goto out;
 }
 
@@ -293,7 +293,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
 out:
        return rc;
 free:
-       kfree_skb(skb);
+       kfree_skb(nskb);
        goto out;
 }
 
@@ -322,7 +322,7 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
 out:
        return rc;
 free:
-       kfree_skb(skb);
+       kfree_skb(nskb);
        goto out;
 }
 
@@ -687,12 +687,8 @@ static void llc_station_rcv(struct sk_buff *skb)
        llc_station_state_process(skb);
 }
 
-int __init llc_station_init(void)
+void __init llc_station_init(void)
 {
-       int rc = -ENOBUFS;
-       struct sk_buff *skb;
-       struct llc_station_state_ev *ev;
-
        skb_queue_head_init(&llc_main_station.mac_pdu_q);
        skb_queue_head_init(&llc_main_station.ev_q.list);
        spin_lock_init(&llc_main_station.ev_q.lock);
@@ -700,23 +696,12 @@ int __init llc_station_init(void)
                        (unsigned long)&llc_main_station);
        llc_main_station.ack_timer.expires  = jiffies +
                                                sysctl_llc_station_ack_timeout;
-       skb = alloc_skb(0, GFP_ATOMIC);
-       if (!skb)
-               goto out;
-       rc = 0;
-       llc_set_station_handler(llc_station_rcv);
-       ev = llc_station_ev(skb);
-       memset(ev, 0, sizeof(*ev));
        llc_main_station.maximum_retry  = 1;
-       llc_main_station.state          = LLC_STATION_STATE_DOWN;
-       ev->type        = LLC_STATION_EV_TYPE_SIMPLE;
-       ev->prim_type   = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
-       rc = llc_station_next_state(skb);
-out:
-       return rc;
+       llc_main_station.state          = LLC_STATION_STATE_UP;
+       llc_set_station_handler(llc_station_rcv);
 }
 
-void __exit llc_station_exit(void)
+void llc_station_exit(void)
 {
        llc_set_station_handler(NULL);
 }
index 6fac18c0423ff391213de03242299ff3b1e4b965..85572353a7e37d59b64ced140d75f7a9b8d3fb81 100644 (file)
@@ -622,6 +622,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
 
        del_timer_sync(&sdata->u.mesh.housekeeping_timer);
        del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
+       del_timer_sync(&sdata->u.mesh.mesh_path_timer);
        /*
         * If the timer fired while we waited for it, it will have
         * requeued the work. Now the work will be running again
@@ -634,6 +635,8 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
        local->fif_other_bss--;
        atomic_dec(&local->iff_allmultis);
        ieee80211_configure_filter(local);
+
+       sdata->u.mesh.timers_running = 0;
 }
 
 static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
index cef0c9e79aba5ff4657938478dea6e829e10b164..a4a5acdbaa4dd3ac5e2fb8c5f0ff1d1b97553d6a 100644 (file)
@@ -1430,6 +1430,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
        del_timer_sync(&sdata->u.mgd.timer);
        del_timer_sync(&sdata->u.mgd.chswitch_timer);
+
+       sdata->u.mgd.timers_running = 0;
 }
 
 void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
index bcaee5d1283915efdbc8c63f4365c7ed42d486dc..839dd9737989ec78bbb979c814953b1bdd0187a8 100644 (file)
@@ -299,7 +299,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
        if (local->scan_req != local->int_scan_req)
                cfg80211_scan_done(local->scan_req, aborted);
        local->scan_req = NULL;
-       local->scan_sdata = NULL;
+       rcu_assign_pointer(local->scan_sdata, NULL);
 
        local->scanning = 0;
        local->scan_channel = NULL;
@@ -984,7 +984,6 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
                        kfree(local->sched_scan_ies.ie[i]);
 
                drv_sched_scan_stop(local, sdata);
-               rcu_assign_pointer(local->sched_scan_sdata, NULL);
        }
 out:
        mutex_unlock(&local->mtx);
index 84444dda194b61806efaeadde4c2458f502d8283..72bf32a84874718927a4bcbdc2e26395be00bdd8 100644 (file)
@@ -2759,6 +2759,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        {
                struct ip_vs_timeout_user t;
 
+               memset(&t, 0, sizeof(t));
                __ip_vs_get_timeouts(net, &t);
                if (copy_to_user(user, &t, sizeof(t)) != 0)
                        ret = -EFAULT;
index 45cf602a76bc1f030f1a1870679ec07d62250eee..527651a53a45ded66c97162f4e072ca55a7d1efa 100644 (file)
@@ -361,23 +361,6 @@ static void evict_oldest_expect(struct nf_conn *master,
        }
 }
 
-static inline int refresh_timer(struct nf_conntrack_expect *i)
-{
-       struct nf_conn_help *master_help = nfct_help(i->master);
-       const struct nf_conntrack_expect_policy *p;
-
-       if (!del_timer(&i->timeout))
-               return 0;
-
-       p = &rcu_dereference_protected(
-               master_help->helper,
-               lockdep_is_held(&nf_conntrack_lock)
-               )->expect_policy[i->class];
-       i->timeout.expires = jiffies + p->timeout * HZ;
-       add_timer(&i->timeout);
-       return 1;
-}
-
 static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
 {
        const struct nf_conntrack_expect_policy *p;
@@ -386,7 +369,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
        struct nf_conn_help *master_help = nfct_help(master);
        struct nf_conntrack_helper *helper;
        struct net *net = nf_ct_exp_net(expect);
-       struct hlist_node *n;
+       struct hlist_node *n, *next;
        unsigned int h;
        int ret = 1;
 
@@ -395,12 +378,12 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
                goto out;
        }
        h = nf_ct_expect_dst_hash(&expect->tuple);
-       hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) {
+       hlist_for_each_entry_safe(i, n, next, &net->ct.expect_hash[h], hnode) {
                if (expect_matches(i, expect)) {
-                       /* Refresh timer: if it's dying, ignore.. */
-                       if (refresh_timer(i)) {
-                               ret = 0;
-                               goto out;
+                       if (del_timer(&i->timeout)) {
+                               nf_ct_unlink_expect(i);
+                               nf_ct_expect_put(i);
+                               break;
                        }
                } else if (expect_clash(i, expect)) {
                        ret = -EBUSY;
index 14f67a2cbcb5f065e2b4eab61a59c2447c6826d7..da4fc37a8578b6ef4590cbd0abf6e04241ebb8fc 100644 (file)
@@ -1896,10 +1896,15 @@ static int
 ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
 {
        struct nlattr *cda[CTA_MAX+1];
+       int ret;
 
        nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy);
 
-       return ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+       spin_lock_bh(&nf_conntrack_lock);
+       ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
+       spin_unlock_bh(&nf_conntrack_lock);
+
+       return ret;
 }
 
 static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
index 758a1bacc126468a4a495748eb034ac80ed65d01..5c0a112aeee6adc580f0303b50e6821d12e8839e 100644 (file)
@@ -183,12 +183,12 @@ static int media_len(const struct nf_conn *ct, const char *dptr,
        return len + digits_len(ct, dptr, limit, shift);
 }
 
-static int parse_addr(const struct nf_conn *ct, const char *cp,
-                      const char **endp, union nf_inet_addr *addr,
-                      const char *limit)
+static int sip_parse_addr(const struct nf_conn *ct, const char *cp,
+                         const char **endp, union nf_inet_addr *addr,
+                         const char *limit, bool delim)
 {
        const char *end;
-       int ret = 0;
+       int ret;
 
        if (!ct)
                return 0;
@@ -197,16 +197,28 @@ static int parse_addr(const struct nf_conn *ct, const char *cp,
        switch (nf_ct_l3num(ct)) {
        case AF_INET:
                ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
+               if (ret == 0)
+                       return 0;
                break;
        case AF_INET6:
+               if (cp < limit && *cp == '[')
+                       cp++;
+               else if (delim)
+                       return 0;
+
                ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
+               if (ret == 0)
+                       return 0;
+
+               if (end < limit && *end == ']')
+                       end++;
+               else if (delim)
+                       return 0;
                break;
        default:
                BUG();
        }
 
-       if (ret == 0 || end == cp)
-               return 0;
        if (endp)
                *endp = end;
        return 1;
@@ -219,7 +231,7 @@ static int epaddr_len(const struct nf_conn *ct, const char *dptr,
        union nf_inet_addr addr;
        const char *aux = dptr;
 
-       if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
+       if (!sip_parse_addr(ct, dptr, &dptr, &addr, limit, true)) {
                pr_debug("ip: %s parse failed.!\n", dptr);
                return 0;
        }
@@ -296,7 +308,7 @@ int ct_sip_parse_request(const struct nf_conn *ct,
                return 0;
        dptr += shift;
 
-       if (!parse_addr(ct, dptr, &end, addr, limit))
+       if (!sip_parse_addr(ct, dptr, &end, addr, limit, true))
                return -1;
        if (end < limit && *end == ':') {
                end++;
@@ -550,7 +562,7 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
        if (ret == 0)
                return ret;
 
-       if (!parse_addr(ct, dptr + *matchoff, &c, addr, limit))
+       if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true))
                return -1;
        if (*c == ':') {
                c++;
@@ -599,7 +611,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
                               unsigned int dataoff, unsigned int datalen,
                               const char *name,
                               unsigned int *matchoff, unsigned int *matchlen,
-                              union nf_inet_addr *addr)
+                              union nf_inet_addr *addr, bool delim)
 {
        const char *limit = dptr + datalen;
        const char *start, *end;
@@ -613,7 +625,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr,
                return 0;
 
        start += strlen(name);
-       if (!parse_addr(ct, start, &end, addr, limit))
+       if (!sip_parse_addr(ct, start, &end, addr, limit, delim))
                return 0;
        *matchoff = start - dptr;
        *matchlen = end - start;
@@ -675,6 +687,47 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
        return 1;
 }
 
+static int sdp_parse_addr(const struct nf_conn *ct, const char *cp,
+                         const char **endp, union nf_inet_addr *addr,
+                         const char *limit)
+{
+       const char *end;
+       int ret;
+
+       memset(addr, 0, sizeof(*addr));
+       switch (nf_ct_l3num(ct)) {
+       case AF_INET:
+               ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
+               break;
+       case AF_INET6:
+               ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
+               break;
+       default:
+               BUG();
+       }
+
+       if (ret == 0)
+               return 0;
+       if (endp)
+               *endp = end;
+       return 1;
+}
+
+/* skip ip address. returns its length. */
+static int sdp_addr_len(const struct nf_conn *ct, const char *dptr,
+                       const char *limit, int *shift)
+{
+       union nf_inet_addr addr;
+       const char *aux = dptr;
+
+       if (!sdp_parse_addr(ct, dptr, &dptr, &addr, limit)) {
+               pr_debug("ip: %s parse failed.!\n", dptr);
+               return 0;
+       }
+
+       return dptr - aux;
+}
+
 /* SDP header parsing: a SDP session description contains an ordered set of
  * headers, starting with a section containing general session parameters,
  * optionally followed by multiple media descriptions.
@@ -686,10 +739,10 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr,
  */
 static const struct sip_header ct_sdp_hdrs[] = {
        [SDP_HDR_VERSION]               = SDP_HDR("v=", NULL, digits_len),
-       [SDP_HDR_OWNER_IP4]             = SDP_HDR("o=", "IN IP4 ", epaddr_len),
-       [SDP_HDR_CONNECTION_IP4]        = SDP_HDR("c=", "IN IP4 ", epaddr_len),
-       [SDP_HDR_OWNER_IP6]             = SDP_HDR("o=", "IN IP6 ", epaddr_len),
-       [SDP_HDR_CONNECTION_IP6]        = SDP_HDR("c=", "IN IP6 ", epaddr_len),
+       [SDP_HDR_OWNER_IP4]             = SDP_HDR("o=", "IN IP4 ", sdp_addr_len),
+       [SDP_HDR_CONNECTION_IP4]        = SDP_HDR("c=", "IN IP4 ", sdp_addr_len),
+       [SDP_HDR_OWNER_IP6]             = SDP_HDR("o=", "IN IP6 ", sdp_addr_len),
+       [SDP_HDR_CONNECTION_IP6]        = SDP_HDR("c=", "IN IP6 ", sdp_addr_len),
        [SDP_HDR_MEDIA]                 = SDP_HDR("m=", NULL, media_len),
 };
 
@@ -775,8 +828,8 @@ static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr,
        if (ret <= 0)
                return ret;
 
-       if (!parse_addr(ct, dptr + *matchoff, NULL, addr,
-                       dptr + *matchoff + *matchlen))
+       if (!sdp_parse_addr(ct, dptr + *matchoff, NULL, addr,
+                           dptr + *matchoff + *matchlen))
                return -1;
        return 1;
 }
@@ -1515,7 +1568,6 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
 }
 
 static struct nf_conntrack_helper sip[MAX_PORTS][4] __read_mostly;
-static char sip_names[MAX_PORTS][4][sizeof("sip-65535")] __read_mostly;
 
 static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {
        [SIP_EXPECT_SIGNALLING] = {
@@ -1585,9 +1637,9 @@ static int __init nf_conntrack_sip_init(void)
                        sip[i][j].me = THIS_MODULE;
 
                        if (ports[i] == SIP_PORT)
-                               sprintf(sip_names[i][j], "sip");
+                               sprintf(sip[i][j].name, "sip");
                        else
-                               sprintf(sip_names[i][j], "sip-%u", i);
+                               sprintf(sip[i][j].name, "sip-%u", i);
 
                        pr_debug("port #%u: %u\n", i, ports[i]);
 
index 5463969da45b9a30dbbb1802624b0e9e8bf92a29..1445d73533ed13ac9aa43dd85d6f58b4a006c130 100644 (file)
@@ -1362,7 +1362,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        if (NULL == siocb->scm)
                siocb->scm = &scm;
 
-       err = scm_send(sock, msg, siocb->scm);
+       err = scm_send(sock, msg, siocb->scm, true);
        if (err < 0)
                return err;
 
index ceaca7c134a011b659bc439dff6de58269b532b4..aee7196aac36c990eedfc7b494a04351c29bb167 100644 (file)
@@ -1079,7 +1079,7 @@ static void *packet_current_rx_frame(struct packet_sock *po,
        default:
                WARN(1, "TPACKET version not supported\n");
                BUG();
-               return 0;
+               return NULL;
        }
 }
 
@@ -1273,6 +1273,14 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po)
        spin_unlock(&f->lock);
 }
 
+bool match_fanout_group(struct packet_type *ptype, struct sock * sk)
+{
+       if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout)
+               return true;
+
+       return false;
+}
+
 static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
 {
        struct packet_sock *po = pkt_sk(sk);
@@ -1325,6 +1333,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
                match->prot_hook.dev = po->prot_hook.dev;
                match->prot_hook.func = packet_rcv_fanout;
                match->prot_hook.af_packet_priv = match;
+               match->prot_hook.id_match = match_fanout_group;
                dev_add_pack(&match->prot_hook);
                list_add(&match->list, &fanout_list);
        }
@@ -1936,7 +1945,6 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
 
        if (likely(po->tx_ring.pg_vec)) {
                ph = skb_shinfo(skb)->destructor_arg;
-               BUG_ON(__packet_get_status(po, ph) != TP_STATUS_SENDING);
                BUG_ON(atomic_read(&po->tx_ring.pending) == 0);
                atomic_dec(&po->tx_ring.pending);
                __packet_set_status(po, ph, TP_STATUS_AVAILABLE);
index f10fb8256442014afbba6b85a23a3544ee0ec9e4..05d60859d8e3d1c2eb700ff7d1d63d81d9f98894 100644 (file)
@@ -67,6 +67,9 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
        struct tcf_common *pc;
        int ret = 0;
        int err;
+#ifdef CONFIG_GACT_PROB
+       struct tc_gact_p *p_parm = NULL;
+#endif
 
        if (nla == NULL)
                return -EINVAL;
@@ -82,6 +85,12 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
 #ifndef CONFIG_GACT_PROB
        if (tb[TCA_GACT_PROB] != NULL)
                return -EOPNOTSUPP;
+#else
+       if (tb[TCA_GACT_PROB]) {
+               p_parm = nla_data(tb[TCA_GACT_PROB]);
+               if (p_parm->ptype >= MAX_RAND)
+                       return -EINVAL;
+       }
 #endif
 
        pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info);
@@ -103,8 +112,7 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
        spin_lock_bh(&gact->tcf_lock);
        gact->tcf_action = parm->action;
 #ifdef CONFIG_GACT_PROB
-       if (tb[TCA_GACT_PROB] != NULL) {
-               struct tc_gact_p *p_parm = nla_data(tb[TCA_GACT_PROB]);
+       if (p_parm) {
                gact->tcfg_paction = p_parm->paction;
                gact->tcfg_pval    = p_parm->pval;
                gact->tcfg_ptype   = p_parm->ptype;
@@ -133,7 +141,7 @@ static int tcf_gact(struct sk_buff *skb, const struct tc_action *a,
 
        spin_lock(&gact->tcf_lock);
 #ifdef CONFIG_GACT_PROB
-       if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL)
+       if (gact->tcfg_ptype)
                action = gact_rand[gact->tcfg_ptype](gact);
        else
                action = gact->tcf_action;
index 60e281ad0f07292d5b60b0501e465c1316df433a..58fb3c7aab9eea8a0e65851948dd3d81da4fe3b8 100644 (file)
@@ -185,7 +185,12 @@ err3:
 err2:
        kfree(tname);
 err1:
-       kfree(pc);
+       if (ret == ACT_P_CREATED) {
+               if (est)
+                       gen_kill_estimator(&pc->tcfc_bstats,
+                                          &pc->tcfc_rate_est);
+               kfree_rcu(pc, tcfc_rcu);
+       }
        return err;
 }
 
index fe81cc18e9e0dd20624aa4a6e7aa5aa098f737fc..9c0fd0c788145c0b6fa877463022f5ec90a707e2 100644 (file)
@@ -200,13 +200,12 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
 out:
        if (err) {
                m->tcf_qstats.overlimits++;
-               /* should we be asking for packet to be dropped?
-                * may make sense for redirect case only
-                */
-               retval = TC_ACT_SHOT;
-       } else {
+               if (m->tcfm_eaction != TCA_EGRESS_MIRROR)
+                       retval = TC_ACT_SHOT;
+               else
+                       retval = m->tcf_action;
+       } else
                retval = m->tcf_action;
-       }
        spin_unlock(&m->tcf_lock);
 
        return retval;
index 26aa2f6ce257c5b39541df44db40c950fcd67045..45c53ab067a63240357a970e15ab2633802211d6 100644 (file)
@@ -74,7 +74,10 @@ static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est,
                p = to_pedit(pc);
                keys = kmalloc(ksize, GFP_KERNEL);
                if (keys == NULL) {
-                       kfree(pc);
+                       if (est)
+                               gen_kill_estimator(&pc->tcfc_bstats,
+                                                  &pc->tcfc_rate_est);
+                       kfree_rcu(pc, tcfc_rcu);
                        return -ENOMEM;
                }
                ret = ACT_P_CREATED;
index 3922f2a2821b83cf3f9db318980a7cad06111e1f..3714f60f0b3c5869725e449de8456ec9bd6b20fe 100644 (file)
@@ -131,7 +131,10 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
                d = to_defact(pc);
                ret = alloc_defdata(d, defdata);
                if (ret < 0) {
-                       kfree(pc);
+                       if (est)
+                               gen_kill_estimator(&pc->tcfc_bstats,
+                                                  &pc->tcfc_rate_est);
+                       kfree_rcu(pc, tcfc_rcu);
                        return ret;
                }
                d->tcf_action = parm->action;
index 9af01f3df18c66b6325c8afe628758b56e306952..e4723d31fdd56d6a46b2519afd19d612c7336749 100644 (file)
@@ -203,6 +203,34 @@ out:
        return index;
 }
 
+/* Length of the next packet (0 if the queue is empty). */
+static unsigned int qdisc_peek_len(struct Qdisc *sch)
+{
+       struct sk_buff *skb;
+
+       skb = sch->ops->peek(sch);
+       return skb ? qdisc_pkt_len(skb) : 0;
+}
+
+static void qfq_deactivate_class(struct qfq_sched *, struct qfq_class *);
+static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
+                              unsigned int len);
+
+static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl,
+                                   u32 lmax, u32 inv_w, int delta_w)
+{
+       int i;
+
+       /* update qfq-specific data */
+       cl->lmax = lmax;
+       cl->inv_w = inv_w;
+       i = qfq_calc_index(cl->inv_w, cl->lmax);
+
+       cl->grp = &q->groups[i];
+
+       q->wsum += delta_w;
+}
+
 static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
                            struct nlattr **tca, unsigned long *arg)
 {
@@ -250,6 +278,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
                lmax = 1UL << QFQ_MTU_SHIFT;
 
        if (cl != NULL) {
+               bool need_reactivation = false;
+
                if (tca[TCA_RATE]) {
                        err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
                                                    qdisc_root_sleeping_lock(sch),
@@ -258,12 +288,29 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
                                return err;
                }
 
-               if (inv_w != cl->inv_w) {
-                       sch_tree_lock(sch);
-                       q->wsum += delta_w;
-                       cl->inv_w = inv_w;
-                       sch_tree_unlock(sch);
+               if (lmax == cl->lmax && inv_w == cl->inv_w)
+                       return 0; /* nothing to update */
+
+               i = qfq_calc_index(inv_w, lmax);
+               sch_tree_lock(sch);
+               if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
+                       /*
+                        * shift cl->F back, to not charge the
+                        * class for the not-yet-served head
+                        * packet
+                        */
+                       cl->F = cl->S;
+                       /* remove class from its slot in the old group */
+                       qfq_deactivate_class(q, cl);
+                       need_reactivation = true;
                }
+
+               qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
+
+               if (need_reactivation) /* activate in new group */
+                       qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
+               sch_tree_unlock(sch);
+
                return 0;
        }
 
@@ -273,11 +320,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 
        cl->refcnt = 1;
        cl->common.classid = classid;
-       cl->lmax = lmax;
-       cl->inv_w = inv_w;
-       i = qfq_calc_index(cl->inv_w, cl->lmax);
 
-       cl->grp = &q->groups[i];
+       qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
 
        cl->qdisc = qdisc_create_dflt(sch->dev_queue,
                                      &pfifo_qdisc_ops, classid);
@@ -294,7 +338,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
                        return err;
                }
        }
-       q->wsum += weight;
 
        sch_tree_lock(sch);
        qdisc_class_hash_insert(&q->clhash, &cl->common);
@@ -711,15 +754,6 @@ static void qfq_update_eligible(struct qfq_sched *q, u64 old_V)
        }
 }
 
-/* What is length of next packet in queue (0 if queue is empty) */
-static unsigned int qdisc_peek_len(struct Qdisc *sch)
-{
-       struct sk_buff *skb;
-
-       skb = sch->ops->peek(sch);
-       return skb ? qdisc_pkt_len(skb) : 0;
-}
-
 /*
  * Updates the class, returns true if also the group needs to be updated.
  */
@@ -843,11 +877,8 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
 static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct qfq_sched *q = qdisc_priv(sch);
-       struct qfq_group *grp;
        struct qfq_class *cl;
        int err;
-       u64 roundedS;
-       int s;
 
        cl = qfq_classify(skb, sch, &err);
        if (cl == NULL) {
@@ -876,11 +907,25 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                return err;
 
        /* If reach this point, queue q was idle */
-       grp = cl->grp;
+       qfq_activate_class(q, cl, qdisc_pkt_len(skb));
+
+       return err;
+}
+
+/*
+ * Handle class switch from idle to backlogged.
+ */
+static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
+                              unsigned int pkt_len)
+{
+       struct qfq_group *grp = cl->grp;
+       u64 roundedS;
+       int s;
+
        qfq_update_start(q, cl);
 
        /* compute new finish time and rounded start. */
-       cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w;
+       cl->F = cl->S + (u64)pkt_len * cl->inv_w;
        roundedS = qfq_round_down(cl->S, grp->slot_shift);
 
        /*
@@ -917,8 +962,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 skip_update:
        qfq_slot_insert(grp, cl, roundedS);
-
-       return err;
 }
 
 
index dfe5b66c97e0bc836efed43ad080dec620301306..a5471f804d994ece8c31df6be0e04d5076b6dfd0 100644 (file)
@@ -2657,6 +2657,7 @@ static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
        if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
                return -EFAULT;
 
+       memset(&ifc, 0, sizeof(ifc));
        if (ifc32.ifcbuf == 0) {
                ifc32.ifc_len = 0;
                ifc.ifc_len = 0;
index 88f2bf671960d444e73d3d9eba2998f75ac2885b..bac973a313673eaab9dc5300a86cef0cfbd577e0 100644 (file)
@@ -316,7 +316,6 @@ static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)
  */
 void svc_xprt_enqueue(struct svc_xprt *xprt)
 {
-       struct svc_serv *serv = xprt->xpt_server;
        struct svc_pool *pool;
        struct svc_rqst *rqstp;
        int cpu;
@@ -362,8 +361,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
                                rqstp, rqstp->rq_xprt);
                rqstp->rq_xprt = xprt;
                svc_xprt_get(xprt);
-               rqstp->rq_reserved = serv->sv_max_mesg;
-               atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
                pool->sp_stats.threads_woken++;
                wake_up(&rqstp->rq_wait);
        } else {
@@ -640,8 +637,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
        if (xprt) {
                rqstp->rq_xprt = xprt;
                svc_xprt_get(xprt);
-               rqstp->rq_reserved = serv->sv_max_mesg;
-               atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
 
                /* As there is a shortage of threads and this request
                 * had to be queued, don't allow the thread to wait so
@@ -738,6 +733,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
                else
                        len = xprt->xpt_ops->xpo_recvfrom(rqstp);
                dprintk("svc: got len=%d\n", len);
+               rqstp->rq_reserved = serv->sv_max_mesg;
+               atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
        }
        svc_xprt_received(xprt);
 
@@ -794,7 +791,8 @@ int svc_send(struct svc_rqst *rqstp)
 
        /* Grab mutex to serialize outgoing data. */
        mutex_lock(&xprt->xpt_mutex);
-       if (test_bit(XPT_DEAD, &xprt->xpt_flags))
+       if (test_bit(XPT_DEAD, &xprt->xpt_flags)
+                       || test_bit(XPT_CLOSE, &xprt->xpt_flags))
                len = -ENOTCONN;
        else
                len = xprt->xpt_ops->xpo_sendto(rqstp);
index 18bc130255a75e537f87d15bddde82faf165d91e..998aa8c1807cd7cd548023d4ea2e80fedc9c2ca9 100644 (file)
@@ -1129,9 +1129,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
        if (len >= 0)
                svsk->sk_tcplen += len;
        if (len != want) {
+               svc_tcp_save_pages(svsk, rqstp);
                if (len < 0 && len != -EAGAIN)
                        goto err_other;
-               svc_tcp_save_pages(svsk, rqstp);
                dprintk("svc: incomplete TCP record (%d of %d)\n",
                        svsk->sk_tcplen, svsk->sk_reclen);
                goto err_noclose;
index e4768c180da237c176e2e9491091a94420f4febe..c5ee4ff613641b3f8439f1c9cb6b22d55a1ff7f2 100644 (file)
@@ -1450,7 +1450,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
        wait_for_unix_gc();
-       err = scm_send(sock, msg, siocb->scm);
+       err = scm_send(sock, msg, siocb->scm, false);
        if (err < 0)
                return err;
 
@@ -1619,7 +1619,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
        wait_for_unix_gc();
-       err = scm_send(sock, msg, siocb->scm);
+       err = scm_send(sock, msg, siocb->scm, false);
        if (err < 0)
                return err;
 
index 31b40cc4a9c3c59bac7986e3c5c8725153381179..dcd64d5b07aadfba26a799506452a9b04fe8e7d3 100644 (file)
@@ -952,6 +952,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
                 */
                synchronize_rcu();
                INIT_LIST_HEAD(&wdev->list);
+               /*
+                * Ensure that all events have been processed and
+                * freed.
+                */
+               cfg80211_process_wdev_events(wdev);
                break;
        case NETDEV_PRE_UP:
                if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
index 5206c6844fd735b5aac540a3afe7337ce79963d7..bc7430b54771af18e903ee1d263ede3b4eb1b78f 100644 (file)
@@ -426,6 +426,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
                          struct net_device *dev, enum nl80211_iftype ntype,
                          u32 *flags, struct vif_params *params);
 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
+void cfg80211_process_wdev_events(struct wireless_dev *wdev);
 
 int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
                                 struct wireless_dev *wdev,
index 2303ee73b50ad2fc40dc136c9250861e9bb890ee..2ded3c7fad063a067151595c774b9bddd14bdc9a 100644 (file)
@@ -680,6 +680,8 @@ static u32 map_regdom_flags(u32 rd_flags)
                channel_flags |= IEEE80211_CHAN_NO_IBSS;
        if (rd_flags & NL80211_RRF_DFS)
                channel_flags |= IEEE80211_CHAN_RADAR;
+       if (rd_flags & NL80211_RRF_NO_OFDM)
+               channel_flags |= IEEE80211_CHAN_NO_OFDM;
        return channel_flags;
 }
 
@@ -901,7 +903,21 @@ static void handle_channel(struct wiphy *wiphy,
        chan->max_antenna_gain = min(chan->orig_mag,
                (int) MBI_TO_DBI(power_rule->max_antenna_gain));
        chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
-       chan->max_power = min(chan->max_power, chan->max_reg_power);
+       if (chan->orig_mpwr) {
+               /*
+                * Devices that have their own custom regulatory domain
+                * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
+                * passed country IE power settings.
+                */
+               if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
+                   wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
+                   wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
+                       chan->max_power = chan->max_reg_power;
+               else
+                       chan->max_power = min(chan->orig_mpwr,
+                                             chan->max_reg_power);
+       } else
+               chan->max_power = chan->max_reg_power;
 }
 
 static void handle_band(struct wiphy *wiphy,
@@ -1885,6 +1901,7 @@ static void restore_custom_reg_settings(struct wiphy *wiphy)
                        chan->flags = chan->orig_flags;
                        chan->max_antenna_gain = chan->orig_mag;
                        chan->max_power = chan->orig_mpwr;
+                       chan->beacon_found = false;
                }
        }
 }
index 26f8cd30f712dc190d9e207e4dff989a75106c66..994e2f0cc7a8a12fc34cbe61fdee97afde3df10b 100644 (file)
@@ -735,7 +735,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
        wdev->connect_keys = NULL;
 }
 
-static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
+void cfg80211_process_wdev_events(struct wireless_dev *wdev)
 {
        struct cfg80211_event *ev;
        unsigned long flags;
index c5a5165a5927a185043bdc83e8c9c4e25f549753..5a2aa17e4d3c4a3667783266ddbb8992a3eff6bd 100644 (file)
@@ -1357,6 +1357,8 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
 
                memset(dst + 1, 0, sizeof(*xdst) - sizeof(*dst));
                xdst->flo.ops = &xfrm_bundle_fc_ops;
+               if (afinfo->init_dst)
+                       afinfo->init_dst(net, xdst);
        } else
                xdst = ERR_PTR(-ENOBUFS);
 
index 5b228f97d4b3308a950ae857828e04e90df86848..87cd0e4d42829a19797ae3e2371c47723fd40fb7 100644 (file)
@@ -415,8 +415,17 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)
        if (x->lft.hard_add_expires_seconds) {
                long tmo = x->lft.hard_add_expires_seconds +
                        x->curlft.add_time - now;
-               if (tmo <= 0)
-                       goto expired;
+               if (tmo <= 0) {
+                       if (x->xflags & XFRM_SOFT_EXPIRE) {
+                               /* enter hard expire without soft expire first?!
+                                * setting a new date could trigger this.
+                                * workarbound: fix x->curflt.add_time by below:
+                                */
+                               x->curlft.add_time = now - x->saved_tmo - 1;
+                               tmo = x->lft.hard_add_expires_seconds - x->saved_tmo;
+                       } else
+                               goto expired;
+               }
                if (tmo < next)
                        next = tmo;
        }
@@ -433,10 +442,14 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)
        if (x->lft.soft_add_expires_seconds) {
                long tmo = x->lft.soft_add_expires_seconds +
                        x->curlft.add_time - now;
-               if (tmo <= 0)
+               if (tmo <= 0) {
                        warn = 1;
-               else if (tmo < next)
+                       x->xflags &= ~XFRM_SOFT_EXPIRE;
+               } else if (tmo < next) {
                        next = tmo;
+                       x->xflags |= XFRM_SOFT_EXPIRE;
+                       x->saved_tmo = tmo;
+               }
        }
        if (x->lft.soft_use_expires_seconds) {
                long tmo = x->lft.soft_use_expires_seconds +
index 913d6bdfdda3ecb44f521af79980019d5a531399..ca05ba217f5fd4038bcc511adff8a5b95823fb3e 100755 (executable)
@@ -3016,7 +3016,8 @@ sub process {
                                        $herectx .= raw_line($linenr, $n) . "\n";
                                }
 
-                               if (($stmts =~ tr/;/;/) == 1) {
+                               if (($stmts =~ tr/;/;/) == 1 &&
+                                   $stmts !~ /^\s*(if|while|for|switch)\b/) {
                                        WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
                                             "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
                                }
index 18ba881c34159a8bcdc3b8b582bd3f0617f90e8a..4f8248d5a11f2e74712b77d4c3521870652dcddd 100755 (executable)
@@ -89,7 +89,7 @@ echo $code >> $T.s
 disas $T
 cat $T.dis >> $T.aa
 
-faultline=`cat $T.dis | head -1 | cut -d":" -f2`
+faultline=`cat $T.dis | head -1 | cut -d":" -f2-`
 faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
 
 cat $T.oo | sed -e "s/\($faultline\)/\*\1     <-- trapping instruction/g"
index 9b0c0b8b4ab4cd483158cfb606aaba038fbbabb5..8fd107a3fac49e32a0879549e88546d7f7f594dd 100755 (executable)
@@ -1786,6 +1786,7 @@ sub dump_function($$) {
     $prototype =~ s/__init +//;
     $prototype =~ s/__init_or_module +//;
     $prototype =~ s/__must_check +//;
+    $prototype =~ s/__weak +//;
     $prototype =~ s/^#\s*define\s+//; #ak added
     $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
 
index 83554ee8a587fbf27bdc7095fa8a600b82aada57..0cc99a3ea42d65c81188c302626681fae6044473 100644 (file)
@@ -279,12 +279,46 @@ static int yama_ptrace_access_check(struct task_struct *child,
        }
 
        if (rc) {
-               char name[sizeof(current->comm)];
                printk_ratelimited(KERN_NOTICE
                        "ptrace of pid %d was attempted by: %s (pid %d)\n",
-                       child->pid,
-                       get_task_comm(name, current),
-                       current->pid);
+                       child->pid, current->comm, current->pid);
+       }
+
+       return rc;
+}
+
+/**
+ * yama_ptrace_traceme - validate PTRACE_TRACEME calls
+ * @parent: task that will become the ptracer of the current task
+ *
+ * Returns 0 if following the ptrace is allowed, -ve on error.
+ */
+static int yama_ptrace_traceme(struct task_struct *parent)
+{
+       int rc;
+
+       /* If standard caps disallows it, so does Yama.  We should
+        * only tighten restrictions further.
+        */
+       rc = cap_ptrace_traceme(parent);
+       if (rc)
+               return rc;
+
+       /* Only disallow PTRACE_TRACEME on more aggressive settings. */
+       switch (ptrace_scope) {
+       case YAMA_SCOPE_CAPABILITY:
+               if (!ns_capable(task_user_ns(parent), CAP_SYS_PTRACE))
+                       rc = -EPERM;
+               break;
+       case YAMA_SCOPE_NO_ATTACH:
+               rc = -EPERM;
+               break;
+       }
+
+       if (rc) {
+               printk_ratelimited(KERN_NOTICE
+                       "ptraceme of pid %d was attempted by: %s (pid %d)\n",
+                       current->pid, parent->comm, parent->pid);
        }
 
        return rc;
@@ -294,6 +328,7 @@ static struct security_operations yama_ops = {
        .name =                 "yama",
 
        .ptrace_access_check =  yama_ptrace_access_check,
+       .ptrace_traceme =       yama_ptrace_traceme,
        .task_prctl =           yama_task_prctl,
        .task_free =            yama_task_free,
 };
index 0d7b25e816437064775a1f81ab8753a0f619ccab..4e1fda75c1c9fbc335b6b45fd34871e8ce0a1898 100644 (file)
@@ -106,7 +106,7 @@ static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = {
        .prepare                = pxa2xx_ac97_pcm_prepare,
 };
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 
 static int pxa2xx_ac97_do_suspend(struct snd_card *card)
 {
@@ -243,7 +243,7 @@ static struct platform_driver pxa2xx_ac97_driver = {
        .driver         = {
                .name   = "pxa2xx-ac97",
                .owner  = THIS_MODULE,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
                .pm     = &pxa2xx_ac97_pm_ops,
 #endif
        },
index eb4ceb71123e1aa91f9063fa57653befc5a7ef09..277ebce23a452be6cb027590eb997c278971eba8 100644 (file)
@@ -452,6 +452,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
        dac->regs = ioremap(regs->start, resource_size(regs));
        if (!dac->regs) {
                dev_dbg(&pdev->dev, "could not remap register memory\n");
+               retval = -ENOMEM;
                goto out_free_card;
        }
 
@@ -534,7 +535,7 @@ out_put_pclk:
        return retval;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int atmel_abdac_suspend(struct device *pdev)
 {
        struct snd_card *card = dev_get_drvdata(pdev);
index bf47025bdf45776ce020e738f04af62752ea025c..9052aff37f6460fcdaba020f0b44d85484243c96 100644 (file)
@@ -278,14 +278,9 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
        if (retval < 0)
                return retval;
        /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
-       if (cpu_is_at32ap7000()) {
-               if (retval < 0)
-                       return retval;
-               /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
-               if (retval == 1)
-                       if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
-                               dw_dma_cyclic_free(chip->dma.rx_chan);
-       }
+       if (cpu_is_at32ap7000() && retval == 1)
+               if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
+                       dw_dma_cyclic_free(chip->dma.rx_chan);
 
        /* Set restrictions to params. */
        mutex_lock(&opened_mutex);
@@ -980,6 +975,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
 
        if (!chip->regs) {
                dev_dbg(&pdev->dev, "could not remap register memory\n");
+               retval = -ENOMEM;
                goto err_ioremap;
        }
 
@@ -1134,7 +1130,7 @@ err_snd_card_new:
        return retval;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int atmel_ac97c_suspend(struct device *pdev)
 {
        struct snd_card *card = dev_get_drvdata(pdev);
index 4e7ec2b498738b6e2ebca47511be93b590af2aa8..d0f00356fc115a32db23bc8475f08a6aad178c47 100644 (file)
@@ -101,7 +101,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
                if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
                                                 chunk, &tmpb) < 0) {
                        if (!sgbuf->pages)
-                               return NULL;
+                               goto _failed;
                        if (!res_size)
                                goto _failed;
                        size = sgbuf->pages * PAGE_SIZE;
index 1128b35b2b05f47fc2c5783a16a10e9e26b9de29..5a34355e78e8f83295496e1feb836a99f7ff7b44 100644 (file)
@@ -1176,7 +1176,7 @@ static int __devexit loopback_remove(struct platform_device *devptr)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int loopback_suspend(struct device *pdev)
 {
        struct snd_card *card = dev_get_drvdata(pdev);
index f7d3bfc6bca83ed296a59fb059cd79ea364c6879..54bb6644a598a8177e3fbec4220df2966abd6131 100644 (file)
@@ -1064,7 +1064,7 @@ static int __devexit snd_dummy_remove(struct platform_device *devptr)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_dummy_suspend(struct device *pdev)
 {
        struct snd_card *card = dev_get_drvdata(pdev);
index 6ca59fc6dcb9c0faf3e5fe07890fd237568a5d79..ef171295f6d46b3684667dfac434196f5a9ccd3f 100644 (file)
@@ -199,7 +199,7 @@ static void pcsp_stop_beep(struct snd_pcsp *chip)
        pcspkr_stop_sound();
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int pcsp_suspend(struct device *dev)
 {
        struct snd_pcsp *chip = dev_get_drvdata(dev);
@@ -212,7 +212,7 @@ static SIMPLE_DEV_PM_OPS(pcsp_pm, pcsp_suspend, NULL);
 #define PCSP_PM_OPS    &pcsp_pm
 #else
 #define PCSP_PM_OPS    NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static void pcsp_shutdown(struct platform_device *dev)
 {
index 2d67c78c9f4bc16e01bf7d869d2163f8122f5616..f7cdaf51512d05d26ca93baf8ce2627375a8af43 100644 (file)
@@ -233,7 +233,7 @@ static int __devinit snd_card_als100_probe(int dev,
                        irq[dev], dma8[dev], dma16[dev]);
        }
 
-       if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
+       if ((error = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) {
                snd_card_free(card);
                return error;
        }
index 733b014ec7d1637a50954b46ff64b6bd662241e3..b2b3c014221afd4d6b2079c6a3627f64fcfe9480 100644 (file)
@@ -575,13 +575,15 @@ static int jazz16_audio_set_speed(int dev, int speed)
        if (speed > 0)
        {
                int tmp;
-               int s = speed * devc->channels;
+               int s;
 
                if (speed < 5000)
                        speed = 5000;
                if (speed > 44100)
                        speed = 44100;
 
+               s = speed * devc->channels;
+
                devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
 
                tmp = 256 - devc->tconst;
index f75f5ffdfdfb60724db8a90dbac5ca05447f3816..a71d1c14a0f6b9efa06bc91d2970bb304ebaa872 100644 (file)
@@ -94,7 +94,7 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
 
        if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
                       codec_index != CS46XX_SECONDARY_CODEC_INDEX))
-               return -EINVAL;
+               return 0xffff;
 
        chip->active_ctrl(chip, 1);
 
index 8e40262d4117cf923c9972711177ab5b8b445dcd..2f6e9c762d3fd184dd995b17a9485faf050dffeb 100644 (file)
@@ -1725,8 +1725,10 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
        atc_connect_resources(atc);
 
        atc->timer = ct_timer_new(atc);
-       if (!atc->timer)
+       if (!atc->timer) {
+               err = -ENOMEM;
                goto error1;
+       }
 
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops);
        if (err < 0)
index 4f502a2bdc3c51759ef26a4c4f80c858cc6192f9..0a436626182b9cc358def5a31f7a7daabf43c484 100644 (file)
@@ -326,7 +326,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
        for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
                unsigned long ofs = idx << PAGE_SHIFT;
                dma_addr_t addr;
-               addr = snd_pcm_sgbuf_get_addr(substream, ofs);
+               if (ofs >= runtime->dma_bytes)
+                       addr = emu->silent_page.addr;
+               else
+                       addr = snd_pcm_sgbuf_get_addr(substream, ofs);
                if (! is_valid_page(emu, addr)) {
                        printk(KERN_ERR "emu: failure page = %d\n", idx);
                        mutex_unlock(&hdr->block_mutex);
index 647218d69f6890862b5fcfd690dc9e09d29bc3ea..4f7d2dfcef7b16357ead4185b7b62e3463d5f1a5 100644 (file)
@@ -332,13 +332,12 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
        if (cfg->dig_outs)
                snd_printd("   dig-out=0x%x/0x%x\n",
                           cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
-       snd_printd("   inputs:");
+       snd_printd("   inputs:\n");
        for (i = 0; i < cfg->num_inputs; i++) {
-               snd_printd(" %s=0x%x",
+               snd_printd("     %s=0x%x\n",
                            hda_get_autocfg_input_label(codec, cfg, i),
                            cfg->inputs[i].pin);
        }
-       snd_printd("\n");
        if (cfg->dig_in_pin)
                snd_printd("   dig-in=0x%x\n", cfg->dig_in_pin);
 
index 0bc2315b181dad0ec6ed7a33af9e0a0a636c3608..0849aac449f2043fe1df237c48773436b5aefe7d 100644 (file)
@@ -231,16 +231,22 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
 }
 EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
 
+static bool ctl_has_mute(struct snd_kcontrol *kcontrol)
+{
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+       return query_amp_caps(codec, get_amp_nid(kcontrol),
+                             get_amp_direction(kcontrol)) & AC_AMPCAP_MUTE;
+}
+
 /* get/put callbacks for beep mute mixer switches */
 int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
                                      struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct hda_beep *beep = codec->beep;
-       if (beep) {
+       if (beep && (!beep->enabled || !ctl_has_mute(kcontrol))) {
                ucontrol->value.integer.value[0] =
-                       ucontrol->value.integer.value[1] =
-                       beep->enabled;
+                       ucontrol->value.integer.value[1] = beep->enabled;
                return 0;
        }
        return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
@@ -252,9 +258,20 @@ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct hda_beep *beep = codec->beep;
-       if (beep)
-               snd_hda_enable_beep_device(codec,
-                                          *ucontrol->value.integer.value);
+       if (beep) {
+               u8 chs = get_amp_channels(kcontrol);
+               int enable = 0;
+               long *valp = ucontrol->value.integer.value;
+               if (chs & 1) {
+                       enable |= *valp;
+                       valp++;
+               }
+               if (chs & 2)
+                       enable |= *valp;
+               snd_hda_enable_beep_device(codec, enable);
+       }
+       if (!ctl_has_mute(kcontrol))
+               return 0;
        return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
 }
 EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
index 88a9c20eb7a29cbff43745f5a64afefefb52b76e..f560051a949e943e10efb844364d5a978a587fcd 100644 (file)
@@ -1386,6 +1386,44 @@ int snd_hda_codec_configure(struct hda_codec *codec)
 }
 EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
 
+/* update the stream-id if changed */
+static void update_pcm_stream_id(struct hda_codec *codec,
+                                struct hda_cvt_setup *p, hda_nid_t nid,
+                                u32 stream_tag, int channel_id)
+{
+       unsigned int oldval, newval;
+
+       if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
+               oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
+               newval = (stream_tag << 4) | channel_id;
+               if (oldval != newval)
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_CHANNEL_STREAMID,
+                                           newval);
+               p->stream_tag = stream_tag;
+               p->channel_id = channel_id;
+       }
+}
+
+/* update the format-id if changed */
+static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p,
+                             hda_nid_t nid, int format)
+{
+       unsigned int oldval;
+
+       if (p->format_id != format) {
+               oldval = snd_hda_codec_read(codec, nid, 0,
+                                           AC_VERB_GET_STREAM_FORMAT, 0);
+               if (oldval != format) {
+                       msleep(1);
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_STREAM_FORMAT,
+                                           format);
+               }
+               p->format_id = format;
+       }
+}
+
 /**
  * snd_hda_codec_setup_stream - set up the codec for streaming
  * @codec: the CODEC to set up
@@ -1400,7 +1438,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
 {
        struct hda_codec *c;
        struct hda_cvt_setup *p;
-       unsigned int oldval, newval;
        int type;
        int i;
 
@@ -1413,29 +1450,13 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
        p = get_hda_cvt_setup(codec, nid);
        if (!p)
                return;
-       /* update the stream-id if changed */
-       if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
-               oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
-               newval = (stream_tag << 4) | channel_id;
-               if (oldval != newval)
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_CHANNEL_STREAMID,
-                                           newval);
-               p->stream_tag = stream_tag;
-               p->channel_id = channel_id;
-       }
-       /* update the format-id if changed */
-       if (p->format_id != format) {
-               oldval = snd_hda_codec_read(codec, nid, 0,
-                                           AC_VERB_GET_STREAM_FORMAT, 0);
-               if (oldval != format) {
-                       msleep(1);
-                       snd_hda_codec_write(codec, nid, 0,
-                                           AC_VERB_SET_STREAM_FORMAT,
-                                           format);
-               }
-               p->format_id = format;
-       }
+
+       if (codec->pcm_format_first)
+               update_pcm_format(codec, p, nid, format);
+       update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
+       if (!codec->pcm_format_first)
+               update_pcm_format(codec, p, nid, format);
+
        p->active = 1;
        p->dirty = 0;
 
@@ -3497,7 +3518,7 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg
 {
        int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE);
 
-       if (sup < 0)
+       if (sup == -1)
                return false;
        if (sup & power_state)
                return true;
@@ -4433,6 +4454,8 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
         * then there is no need to go through power up here.
         */
        if (codec->power_on) {
+               if (codec->power_transition < 0)
+                       codec->power_transition = 0;
                spin_unlock(&codec->power_lock);
                return;
        }
index c422d330ca54fe018379e5b14b24dcd03a4e208e..7fbc1bcaf1a9593b6e0ec71b8b5ac2bb5262e336 100644 (file)
@@ -861,6 +861,7 @@ struct hda_codec {
        unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
        unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
        unsigned int no_jack_detect:1;  /* Machine has no jack-detection */
+       unsigned int pcm_format_first:1; /* PCM format must be set first */
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        unsigned int power_on :1;       /* current (global) power-state */
        int power_transition;   /* power-state in transition */
index c8aced182fd15738cf165505d532e24e89bcd906..60882c62f18006a3b2339d354b58550fdcd30718 100644 (file)
@@ -151,6 +151,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{Intel, CPT},"
                         "{Intel, PPT},"
                         "{Intel, LPT},"
+                        "{Intel, LPT_LP},"
                         "{Intel, HPT},"
                         "{Intel, PBG},"
                         "{Intel, SCH},"
@@ -3270,6 +3271,14 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        { PCI_DEVICE(0x8086, 0x8c20),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
          AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+       /* Lynx Point-LP */
+       { PCI_DEVICE(0x8086, 0x9c20),
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
+         AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+       /* Lynx Point-LP */
+       { PCI_DEVICE(0x8086, 0x9c21),
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
+         AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
        /* Haswell */
        { PCI_DEVICE(0x8086, 0x0c0c),
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
index 7e46258fc7002e24eeb1159e49b05d157a534995..6894ec66258c5988771b2518071e6e9a603e14f2 100644 (file)
@@ -412,7 +412,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
        if (digi1 & AC_DIG1_EMPHASIS)
                snd_iprintf(buffer, " Preemphasis");
        if (digi1 & AC_DIG1_COPYRIGHT)
-               snd_iprintf(buffer, " Copyright");
+               snd_iprintf(buffer, " Non-Copyright");
        if (digi1 & AC_DIG1_NONAUDIO)
                snd_iprintf(buffer, " Non-Audio");
        if (digi1 & AC_DIG1_PROFESSIONAL)
index d0d3540e39e7746b1c42074257fe8194b928e09b..49750a96d649b5f842412c8a94c116f65f1dcf52 100644 (file)
@@ -246,7 +246,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
                                            AC_VERB_SET_AMP_GAIN_MUTE,
                                            AMP_OUT_UNMUTE);
        }
-       if (dac)
+       if (dac && (get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
                snd_hda_codec_write(codec, dac, 0,
                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
 }
@@ -261,7 +261,7 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
                                            AC_VERB_SET_AMP_GAIN_MUTE,
                                            AMP_IN_UNMUTE(0));
        }
-       if (adc)
+       if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP))
                snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
                                    AMP_IN_UNMUTE(0));
 }
@@ -275,6 +275,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
        int type = dir ? HDA_INPUT : HDA_OUTPUT;
        struct snd_kcontrol_new knew =
                HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
+       if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) {
+               snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid);
+               return 0;
+       }
        sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
        return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
 }
@@ -286,6 +290,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
        int type = dir ? HDA_INPUT : HDA_OUTPUT;
        struct snd_kcontrol_new knew =
                HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
+       if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) {
+               snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid);
+               return 0;
+       }
        sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
        return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
 }
@@ -464,50 +472,17 @@ exit:
 }
 
 /*
- * PCM stuffs
+ * PCM callbacks
  */
-static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid,
-                                u32 stream_tag,
-                                int channel_id, int format)
+static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo,
+                                   struct hda_codec *codec,
+                                   struct snd_pcm_substream *substream)
 {
-       unsigned int oldval, newval;
-
-       if (!nid)
-               return;
-
-       snd_printdd("ca0132_setup_stream: "
-               "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
-               nid, stream_tag, channel_id, format);
-
-       /* update the format-id if changed */
-       oldval = snd_hda_codec_read(codec, nid, 0,
-                                   AC_VERB_GET_STREAM_FORMAT,
-                                   0);
-       if (oldval != format) {
-               msleep(20);
-               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_STREAM_FORMAT,
-                                   format);
-       }
-
-       oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
-       newval = (stream_tag << 4) | channel_id;
-       if (oldval != newval) {
-               snd_hda_codec_write(codec, nid, 0,
-                                   AC_VERB_SET_CHANNEL_STREAMID,
-                                   newval);
-       }
-}
-
-static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
-{
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
+       struct ca0132_spec *spec = codec->spec;
+       return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
+                                            hinfo);
 }
 
-/*
- * PCM callbacks
- */
 static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
                        struct hda_codec *codec,
                        unsigned int stream_tag,
@@ -515,10 +490,8 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
                        struct snd_pcm_substream *substream)
 {
        struct ca0132_spec *spec = codec->spec;
-
-       ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format);
-
-       return 0;
+       return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
+                                               stream_tag, format, substream);
 }
 
 static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
@@ -526,92 +499,45 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
                        struct snd_pcm_substream *substream)
 {
        struct ca0132_spec *spec = codec->spec;
-
-       ca0132_cleanup_stream(codec, spec->dacs[0]);
-
-       return 0;
+       return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
 }
 
 /*
  * Digital out
  */
-static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
-                       struct hda_codec *codec,
-                       unsigned int stream_tag,
-                       unsigned int format,
-                       struct snd_pcm_substream *substream)
+static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+                                       struct hda_codec *codec,
+                                       struct snd_pcm_substream *substream)
 {
        struct ca0132_spec *spec = codec->spec;
-
-       ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format);
-
-       return 0;
+       return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 }
 
-static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
-                       struct hda_codec *codec,
-                       struct snd_pcm_substream *substream)
-{
-       struct ca0132_spec *spec = codec->spec;
-
-       ca0132_cleanup_stream(codec, spec->dig_out);
-
-       return 0;
-}
-
-/*
- * Analog capture
- */
-static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
                        struct hda_codec *codec,
                        unsigned int stream_tag,
                        unsigned int format,
                        struct snd_pcm_substream *substream)
 {
        struct ca0132_spec *spec = codec->spec;
-
-       ca0132_setup_stream(codec, spec->adcs[substream->number],
-                            stream_tag, 0, format);
-
-       return 0;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+                                            stream_tag, format, substream);
 }
 
-static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
                        struct hda_codec *codec,
                        struct snd_pcm_substream *substream)
 {
        struct ca0132_spec *spec = codec->spec;
-
-       ca0132_cleanup_stream(codec, spec->adcs[substream->number]);
-
-       return 0;
+       return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
 }
 
-/*
- * Digital capture
- */
-static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
-                       struct hda_codec *codec,
-                       unsigned int stream_tag,
-                       unsigned int format,
-                       struct snd_pcm_substream *substream)
+static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+                                        struct hda_codec *codec,
+                                        struct snd_pcm_substream *substream)
 {
        struct ca0132_spec *spec = codec->spec;
-
-       ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format);
-
-       return 0;
-}
-
-static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
-                       struct hda_codec *codec,
-                       struct snd_pcm_substream *substream)
-{
-       struct ca0132_spec *spec = codec->spec;
-
-       ca0132_cleanup_stream(codec, spec->dig_in);
-
-       return 0;
+       return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
 /*
@@ -621,6 +547,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = {
        .channels_min = 2,
        .channels_max = 2,
        .ops = {
+               .open = ca0132_playback_pcm_open,
                .prepare = ca0132_playback_pcm_prepare,
                .cleanup = ca0132_playback_pcm_cleanup
        },
@@ -630,10 +557,6 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = {
        .substreams = 1,
        .channels_min = 2,
        .channels_max = 2,
-       .ops = {
-               .prepare = ca0132_capture_pcm_prepare,
-               .cleanup = ca0132_capture_pcm_cleanup
-       },
 };
 
 static struct hda_pcm_stream ca0132_pcm_digital_playback = {
@@ -641,6 +564,8 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = {
        .channels_min = 2,
        .channels_max = 2,
        .ops = {
+               .open = ca0132_dig_playback_pcm_open,
+               .close = ca0132_dig_playback_pcm_close,
                .prepare = ca0132_dig_playback_pcm_prepare,
                .cleanup = ca0132_dig_playback_pcm_cleanup
        },
@@ -650,10 +575,6 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = {
        .substreams = 1,
        .channels_min = 2,
        .channels_max = 2,
-       .ops = {
-               .prepare = ca0132_dig_capture_pcm_prepare,
-               .cleanup = ca0132_dig_capture_pcm_cleanup
-       },
 };
 
 static int ca0132_build_pcms(struct hda_codec *codec)
@@ -928,18 +849,16 @@ static int ca0132_build_controls(struct hda_codec *codec)
                                                    spec->dig_out);
                if (err < 0)
                        return err;
-               err = add_out_volume(codec, spec->dig_out, "IEC958");
+               err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
                if (err < 0)
                        return err;
+               /* spec->multiout.share_spdif = 1; */
        }
 
        if (spec->dig_in) {
                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
                if (err < 0)
                        return err;
-               err = add_in_volume(codec, spec->dig_in, "IEC958");
-               if (err < 0)
-                       return err;
        }
        return 0;
 }
@@ -961,6 +880,9 @@ static void ca0132_config(struct hda_codec *codec)
        struct ca0132_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
 
+       codec->pcm_format_first = 1;
+       codec->no_sticky_stream = 1;
+
        /* line-outs */
        cfg->line_outs = 1;
        cfg->line_out_pins[0] = 0x0b; /* front */
@@ -988,14 +910,24 @@ static void ca0132_config(struct hda_codec *codec)
 
        /* Mic-in */
        spec->input_pins[0] = 0x12;
-       spec->input_labels[0] = "Mic-In";
+       spec->input_labels[0] = "Mic";
        spec->adcs[0] = 0x07;
 
        /* Line-In */
        spec->input_pins[1] = 0x11;
-       spec->input_labels[1] = "Line-In";
+       spec->input_labels[1] = "Line";
        spec->adcs[1] = 0x08;
        spec->num_inputs = 2;
+
+       /* SPDIF I/O */
+       spec->dig_out = 0x05;
+       spec->multiout.dig_out_nid = spec->dig_out;
+       cfg->dig_out_pins[0] = 0x0c;
+       cfg->dig_outs = 1;
+       cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF;
+       spec->dig_in = 0x09;
+       cfg->dig_in_pin = 0x0e;
+       cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
 }
 
 static void ca0132_init_chip(struct hda_codec *codec)
index 14361184ae1e0e17ac2483dcac3c525289369f1f..5e22a8f43d2eebc288083142b355feffb61ffedb 100644 (file)
@@ -2967,12 +2967,10 @@ static const char * const cxt5066_models[CXT5066_MODELS] = {
 };
 
 static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
        SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
        SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
-       SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
@@ -2988,14 +2986,10 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
-       SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO),
-       SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
        SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
-       SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
-       SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
        {}
 };
 
index 69b928449789e22afcaef39a67dea3323bc5e5e7..8f23374fa6427198735f91b987656986052a8773 100644 (file)
@@ -877,8 +877,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
        struct hdmi_eld *eld;
        struct hdmi_spec_per_cvt *per_cvt = NULL;
 
-       hinfo->nid = 0; /* clear the leftover value */
-
        /* Validate hinfo */
        pin_idx = hinfo_to_pin_index(spec, hinfo);
        if (snd_BUG_ON(pin_idx < 0))
@@ -1163,6 +1161,14 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
        return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
 }
 
+static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+                                            struct hda_codec *codec,
+                                            struct snd_pcm_substream *substream)
+{
+       snd_hda_codec_cleanup_stream(codec, hinfo->nid);
+       return 0;
+}
+
 static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
                          struct hda_codec *codec,
                          struct snd_pcm_substream *substream)
@@ -1202,6 +1208,7 @@ static const struct hda_pcm_ops generic_ops = {
        .open = hdmi_pcm_open,
        .close = hdmi_pcm_close,
        .prepare = generic_hdmi_playback_pcm_prepare,
+       .cleanup = generic_hdmi_playback_pcm_cleanup,
 };
 
 static int generic_hdmi_build_pcms(struct hda_codec *codec)
@@ -1220,7 +1227,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
                pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
                pstr->substreams = 1;
                pstr->ops = generic_ops;
-               pstr->nid = 1; /* FIXME: just for avoiding a debug WARNING */
                /* other pstr fields are set in open */
        }
 
index 344b221d2102ffd9d4568961d7a0d2b5f8490e2a..4f81dd44c837e1de6b1de327f457bcb0fcc8f16f 100644 (file)
@@ -6099,6 +6099,8 @@ static const struct alc_fixup alc269_fixups[] = {
        [ALC269_FIXUP_PCM_44K] = {
                .type = ALC_FIXUP_FUNC,
                .v.func = alc269_fixup_pcm_44k,
+               .chained = true,
+               .chain_id = ALC269_FIXUP_QUANTA_MUTE
        },
        [ALC269_FIXUP_STEREO_DMIC] = {
                .type = ALC_FIXUP_FUNC,
@@ -6206,9 +6208,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
-       SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
-       SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
+       SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
 
 #if 0
index 94040ccf8e8fbd954833a6302ed37ab60a34f1ed..ea5775a1a7db292e25dd7956b8ac502d1a9db33e 100644 (file)
@@ -4272,7 +4272,8 @@ static int stac92xx_init(struct hda_codec *codec)
        unsigned int gpio;
        int i;
 
-       snd_hda_sequence_write(codec, spec->init);
+       if (spec->init)
+               snd_hda_sequence_write(codec, spec->init);
 
        /* power down adcs initially */
        if (spec->powerdown_adcs)
@@ -5748,7 +5749,6 @@ again:
                /* fallthru */
        case 0x111d76b4: /* 6 Port without Analog Mixer */
        case 0x111d76b5:
-               spec->init = stac92hd71bxx_core_init;
                codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
                spec->num_dmics = stac92xx_connected_ports(codec,
                                        stac92hd71bxx_dmic_nids,
@@ -5773,7 +5773,6 @@ again:
                        spec->stream_delay = 40; /* 40 milliseconds */
 
                /* disable VSW */
-               spec->init = stac92hd71bxx_core_init;
                unmute_init++;
                snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
                snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
@@ -5788,7 +5787,6 @@ again:
 
                /* fallthru */
        default:
-               spec->init = stac92hd71bxx_core_init;
                codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
                spec->num_dmics = stac92xx_connected_ports(codec,
                                        stac92hd71bxx_dmic_nids,
@@ -5796,6 +5794,9 @@ again:
                break;
        }
 
+       if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
+               spec->init = stac92hd71bxx_core_init;
+
        if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
                snd_hda_sequence_write_cache(codec, unmute_init);
 
index 80d90cb42853bd50abfac7349361142e71185a7c..43077177691588ab03590cd0576369c54b55d266 100644 (file)
@@ -1752,6 +1752,14 @@ static int via_suspend(struct hda_codec *codec)
 {
        struct via_spec *spec = codec->spec;
        vt1708_stop_hp_work(spec);
+
+       if (spec->codec_type == VT1802) {
+               /* Fix pop noise on headphones */
+               int i;
+               for (i = 0; i < spec->autocfg.hp_outs; i++)
+                       snd_hda_set_pin_ctl(codec, spec->autocfg.hp_pins[i], 0);
+       }
+
        return 0;
 }
 #endif
index d1ab43706735fb42d12cc8514b48b9add557b5c2..5579b08bb35b6337c646b6d2cb6be5215f0d01d9 100644 (file)
@@ -851,6 +851,8 @@ static int __devinit lx_pcm_create(struct lx6464es *chip)
        /* hardcoded device name & channel count */
        err = snd_pcm_new(chip->card, (char *)card_name, 0,
                          1, 1, &pcm);
+       if (err < 0)
+               return err;
 
        pcm->private_data = chip;
 
index b8ac8710f47fb200d602bc2917598a153cad6884..b12308b5ba2a01170b56b5cd7b69a9d1d93aa6e3 100644 (file)
@@ -6585,7 +6585,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
                snd_printk(KERN_ERR "HDSPM: "
                                "unable to kmalloc Mixer memory of %d Bytes\n",
                                (int)sizeof(struct hdspm_mixer));
-               return err;
+               return -ENOMEM;
        }
 
        hdspm->port_names_in = NULL;
index 512434efcc31136f1570ab5e17429523a354f187..805ab6e9a78fbb0879c111140deda257c083d30c 100644 (file)
@@ -1377,8 +1377,9 @@ static int __devinit sis_chip_create(struct snd_card *card,
        if (rc)
                goto error_out_cleanup;
 
-       if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME,
-                       sis)) {
+       rc = request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME,
+                        sis);
+       if (rc) {
                dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq);
                goto error_out_cleanup;
        }
index f5ceb6f282decab0e89e4b8c5637c0520efde7d9..210cafe0489020ea970ac2724a68797a5be23a6e 100644 (file)
@@ -143,7 +143,7 @@ static int __devexit snd_pmac_remove(struct platform_device *devptr)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_pmac_driver_suspend(struct device *dev)
 {
        struct snd_card *card = dev_get_drvdata(dev);
index 1aa52eff526a1d97094caa525681b25ca4c8d4e8..9b18b5243a56a74bc704fc3e2c79901ac8ec0079 100644 (file)
@@ -1040,6 +1040,7 @@ static int __devinit snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
                                   GFP_KERNEL);
        if (!the_card.null_buffer_start_vaddr) {
                pr_info("%s: nullbuffer alloc failed\n", __func__);
+               ret = -ENOMEM;
                goto clean_preallocate;
        }
        pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__,
index 318c5ba5360f6dfb3e9184aa9f169ad0f23aa3a4..dfb744381c42cb2288b7bb7325fdb04b04338b82 100644 (file)
@@ -413,7 +413,14 @@ EXPORT_SYMBOL(sport_create);
 
 void sport_delete(struct sport_device *sport)
 {
+       if (sport->tx_desc)
+               dma_free_coherent(NULL, sport->tx_desc_size,
+                               sport->tx_desc, 0);
+       if (sport->rx_desc)
+               dma_free_coherent(NULL, sport->rx_desc_size,
+                               sport->rx_desc, 0);
        sport_free_resource(sport);
+       kfree(sport);
 }
 EXPORT_SYMBOL(sport_delete);
 
index 3c795921c5f6b840f6654d53907ed44e18435841..23b40186f9b8f48df8be77a29269eddbad88f792 100644 (file)
@@ -2406,6 +2406,10 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
 
        /* Setup AB8500 according to board-settings */
        pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent);
+
+       /* Inform SoC Core that we have our own I/O arrangements. */
+       codec->control_data = (void *)true;
+
        status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
        if (status < 0) {
                pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
index 8c39dddd7d0063d90adcf587c5e6dc19c37f73ad..11b1b714b8b5e106ad7784258ca4caa4a4939e9e 100644 (file)
@@ -186,6 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 
        printk(KERN_INFO "AD1980 SoC Audio Codec\n");
 
+       codec->control_data = codec;    /* we don't use regmap! */
        ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
        if (ret < 0) {
                printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
index 6276e352125f0a22e156c388c08f53d229fd543e..8f726c063f42badc9c598de4af670fb78f8937e1 100644 (file)
@@ -581,6 +581,8 @@ static int mc13783_probe(struct snd_soc_codec *codec)
 {
        struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
 
+       codec->control_data = priv->mc13xxx;
+
        mc13xxx_lock(priv->mc13xxx);
 
        /* these are the reset values */
index 8af6a5245b18acbfefe5fa1ca8ecbec8fd9068be..df2f99d1d428940424d419378ce6cf9d82a937bf 100644 (file)
@@ -239,6 +239,7 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
        {"Headphone Mux", "DAC", "DAC"},        /* dac --> hp_mux */
        {"LO", NULL, "DAC"},                    /* dac --> line_out */
 
+       {"LINE_IN", NULL, "VAG_POWER"},
        {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
        {"HP", NULL, "Headphone Mux"},          /* hp_mux --> hp */
 
@@ -1357,8 +1358,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
        if (ret)
                goto err;
 
-       snd_soc_dapm_new_widgets(&codec->dapm);
-
        return 0;
 
 err:
index 982e437799a8e62aa8085a9d5b509fa4d8f8a387..33c0f3d39c87ea0ea6c99ea1752f30e663914766 100644 (file)
@@ -340,6 +340,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
 
        printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
 
+       codec->control_data = codec;    /* we don't use regmap! */
        ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
        if (ret < 0)
                goto codec_err;
index 6537f16d383e12f459b9f39950c7b28b46d8d7da..e33d327396ad4fe7a0cb72ffd6ddc6d6caabf3f2 100644 (file)
@@ -128,13 +128,9 @@ SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
 
 ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
-ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE),
-ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE),
 
 SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
                   ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
-SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5,
-                  ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA),
 
 ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
@@ -236,8 +232,6 @@ ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
 
 ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE);
 
 ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
@@ -349,10 +343,6 @@ SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
                 NULL, 0),
 SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
                 NULL, 0),
-SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0,
-                NULL, 0),
-SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0,
-                NULL, 0),
 
 SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
                 NULL, 0),
@@ -466,8 +456,6 @@ ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"),
 
 ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
 ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
-ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"),
-ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"),
 
 ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
 ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
@@ -553,8 +541,6 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
        { name, "EQ4", "EQ4" }, \
        { name, "DRC1L", "DRC1L" }, \
        { name, "DRC1R", "DRC1R" }, \
-       { name, "DRC2L", "DRC2L" }, \
-       { name, "DRC2R", "DRC2R" }, \
        { name, "LHPF1", "LHPF1" }, \
        { name, "LHPF2", "LHPF2" }, \
        { name, "LHPF3", "LHPF3" }, \
@@ -639,6 +625,15 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
        { "AIF2 Capture", NULL, "SYSCLK" },
        { "AIF3 Capture", NULL, "SYSCLK" },
 
+       { "IN1L PGA", NULL, "IN1L" },
+       { "IN1R PGA", NULL, "IN1R" },
+
+       { "IN2L PGA", NULL, "IN2L" },
+       { "IN2R PGA", NULL, "IN2R" },
+
+       { "IN3L PGA", NULL, "IN3L" },
+       { "IN3R PGA", NULL, "IN3R" },
+
        ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
        ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
        ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
@@ -675,8 +670,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
 
        ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
        ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
-       ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"),
-       ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"),
 
        ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
        ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
index 8033f70651897215613275901fd432eea6cdb673..01ebbcc5c6a4a55f31b6448c6ede5e92a1f3f2e8 100644 (file)
@@ -681,6 +681,18 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        { "AIF2 Capture", NULL, "SYSCLK" },
        { "AIF3 Capture", NULL, "SYSCLK" },
 
+       { "IN1L PGA", NULL, "IN1L" },
+       { "IN1R PGA", NULL, "IN1R" },
+
+       { "IN2L PGA", NULL, "IN2L" },
+       { "IN2R PGA", NULL, "IN2R" },
+
+       { "IN3L PGA", NULL, "IN3L" },
+       { "IN3R PGA", NULL, "IN3R" },
+
+       { "IN4L PGA", NULL, "IN4L" },
+       { "IN4R PGA", NULL, "IN4R" },
+
        ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
        ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
        ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
index eaf65863ec2190c8e705eaa3d4b5a95ff6378d30..ce6720073798ddd352df483182b1653b121ec096 100644 (file)
@@ -2501,6 +2501,9 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
                /* VMID 2*250k */
                snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
                                    WM8962_VMID_SEL_MASK, 0x100);
+
+               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
+                       msleep(100);
                break;
 
        case SND_SOC_BIAS_OFF:
@@ -3730,21 +3733,6 @@ static int wm8962_runtime_resume(struct device *dev)
 
        regcache_sync(wm8962->regmap);
 
-       regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
-                          WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
-                          WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
-
-       /* Bias enable at 2*50k for ramp */
-       regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
-                          WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA,
-                          WM8962_BIAS_ENA | 0x180);
-
-       msleep(5);
-
-       /* VMID back to 2x250k for standby */
-       regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
-                          WM8962_VMID_SEL_MASK, 0x100);
-
        return 0;
 }
 
index bb62f4b3d563d434143f52a6ba70f614a8ed61fd..6c9eeca85b952278f375ff9bb21faee1e33ec06a 100644 (file)
@@ -2649,7 +2649,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       bclk_rate = params_rate(params) * 2;
+       bclk_rate = params_rate(params) * 4;
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
                bclk_rate *= 16;
@@ -3253,10 +3253,13 @@ static void wm8994_mic_work(struct work_struct *work)
        int ret;
        int report;
 
+       pm_runtime_get_sync(dev);
+
        ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, &reg);
        if (ret < 0) {
                dev_err(dev, "Failed to read microphone status: %d\n",
                        ret);
+               pm_runtime_put(dev);
                return;
        }
 
@@ -3299,6 +3302,8 @@ static void wm8994_mic_work(struct work_struct *work)
 
        snd_soc_jack_report(priv->micdet[1].jack, report,
                            SND_JACK_HEADSET | SND_JACK_BTN_0);
+
+       pm_runtime_put(dev);
 }
 
 static irqreturn_t wm8994_mic_irq(int irq, void *data)
@@ -3421,12 +3426,15 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
        int reg;
        bool present;
 
+       pm_runtime_get_sync(codec->dev);
+
        mutex_lock(&wm8994->accdet_lock);
 
        reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
        if (reg < 0) {
                dev_err(codec->dev, "Failed to read jack status: %d\n", reg);
                mutex_unlock(&wm8994->accdet_lock);
+               pm_runtime_put(codec->dev);
                return IRQ_NONE;
        }
 
@@ -3491,6 +3499,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
                                    SND_JACK_MECHANICAL | SND_JACK_HEADSET |
                                    wm8994->btn_mask);
 
+       pm_runtime_put(codec->dev);
        return IRQ_HANDLED;
 }
 
@@ -3602,6 +3611,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
        if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
                return IRQ_HANDLED;
 
+       pm_runtime_get_sync(codec->dev);
+
        /* We may occasionally read a detection without an impedence
         * range being provided - if that happens loop again.
         */
@@ -3612,6 +3623,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
                        dev_err(codec->dev,
                                "Failed to read mic detect status: %d\n",
                                reg);
+                       pm_runtime_put(codec->dev);
                        return IRQ_NONE;
                }
 
@@ -3639,6 +3651,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
                dev_warn(codec->dev, "Accessory detection with no callback\n");
 
 out:
+       pm_runtime_put(codec->dev);
        return IRQ_HANDLED;
 }
 
@@ -4025,6 +4038,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
                break;
        case WM8958:
                if (wm8994->revision < 1) {
+                       snd_soc_dapm_add_routes(dapm, wm8994_intercon,
+                                               ARRAY_SIZE(wm8994_intercon));
                        snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
                                                ARRAY_SIZE(wm8994_revd_intercon));
                        snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
index 099e6ec321256009a99ba90c73fc66283cece2d4..c6d2076a796bd9aecf510636a0339e76abed2dde 100644 (file)
@@ -148,7 +148,7 @@ SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
 
 SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1),
 SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
-SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
+SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0),
 SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
 
 SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
@@ -272,7 +272,7 @@ SOC_DAPM_ENUM("Route", wm9712_enum[9]);
 
 /* Mic select */
 static const struct snd_kcontrol_new wm9712_mic_src_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[7]);
+SOC_DAPM_ENUM("Mic Source Select", wm9712_enum[7]);
 
 /* diff select */
 static const struct snd_kcontrol_new wm9712_diff_sel_controls =
@@ -291,7 +291,9 @@ SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
        &wm9712_capture_selectl_controls),
 SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
        &wm9712_capture_selectr_controls),
-SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0,
+SND_SOC_DAPM_MUX("Left Mic Select Source", SND_SOC_NOPM, 0, 0,
+       &wm9712_mic_src_controls),
+SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0,
        &wm9712_mic_src_controls),
 SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0,
        &wm9712_diff_sel_controls),
@@ -319,6 +321,7 @@ SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0),
 SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0),
 SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0),
 SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0),
+SND_SOC_DAPM_PGA("Differential Mic", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1),
 SND_SOC_DAPM_OUTPUT("MONOOUT"),
 SND_SOC_DAPM_OUTPUT("HPOUTL"),
@@ -379,6 +382,18 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = {
        {"Mic PGA", NULL, "MIC1"},
        {"Mic PGA", NULL, "MIC2"},
 
+       /* microphones */
+       {"Differential Mic", NULL, "MIC1"},
+       {"Differential Mic", NULL, "MIC2"},
+       {"Left Mic Select Source", "Mic 1", "MIC1"},
+       {"Left Mic Select Source", "Mic 2", "MIC2"},
+       {"Left Mic Select Source", "Stereo", "MIC1"},
+       {"Left Mic Select Source", "Differential", "Differential Mic"},
+       {"Right Mic Select Source", "Mic 1", "MIC1"},
+       {"Right Mic Select Source", "Mic 2", "MIC2"},
+       {"Right Mic Select Source", "Stereo", "MIC2"},
+       {"Right Mic Select Source", "Differential", "Differential Mic"},
+
        /* left capture selector */
        {"Left Capture Select", "Mic", "MIC1"},
        {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"},
@@ -619,6 +634,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
 {
        int ret = 0;
 
+       codec->control_data = codec;    /* we don't use regmap! */
        ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
        if (ret < 0) {
                printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
index 3eb19fb71d17209e0bccc071ed3f481471201276..d0b8a3287a8592af98dad706861fcb3b87460bbc 100644 (file)
@@ -1196,6 +1196,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
        if (wm9713 == NULL)
                return -ENOMEM;
        snd_soc_codec_set_drvdata(codec, wm9713);
+       codec->control_data = wm9713;   /* we don't use regmap! */
 
        ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
        if (ret < 0)
index 95441bfc819026071020915d6e4e3c53d2dec593..ce5e5cd254ddc395c6d08e8767228b4a6822668d 100644 (file)
@@ -380,14 +380,20 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
 static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
 {
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (dev->txnumevt)      /* enable FIFO */
+               if (dev->txnumevt) {    /* enable FIFO */
+                       mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+                                                               FIFO_ENABLE);
                        mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
                                                                FIFO_ENABLE);
+               }
                mcasp_start_tx(dev);
        } else {
-               if (dev->rxnumevt)      /* enable FIFO */
+               if (dev->rxnumevt) {    /* enable FIFO */
+                       mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+                                                               FIFO_ENABLE);
                        mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
                                                                FIFO_ENABLE);
+               }
                mcasp_start_rx(dev);
        }
 }
index 28dd76c7cb1c08ac308ca7730d9abfc8b02b0903..81d7728cf67fb2d6f4ce1b4287319a0384f0d2d8 100644 (file)
@@ -380,13 +380,14 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
 static struct snd_soc_dai_driver imx_ssi_dai = {
        .probe = imx_ssi_dai_probe,
        .playback = {
-               .channels_min = 1,
+               /* The SSI does not support monaural audio. */
+               .channels_min = 2,
                .channels_max = 2,
                .rates = SNDRV_PCM_RATE_8000_96000,
                .formats = SNDRV_PCM_FMTBIT_S16_LE,
        },
        .capture = {
-               .channels_min = 1,
+               .channels_min = 2,
                .channels_max = 2,
                .rates = SNDRV_PCM_RATE_8000_96000,
                .formats = SNDRV_PCM_FMTBIT_S16_LE,
index 99a997f19bb9d9f76c5fa7a93af992d7dce6b0eb..b6fa77678d97ec542a4585ff152b689c34370fd4 100644 (file)
@@ -10,7 +10,7 @@ menuconfig SND_MXS_SOC
 if SND_MXS_SOC
 
 config SND_SOC_MXS_SGTL5000
-       tristate "SoC Audio support for i.MX boards with sgtl5000"
+       tristate "SoC Audio support for MXS boards with sgtl5000"
        depends on I2C
        select SND_SOC_SGTL5000
        help
index aba71bfa33b15f0813f48a7a236bb61c5b5968b9..b3030718c2288b9942628c9f087694b0568cbbb3 100644 (file)
@@ -394,9 +394,14 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *cpu_dai)
 {
        struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
+       struct mxs_saif *master_saif;
        u32 scr, stat;
        int ret;
 
+       master_saif = mxs_saif_get_master(saif);
+       if (!master_saif)
+               return -EINVAL;
+
        /* mclk should already be set */
        if (!saif->mclk && saif->mclk_in_use) {
                dev_err(cpu_dai->dev, "set mclk first\n");
@@ -420,6 +425,25 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
+       /* prepare clk in hw_param, enable in trigger */
+       clk_prepare(saif->clk);
+       if (saif != master_saif) {
+               /*
+               * Set an initial clock rate for the saif internal logic to work
+               * properly. This is important when working in EXTMASTER mode
+               * that uses the other saif's BITCLK&LRCLK but it still needs a
+               * basic clock which should be fast enough for the internal
+               * logic.
+               */
+               clk_enable(saif->clk);
+               ret = clk_set_rate(saif->clk, 24000000);
+               clk_disable(saif->clk);
+               if (ret)
+                       return ret;
+
+               clk_prepare(master_saif->clk);
+       }
+
        scr = __raw_readl(saif->base + SAIF_CTRL);
 
        scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
index 34835e8a9160ce16b1d074a1f8495d1124e5eac8..d33c48baaf711054da6e1c3f08f5a2e57d394057 100644 (file)
@@ -745,7 +745,7 @@ int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
 {
        const char *signal, *src;
 
-       if (mcbsp->pdata->mux_signal)
+       if (!mcbsp->pdata->mux_signal)
                return -EINVAL;
 
        switch (mux) {
index 1046083e90a079f594b99ef0f88b72bb7e8e5150..acdd3ef14e08c59821d2ae18f7795c0b590e3df0 100644 (file)
@@ -820,3 +820,4 @@ module_platform_driver(asoc_mcbsp_driver);
 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
 MODULE_DESCRIPTION("OMAP I2S SoC Interface");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:omap-mcbsp");
index 5a649da9122a3e798713999a766885f0f732a5cd..f0feb06615f8ea355711239b4ffbd74516221a3e 100644 (file)
@@ -441,3 +441,4 @@ module_platform_driver(omap_pcm_driver);
 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
 MODULE_DESCRIPTION("OMAP PCM DMA module");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:omap-pcm-audio");
index b7b2a1f9142521d931a94fe65cd5ea9a580869d2..89b064650f1492ffc828367ef34c89cbc82800c7 100644 (file)
@@ -20,7 +20,7 @@
 #include <sound/pcm_params.h>
 
 #include <plat/audio.h>
-#include <plat/dma.h>
+#include <mach/dma.h>
 
 #include "dma.h"
 #include "pcm.h"
index f219b2f7ee682c795bcf12ec2bea9b9855506b6f..c501af6d8dbefac0ce233e30d884f02d491594f7 100644 (file)
@@ -826,7 +826,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
        }
 
        if (!rtd->cpu_dai) {
-               dev_dbg(card->dev, "CPU DAI %s not registered\n",
+               dev_err(card->dev, "CPU DAI %s not registered\n",
                        dai_link->cpu_dai_name);
                return -EPROBE_DEFER;
        }
@@ -857,14 +857,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
                }
 
                if (!rtd->codec_dai) {
-                       dev_dbg(card->dev, "CODEC DAI %s not registered\n",
+                       dev_err(card->dev, "CODEC DAI %s not registered\n",
                                dai_link->codec_dai_name);
                        return -EPROBE_DEFER;
                }
        }
 
        if (!rtd->codec) {
-               dev_dbg(card->dev, "CODEC %s not registered\n",
+               dev_err(card->dev, "CODEC %s not registered\n",
                        dai_link->codec_name);
                return -EPROBE_DEFER;
        }
@@ -888,7 +888,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
                rtd->platform = platform;
        }
        if (!rtd->platform) {
-               dev_dbg(card->dev, "platform %s not registered\n",
+               dev_err(card->dev, "platform %s not registered\n",
                        dai_link->platform_name);
                return -EPROBE_DEFER;
        }
@@ -1096,7 +1096,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
        }
 
        /* If the driver didn't set I/O up try regmap */
-       if (!codec->control_data)
+       if (!codec->write && dev_get_regmap(codec->dev, NULL))
                snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
 
        if (driver->controls)
@@ -1481,6 +1481,8 @@ static int soc_check_aux_dev(struct snd_soc_card *card, int num)
                        return 0;
        }
 
+       dev_err(card->dev, "%s not registered\n", aux_dev->codec_name);
+
        return -EPROBE_DEFER;
 }
 
index 7f8b3b7428bbf12c60f603fff8fbb8d3989fa254..0c172938b82a09a1d38f790cf07d4e2b48515b2f 100644 (file)
@@ -103,7 +103,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
        }
 
        /* Report before the DAPM sync to help users updating micbias status */
-       blocking_notifier_call_chain(&jack->notifier, status, jack);
+       blocking_notifier_call_chain(&jack->notifier, jack->status, jack);
 
        snd_soc_dapm_sync(dapm);
 
index d684df294c0c5c80458b6de591c16965027db14b..e463529b38bbfbfd35cc745bf430f68399bfee91 100644 (file)
@@ -177,7 +177,7 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
        }
 
        alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
-       if (alc5632->gpio_hp_det == -ENODEV)
+       if (alc5632->gpio_hp_det == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
        ret = snd_soc_of_parse_card_name(card, "nvidia,model");
index 0c5bb33d258e1aeda033924e92598caa5c372d41..d4f14e492341f3751446057b68ee8d61f0c9bfbd 100644 (file)
@@ -284,27 +284,27 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
        } else if (np) {
                pdata->gpio_spkr_en = of_get_named_gpio(np,
                                                "nvidia,spkr-en-gpios", 0);
-               if (pdata->gpio_spkr_en == -ENODEV)
+               if (pdata->gpio_spkr_en == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
 
                pdata->gpio_hp_mute = of_get_named_gpio(np,
                                                "nvidia,hp-mute-gpios", 0);
-               if (pdata->gpio_hp_mute == -ENODEV)
+               if (pdata->gpio_hp_mute == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
 
                pdata->gpio_hp_det = of_get_named_gpio(np,
                                                "nvidia,hp-det-gpios", 0);
-               if (pdata->gpio_hp_det == -ENODEV)
+               if (pdata->gpio_hp_det == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
 
                pdata->gpio_int_mic_en = of_get_named_gpio(np,
                                                "nvidia,int-mic-en-gpios", 0);
-               if (pdata->gpio_int_mic_en == -ENODEV)
+               if (pdata->gpio_int_mic_en == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
 
                pdata->gpio_ext_mic_en = of_get_named_gpio(np,
                                                "nvidia,ext-mic-en-gpios", 0);
-               if (pdata->gpio_ext_mic_en == -ENODEV)
+               if (pdata->gpio_ext_mic_en == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
        }
 
index 62ac0285bfaffe367f0c3ddfb36bac52cb6113e2..057e28ef770ecbd9582078acb9db8cd7a83f8e4b 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mfd/dbx500-prcmu.h>
 
 #include <mach/hardware.h>
-#include <mach/board-mop500-msp.h>
+#include <mach/msp.h>
 
 #include <sound/soc.h>
 #include <sound/soc-dai.h>
index ee14d2dac2f53c4e328f622bf6566afbd193c309..5c472f335a64d6e5c11a5ee82e755153312ee40b 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/slab.h>
 
 #include <mach/hardware.h>
-#include <mach/board-mop500-msp.h>
+#include <mach/msp.h>
 
 #include <sound/soc.h>
 
index 7f71b4a0d4bc3b391c0633f8c2d6205d156d1511..2d9136da9865f18548d3ccc23548f286b8a994e4 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <linux/platform_device.h>
 
-#include <mach/board-mop500-msp.h>
+#include <mach/msp.h>
 
 #define MSP_INPUT_FREQ_APB 48000000
 
index 0f647d22cb4ac7bccffe25311011255cf0b33104..c411812026884408afd74f1e580f2e87bbe747fc 100644 (file)
@@ -821,10 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
        if (++ep->use_count != 1)
                return 0;
 
-       /* just to be sure */
-       deactivate_urbs(ep, 0, 1);
-       wait_clear_urbs(ep);
-
        ep->active_mask = 0;
        ep->unlink_mask = 0;
        ep->phase = 0;
index a1298f379428280045bf661f89e5fa59bb0acb48..62ec808ed792503e789ea26eb74837998623915e 100644 (file)
@@ -544,6 +544,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
        subs->last_frame_number = 0;
        runtime->delay = 0;
 
+       /* clear the pending deactivation on the target EPs */
+       deactivate_endpoints(subs);
+
        /* for playback, submit the URBs now; otherwise, the first hwptr_done
         * updates for all URBs would happen at the same time when starting */
        if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
index 77f124fe57ad54d8e45858f4e4429f6b63f42273..35655c3a7b7a438dd806b9d5a5fb8baa7102876a 100644 (file)
@@ -319,6 +319,8 @@ LIB_H += $(ARCH_INCLUDE)
 LIB_H += util/cgroup.h
 LIB_H += $(TRACE_EVENT_DIR)event-parse.h
 LIB_H += util/target.h
+LIB_H += util/rblist.h
+LIB_H += util/intlist.h
 
 LIB_OBJS += $(OUTPUT)util/abspath.o
 LIB_OBJS += $(OUTPUT)util/alias.o
@@ -383,6 +385,8 @@ LIB_OBJS += $(OUTPUT)util/xyarray.o
 LIB_OBJS += $(OUTPUT)util/cpumap.o
 LIB_OBJS += $(OUTPUT)util/cgroup.o
 LIB_OBJS += $(OUTPUT)util/target.o
+LIB_OBJS += $(OUTPUT)util/rblist.o
+LIB_OBJS += $(OUTPUT)util/intlist.o
 
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 
@@ -983,7 +987,8 @@ clean:
        $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
        $(MAKE) -C Documentation/ clean
        $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
-       $(RM) $(OUTPUT)util/*-{bison,flex}*
+       $(RM) $(OUTPUT)util/*-bison*
+       $(RM) $(OUTPUT)util/*-flex*
        $(python-clean)
 
 .PHONY: all install clean strip $(LIBTRACEEVENT)
index f5a6452931e6dabaa4f3b4593ab91f30aa7d586b..4db6e1ba54e30bf780d990a8fb1d7b203e89707f 100644 (file)
@@ -313,7 +313,7 @@ try_again:
                }
        }
 
-       perf_session__update_sample_type(session);
+       perf_session__set_id_hdr_size(session);
 }
 
 static int process_buildids(struct perf_record *rec)
@@ -844,8 +844,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
        struct perf_record *rec = &record;
        char errbuf[BUFSIZ];
 
-       perf_header__set_cmdline(argc, argv);
-
        evsel_list = perf_evlist__new(NULL, NULL);
        if (evsel_list == NULL)
                return -ENOMEM;
index 69b1c1185159174f070425d15c17afc8d5325f50..7c88a243b5db04308c9faf2e6aaf32d19bf0bb54 100644 (file)
@@ -249,8 +249,9 @@ static int process_read_event(struct perf_tool *tool,
 static int perf_report__setup_sample_type(struct perf_report *rep)
 {
        struct perf_session *self = rep->session;
+       u64 sample_type = perf_evlist__sample_type(self->evlist);
 
-       if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) {
+       if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
                if (sort__has_parent) {
                        ui__error("Selected --sort parent, but no "
                                    "callchain data. Did you call "
@@ -274,7 +275,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
 
        if (sort__branch_mode == 1) {
                if (!self->fd_pipe &&
-                   !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) {
+                   !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
                        ui__error("Selected -b but no branch data. "
                                  "Did you call perf record without -b?\n");
                        return -1;
index d909eb74a0eb74bc46ec8a9e6cb9d8acca5da7f2..1d592f5cbea9776fcc437e012dc20c1911fd7137 100644 (file)
@@ -478,7 +478,6 @@ static int test__basic_mmap(void)
        unsigned int nr_events[nsyscalls],
                     expected_nr_events[nsyscalls], i, j;
        struct perf_evsel *evsels[nsyscalls], *evsel;
-       int sample_size = __perf_evsel__sample_size(attr.sample_type);
 
        for (i = 0; i < nsyscalls; ++i) {
                char name[64];
@@ -563,8 +562,7 @@ static int test__basic_mmap(void)
                        goto out_munmap;
                }
 
-               err = perf_event__parse_sample(event, attr.sample_type, sample_size,
-                                              false, &sample, false);
+               err = perf_evlist__parse_sample(evlist, event, &sample, false);
                if (err) {
                        pr_err("Can't parse sample, err = %d\n", err);
                        goto out_munmap;
@@ -661,12 +659,12 @@ static int test__PERF_RECORD(void)
        const char *cmd = "sleep";
        const char *argv[] = { cmd, "1", NULL, };
        char *bname;
-       u64 sample_type, prev_time = 0;
+       u64 prev_time = 0;
        bool found_cmd_mmap = false,
             found_libc_mmap = false,
             found_vdso_mmap = false,
             found_ld_mmap = false;
-       int err = -1, errs = 0, i, wakeups = 0, sample_size;
+       int err = -1, errs = 0, i, wakeups = 0;
        u32 cpu;
        int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, };
 
@@ -756,13 +754,6 @@ static int test__PERF_RECORD(void)
                goto out_delete_evlist;
        }
 
-       /*
-        * We'll need these two to parse the PERF_SAMPLE_* fields in each
-        * event.
-        */
-       sample_type = perf_evlist__sample_type(evlist);
-       sample_size = __perf_evsel__sample_size(sample_type);
-
        /*
         * Now that all is properly set up, enable the events, they will
         * count just on workload.pid, which will start...
@@ -788,9 +779,7 @@ static int test__PERF_RECORD(void)
                                if (type < PERF_RECORD_MAX)
                                        nr_events[type]++;
 
-                               err = perf_event__parse_sample(event, sample_type,
-                                                              sample_size, true,
-                                                              &sample, false);
+                               err = perf_evlist__parse_sample(evlist, event, &sample, false);
                                if (err < 0) {
                                        if (verbose)
                                                perf_event__fprintf(event, stderr);
index 35e86c6df713d7af91bc50f98953d55f08cc4162..68cd61ef6ac5440c57579e42a935261d440e20f2 100644 (file)
@@ -38,6 +38,7 @@
 #include "util/cpumap.h"
 #include "util/xyarray.h"
 #include "util/sort.h"
+#include "util/intlist.h"
 
 #include "util/debug.h"
 
@@ -706,8 +707,16 @@ static void perf_event__process_sample(struct perf_tool *tool,
        int err;
 
        if (!machine && perf_guest) {
-               pr_err("Can't find guest [%d]'s kernel information\n",
-                       event->ip.pid);
+               static struct intlist *seen;
+
+               if (!seen)
+                       seen = intlist__new();
+
+               if (!intlist__has_entry(seen, event->ip.pid)) {
+                       pr_err("Can't find guest [%d]'s kernel information\n",
+                               event->ip.pid);
+                       intlist__add(seen, event->ip.pid);
+               }
                return;
        }
 
@@ -811,7 +820,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
        int ret;
 
        while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) {
-               ret = perf_session__parse_sample(session, event, &sample);
+               ret = perf_evlist__parse_sample(top->evlist, event, &sample, false);
                if (ret) {
                        pr_err("Can't parse sample, err = %d\n", ret);
                        continue;
@@ -943,8 +952,10 @@ try_again:
                         * based cpu-clock-tick sw counter, which
                         * is always available even if no PMU support:
                         */
-                       if (attr->type == PERF_TYPE_HARDWARE &&
-                           attr->config == PERF_COUNT_HW_CPU_CYCLES) {
+                       if ((err == ENOENT || err == ENXIO) &&
+                           (attr->type == PERF_TYPE_HARDWARE) &&
+                           (attr->config == PERF_COUNT_HW_CPU_CYCLES)) {
+
                                if (verbose)
                                        ui__warning("Cycles event not supported,\n"
                                                    "trying to fall back to cpu-clock-ticks\n");
@@ -1032,7 +1043,7 @@ static int __cmd_top(struct perf_top *top)
                                               &top->session->host_machine);
        perf_top__start_counters(top);
        top->session->evlist = top->evlist;
-       perf_session__update_sample_type(top->session);
+       perf_session__set_id_hdr_size(top->session);
 
        /* Wait for a minimal set of events before starting the snapshot */
        poll(top->evlist->pollfd, top->evlist->nr_fds, 100);
index 1b197280c621fea866e3bfd90f71f3213971ee4a..d84870b0642627b11b81b5b5dc1c0abade1a09e4 100644 (file)
@@ -197,9 +197,6 @@ int perf_event__preprocess_sample(const union perf_event *self,
 
 const char *perf_event__name(unsigned int id);
 
-int perf_event__parse_sample(const union perf_event *event, u64 type,
-                            int sample_size, bool sample_id_all,
-                            struct perf_sample *sample, bool swapped);
 int perf_event__synthesize_sample(union perf_event *event, u64 type,
                                  const struct perf_sample *sample,
                                  bool swapped);
index 3edfd3483816dfa88ac49dc966d0c2a4db2b5923..9b38681add9e2d46e3a02b8ca0ffe48363a3e3c5 100644 (file)
@@ -881,3 +881,10 @@ int perf_evlist__start_workload(struct perf_evlist *evlist)
 
        return 0;
 }
+
+int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
+                             struct perf_sample *sample, bool swapped)
+{
+       struct perf_evsel *e = list_entry(evlist->entries.next, struct perf_evsel, node);
+       return perf_evsel__parse_sample(e, event, sample, swapped);
+}
index 40d4d3cdced0e081ec41863abe6ab46c562a3e3a..528c1acd9298443ce37afee8a2f3be515f49adfe 100644 (file)
@@ -122,6 +122,9 @@ u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
 bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
 u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist);
 
+int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
+                             struct perf_sample *sample, bool swapped);
+
 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
 
index e81771364867bd2b5d7bf52e38e9ae0984316a0a..2eaae140def26b5ef952d814e47a1a3179d8abbb 100644 (file)
@@ -20,7 +20,7 @@
 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
 #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0))
 
-int __perf_evsel__sample_size(u64 sample_type)
+static int __perf_evsel__sample_size(u64 sample_type)
 {
        u64 mask = sample_type & PERF_SAMPLE_MASK;
        int size = 0;
@@ -53,6 +53,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
        evsel->attr        = *attr;
        INIT_LIST_HEAD(&evsel->node);
        hists__init(&evsel->hists);
+       evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
 }
 
 struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
@@ -728,10 +729,10 @@ static bool sample_overlap(const union perf_event *event,
        return false;
 }
 
-int perf_event__parse_sample(const union perf_event *event, u64 type,
-                            int sample_size, bool sample_id_all,
+int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
                             struct perf_sample *data, bool swapped)
 {
+       u64 type = evsel->attr.sample_type;
        const u64 *array;
 
        /*
@@ -746,14 +747,14 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
        data->period = 1;
 
        if (event->header.type != PERF_RECORD_SAMPLE) {
-               if (!sample_id_all)
+               if (!evsel->attr.sample_id_all)
                        return 0;
                return perf_event__parse_id_sample(event, type, data, swapped);
        }
 
        array = event->sample.array;
 
-       if (sample_size + sizeof(event->header) > event->header.size)
+       if (evsel->sample_size + sizeof(event->header) > event->header.size)
                return -EFAULT;
 
        if (type & PERF_SAMPLE_IP) {
@@ -895,7 +896,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
                u.val32[1] = sample->tid;
                if (swapped) {
                        /*
-                        * Inverse of what is done in perf_event__parse_sample
+                        * Inverse of what is done in perf_evsel__parse_sample
                         */
                        u.val32[0] = bswap_32(u.val32[0]);
                        u.val32[1] = bswap_32(u.val32[1]);
@@ -930,7 +931,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
                u.val32[0] = sample->cpu;
                if (swapped) {
                        /*
-                        * Inverse of what is done in perf_event__parse_sample
+                        * Inverse of what is done in perf_evsel__parse_sample
                         */
                        u.val32[0] = bswap_32(u.val32[0]);
                        u.val64 = bswap_64(u.val64);
index 67cc5033d19234e28071523f51ecf7c7186822b1..b559929983bbefd2e991fdf26e338fe588570a66 100644 (file)
@@ -65,6 +65,7 @@ struct perf_evsel {
                void            *func;
                void            *data;
        } handler;
+       unsigned int            sample_size;
        bool                    supported;
 };
 
@@ -177,13 +178,8 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
        return __perf_evsel__read(evsel, ncpus, nthreads, true);
 }
 
-int __perf_evsel__sample_size(u64 sample_type);
-
-static inline int perf_evsel__sample_size(struct perf_evsel *evsel)
-{
-       return __perf_evsel__sample_size(evsel->attr.sample_type);
-}
-
 void hists__init(struct hists *hists);
 
+int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
+                            struct perf_sample *sample, bool swapped);
 #endif /* __PERF_EVSEL_H */
index 3a6d20443330b13d74b2b69b4c1d0e39cd5bb678..74ea3c2f81382c2881d9eda1e1cfb451b2a138f7 100644 (file)
@@ -174,6 +174,15 @@ perf_header__set_cmdline(int argc, const char **argv)
 {
        int i;
 
+       /*
+        * If header_argv has already been set, do not override it.
+        * This allows a command to set the cmdline, parse args and
+        * then call another builtin function that implements a
+        * command -- e.g, cmd_kvm calling cmd_record.
+        */
+       if (header_argv)
+               return 0;
+
        header_argc = (u32)argc;
 
        /* do not include NULL termination */
diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c
new file mode 100644 (file)
index 0000000..fd530dc
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Based on intlist.c by:
+ * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
+ *
+ * Licensed under the GPLv2.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <linux/compiler.h>
+
+#include "intlist.h"
+
+static struct rb_node *intlist__node_new(struct rblist *rblist __used,
+                                        const void *entry)
+{
+       int i = (int)((long)entry);
+       struct rb_node *rc = NULL;
+       struct int_node *node = malloc(sizeof(*node));
+
+       if (node != NULL) {
+               node->i = i;
+               rc = &node->rb_node;
+       }
+
+       return rc;
+}
+
+static void int_node__delete(struct int_node *ilist)
+{
+       free(ilist);
+}
+
+static void intlist__node_delete(struct rblist *rblist __used,
+                                struct rb_node *rb_node)
+{
+       struct int_node *node = container_of(rb_node, struct int_node, rb_node);
+
+       int_node__delete(node);
+}
+
+static int intlist__node_cmp(struct rb_node *rb_node, const void *entry)
+{
+       int i = (int)((long)entry);
+       struct int_node *node = container_of(rb_node, struct int_node, rb_node);
+
+       return node->i - i;
+}
+
+int intlist__add(struct intlist *ilist, int i)
+{
+       return rblist__add_node(&ilist->rblist, (void *)((long)i));
+}
+
+void intlist__remove(struct intlist *ilist __used, struct int_node *node)
+{
+       int_node__delete(node);
+}
+
+struct int_node *intlist__find(struct intlist *ilist, int i)
+{
+       struct int_node *node = NULL;
+       struct rb_node *rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
+
+       if (rb_node)
+               node = container_of(rb_node, struct int_node, rb_node);
+
+       return node;
+}
+
+struct intlist *intlist__new(void)
+{
+       struct intlist *ilist = malloc(sizeof(*ilist));
+
+       if (ilist != NULL) {
+               rblist__init(&ilist->rblist);
+               ilist->rblist.node_cmp    = intlist__node_cmp;
+               ilist->rblist.node_new    = intlist__node_new;
+               ilist->rblist.node_delete = intlist__node_delete;
+       }
+
+       return ilist;
+}
+
+void intlist__delete(struct intlist *ilist)
+{
+       if (ilist != NULL)
+               rblist__delete(&ilist->rblist);
+}
+
+struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx)
+{
+       struct int_node *node = NULL;
+       struct rb_node *rb_node;
+
+       rb_node = rblist__entry(&ilist->rblist, idx);
+       if (rb_node)
+               node = container_of(rb_node, struct int_node, rb_node);
+
+       return node;
+}
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h
new file mode 100644 (file)
index 0000000..6d63ab9
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef __PERF_INTLIST_H
+#define __PERF_INTLIST_H
+
+#include <linux/rbtree.h>
+#include <stdbool.h>
+
+#include "rblist.h"
+
+struct int_node {
+       struct rb_node rb_node;
+       int i;
+};
+
+struct intlist {
+       struct rblist rblist;
+};
+
+struct intlist *intlist__new(void);
+void intlist__delete(struct intlist *ilist);
+
+void intlist__remove(struct intlist *ilist, struct int_node *in);
+int intlist__add(struct intlist *ilist, int i);
+
+struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx);
+struct int_node *intlist__find(struct intlist *ilist, int i);
+
+static inline bool intlist__has_entry(struct intlist *ilist, int i)
+{
+       return intlist__find(ilist, i) != NULL;
+}
+
+static inline bool intlist__empty(const struct intlist *ilist)
+{
+       return rblist__empty(&ilist->rblist);
+}
+
+static inline unsigned int intlist__nr_entries(const struct intlist *ilist)
+{
+       return rblist__nr_entries(&ilist->rblist);
+}
+
+/* For intlist iteration */
+static inline struct int_node *intlist__first(struct intlist *ilist)
+{
+       struct rb_node *rn = rb_first(&ilist->rblist.entries);
+       return rn ? rb_entry(rn, struct int_node, rb_node) : NULL;
+}
+static inline struct int_node *intlist__next(struct int_node *in)
+{
+       struct rb_node *rn;
+       if (!in)
+               return NULL;
+       rn = rb_next(&in->rb_node);
+       return rn ? rb_entry(rn, struct int_node, rb_node) : NULL;
+}
+
+/**
+ * intlist_for_each      - iterate over a intlist
+ * @pos:       the &struct int_node to use as a loop cursor.
+ * @ilist:     the &struct intlist for loop.
+ */
+#define intlist__for_each(pos, ilist)  \
+       for (pos = intlist__first(ilist); pos; pos = intlist__next(pos))
+
+/**
+ * intlist_for_each_safe - iterate over a intlist safe against removal of
+ *                         int_node
+ * @pos:       the &struct int_node to use as a loop cursor.
+ * @n:         another &struct int_node to use as temporary storage.
+ * @ilist:     the &struct intlist for loop.
+ */
+#define intlist__for_each_safe(pos, n, ilist)  \
+       for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\
+            pos = n, n = intlist__next(n))
+#endif /* __PERF_INTLIST_H */
index 1b997d2b89ce2638f63c01aee63c2b7884028427..127d648cc5488e6b1216ce3d3428c7a69e5157fb 100644 (file)
@@ -13,6 +13,9 @@ do { \
        } \
 } while (0)
 
+#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \
+                            PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
+
 static int test__checkevent_tracepoint(struct perf_evlist *evlist)
 {
        struct perf_evsel *evsel = list_entry(evlist->entries.next,
@@ -21,8 +24,7 @@ static int test__checkevent_tracepoint(struct perf_evlist *evlist)
        TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
        TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
        TEST_ASSERT_VAL("wrong sample_type",
-               (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
-               evsel->attr.sample_type);
+               PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
        TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
        return 0;
 }
@@ -37,8 +39,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
                TEST_ASSERT_VAL("wrong type",
                        PERF_TYPE_TRACEPOINT == evsel->attr.type);
                TEST_ASSERT_VAL("wrong sample_type",
-                       (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU)
-                       == evsel->attr.sample_type);
+                       PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
                TEST_ASSERT_VAL("wrong sample_period",
                        1 == evsel->attr.sample_period);
        }
@@ -428,8 +429,7 @@ static int test__checkevent_list(struct perf_evlist *evlist)
        evsel = list_entry(evsel->node.next, struct perf_evsel, node);
        TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
        TEST_ASSERT_VAL("wrong sample_type",
-               (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
-               evsel->attr.sample_type);
+               PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
        TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
        TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
        TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
index 99d02aa57dbf19a8c0cb1a1a3a900486ef956b65..594f8fad5ecd5ae3e858899173b1a18403335dc0 100644 (file)
@@ -1,6 +1,7 @@
 #include "util.h"
 #include "parse-options.h"
 #include "cache.h"
+#include "header.h"
 
 #define OPT_SHORT 1
 #define OPT_UNSET 2
@@ -413,6 +414,8 @@ int parse_options(int argc, const char **argv, const struct option *options,
 {
        struct parse_opt_ctx_t ctx;
 
+       perf_header__set_cmdline(argc, argv);
+
        parse_options_start(&ctx, argc, argv, flags);
        switch (parse_options_step(&ctx, options, usagestr)) {
        case PARSE_OPT_HELP:
index 2884e67ee625d6c41c8fb6a6fb495d843a6b86e7..213362850abdab31ca804db1a583dd5c38bdfbbd 100644 (file)
@@ -10,10 +10,12 @@ util/ctype.c
 util/evlist.c
 util/evsel.c
 util/cpumap.c
+util/hweight.c
 util/thread_map.c
 util/util.c
 util/xyarray.c
 util/cgroup.c
 util/debugfs.c
+util/rblist.c
 util/strlist.c
 ../../lib/rbtree.c
index e03b58a4842431d51edaf68ec6da95cec6caadf5..0688bfb6d280a3b8ae3b8c0e3a474f51b9a404c2 100644 (file)
@@ -797,17 +797,13 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
 
        event = perf_evlist__mmap_read(evlist, cpu);
        if (event != NULL) {
-               struct perf_evsel *first;
                PyObject *pyevent = pyrf_event__new(event);
                struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
 
                if (pyevent == NULL)
                        return PyErr_NoMemory();
 
-               first = list_entry(evlist->entries.next, struct perf_evsel, node);
-               err = perf_event__parse_sample(event, first->attr.sample_type,
-                                              perf_evsel__sample_size(first),
-                                              sample_id_all, &pevent->sample, false);
+               err = perf_evlist__parse_sample(evlist, event, &pevent->sample, false);
                if (err)
                        return PyErr_Format(PyExc_OSError,
                                            "perf: can't parse sample, err=%d", err);
diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c
new file mode 100644 (file)
index 0000000..0171fb6
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Based on strlist.c by:
+ * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
+ *
+ * Licensed under the GPLv2.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "rblist.h"
+
+int rblist__add_node(struct rblist *rblist, const void *new_entry)
+{
+       struct rb_node **p = &rblist->entries.rb_node;
+       struct rb_node *parent = NULL, *new_node;
+
+       while (*p != NULL) {
+               int rc;
+
+               parent = *p;
+
+               rc = rblist->node_cmp(parent, new_entry);
+               if (rc > 0)
+                       p = &(*p)->rb_left;
+               else if (rc < 0)
+                       p = &(*p)->rb_right;
+               else
+                       return -EEXIST;
+       }
+
+       new_node = rblist->node_new(rblist, new_entry);
+       if (new_node == NULL)
+               return -ENOMEM;
+
+       rb_link_node(new_node, parent, p);
+       rb_insert_color(new_node, &rblist->entries);
+       ++rblist->nr_entries;
+
+       return 0;
+}
+
+void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
+{
+       rb_erase(rb_node, &rblist->entries);
+       rblist->node_delete(rblist, rb_node);
+}
+
+struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
+{
+       struct rb_node **p = &rblist->entries.rb_node;
+       struct rb_node *parent = NULL;
+
+       while (*p != NULL) {
+               int rc;
+
+               parent = *p;
+
+               rc = rblist->node_cmp(parent, entry);
+               if (rc > 0)
+                       p = &(*p)->rb_left;
+               else if (rc < 0)
+                       p = &(*p)->rb_right;
+               else
+                       return parent;
+       }
+
+       return NULL;
+}
+
+void rblist__init(struct rblist *rblist)
+{
+       if (rblist != NULL) {
+               rblist->entries  = RB_ROOT;
+               rblist->nr_entries = 0;
+       }
+
+       return;
+}
+
+void rblist__delete(struct rblist *rblist)
+{
+       if (rblist != NULL) {
+               struct rb_node *pos, *next = rb_first(&rblist->entries);
+
+               while (next) {
+                       pos = next;
+                       next = rb_next(pos);
+                       rb_erase(pos, &rblist->entries);
+                       rblist->node_delete(rblist, pos);
+               }
+               free(rblist);
+       }
+}
+
+struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx)
+{
+       struct rb_node *node;
+
+       for (node = rb_first(&rblist->entries); node; node = rb_next(node)) {
+               if (!idx--)
+                       return node;
+       }
+
+       return NULL;
+}
diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h
new file mode 100644 (file)
index 0000000..6d0cae5
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __PERF_RBLIST_H
+#define __PERF_RBLIST_H
+
+#include <linux/rbtree.h>
+#include <stdbool.h>
+
+/*
+ * create node structs of the form:
+ * struct my_node {
+ *     struct rb_node rb_node;
+ *     ... my data ...
+ * };
+ *
+ * create list structs of the form:
+ * struct mylist {
+ *     struct rblist rblist;
+ *     ... my data ...
+ * };
+ */
+
+struct rblist {
+       struct rb_root entries;
+       unsigned int   nr_entries;
+
+       int (*node_cmp)(struct rb_node *rbn, const void *entry);
+       struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry);
+       void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node);
+};
+
+void rblist__init(struct rblist *rblist);
+void rblist__delete(struct rblist *rblist);
+int rblist__add_node(struct rblist *rblist, const void *new_entry);
+void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node);
+struct rb_node *rblist__find(struct rblist *rblist, const void *entry);
+struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx);
+
+static inline bool rblist__empty(const struct rblist *rblist)
+{
+       return rblist->nr_entries == 0;
+}
+
+static inline unsigned int rblist__nr_entries(const struct rblist *rblist)
+{
+       return rblist->nr_entries;
+}
+
+#endif /* __PERF_RBLIST_H */
index 8e4f0755d2aa8364d81fa714888d622d61f6a2db..2437fb0b463a21566ad9c8679861456e4f2b3f05 100644 (file)
@@ -80,14 +80,12 @@ out_close:
        return -1;
 }
 
-void perf_session__update_sample_type(struct perf_session *self)
+void perf_session__set_id_hdr_size(struct perf_session *session)
 {
-       self->sample_type = perf_evlist__sample_type(self->evlist);
-       self->sample_size = __perf_evsel__sample_size(self->sample_type);
-       self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
-       self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist);
-       self->host_machine.id_hdr_size = self->id_hdr_size;
-       machines__set_id_hdr_size(&self->machines, self->id_hdr_size);
+       u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist);
+
+       session->host_machine.id_hdr_size = id_hdr_size;
+       machines__set_id_hdr_size(&session->machines, id_hdr_size);
 }
 
 int perf_session__create_kernel_maps(struct perf_session *self)
@@ -147,7 +145,7 @@ struct perf_session *perf_session__new(const char *filename, int mode,
        if (mode == O_RDONLY) {
                if (perf_session__open(self, force) < 0)
                        goto out_delete;
-               perf_session__update_sample_type(self);
+               perf_session__set_id_hdr_size(self);
        } else if (mode == O_WRONLY) {
                /*
                 * In O_RDONLY mode this will be performed when reading the
@@ -158,7 +156,7 @@ struct perf_session *perf_session__new(const char *filename, int mode,
        }
 
        if (tool && tool->ordering_requires_timestamps &&
-           tool->ordered_samples && !self->sample_id_all) {
+           tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) {
                dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
                tool->ordered_samples = false;
        }
@@ -673,7 +671,8 @@ static void flush_sample_queue(struct perf_session *s,
                if (iter->timestamp > limit)
                        break;
 
-               ret = perf_session__parse_sample(s, iter->event, &sample);
+               ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample,
+                                               s->header.needs_swap);
                if (ret)
                        pr_err("Can't parse sample, err = %d\n", ret);
                else
@@ -865,16 +864,18 @@ static void perf_session__print_tstamp(struct perf_session *session,
                                       union perf_event *event,
                                       struct perf_sample *sample)
 {
+       u64 sample_type = perf_evlist__sample_type(session->evlist);
+
        if (event->header.type != PERF_RECORD_SAMPLE &&
-           !session->sample_id_all) {
+           !perf_evlist__sample_id_all(session->evlist)) {
                fputs("-1 -1 ", stdout);
                return;
        }
 
-       if ((session->sample_type & PERF_SAMPLE_CPU))
+       if ((sample_type & PERF_SAMPLE_CPU))
                printf("%u ", sample->cpu);
 
-       if (session->sample_type & PERF_SAMPLE_TIME)
+       if (sample_type & PERF_SAMPLE_TIME)
                printf("%" PRIu64 " ", sample->time);
 }
 
@@ -899,6 +900,8 @@ static void dump_event(struct perf_session *session, union perf_event *event,
 static void dump_sample(struct perf_session *session, union perf_event *event,
                        struct perf_sample *sample)
 {
+       u64 sample_type;
+
        if (!dump_trace)
                return;
 
@@ -906,10 +909,12 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
               event->header.misc, sample->pid, sample->tid, sample->ip,
               sample->period, sample->addr);
 
-       if (session->sample_type & PERF_SAMPLE_CALLCHAIN)
+       sample_type = perf_evlist__sample_type(session->evlist);
+
+       if (sample_type & PERF_SAMPLE_CALLCHAIN)
                callchain__printf(sample);
 
-       if (session->sample_type & PERF_SAMPLE_BRANCH_STACK)
+       if (sample_type & PERF_SAMPLE_BRANCH_STACK)
                branch_stack__printf(sample);
 }
 
@@ -1006,7 +1011,7 @@ static int perf_session__preprocess_sample(struct perf_session *session,
                                           union perf_event *event, struct perf_sample *sample)
 {
        if (event->header.type != PERF_RECORD_SAMPLE ||
-           !(session->sample_type & PERF_SAMPLE_CALLCHAIN))
+           !(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_CALLCHAIN))
                return 0;
 
        if (!ip_callchain__valid(sample->callchain, event)) {
@@ -1030,7 +1035,7 @@ static int perf_session__process_user_event(struct perf_session *session, union
        case PERF_RECORD_HEADER_ATTR:
                err = tool->attr(event, &session->evlist);
                if (err == 0)
-                       perf_session__update_sample_type(session);
+                       perf_session__set_id_hdr_size(session);
                return err;
        case PERF_RECORD_HEADER_EVENT_TYPE:
                return tool->event_type(tool, event);
@@ -1065,7 +1070,7 @@ static int perf_session__process_event(struct perf_session *session,
        int ret;
 
        if (session->header.needs_swap)
-               event_swap(event, session->sample_id_all);
+               event_swap(event, perf_evlist__sample_id_all(session->evlist));
 
        if (event->header.type >= PERF_RECORD_HEADER_MAX)
                return -EINVAL;
@@ -1078,7 +1083,8 @@ static int perf_session__process_event(struct perf_session *session,
        /*
         * For all kernel events we get the sample data
         */
-       ret = perf_session__parse_sample(session, event, &sample);
+       ret = perf_evlist__parse_sample(session->evlist, event, &sample,
+                                       session->header.needs_swap);
        if (ret)
                return ret;
 
@@ -1389,9 +1395,9 @@ int perf_session__process_events(struct perf_session *self,
        return err;
 }
 
-bool perf_session__has_traces(struct perf_session *self, const char *msg)
+bool perf_session__has_traces(struct perf_session *session, const char *msg)
 {
-       if (!(self->sample_type & PERF_SAMPLE_RAW)) {
+       if (!(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_RAW)) {
                pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg);
                return false;
        }
index 7c435bde6eb0ea1f913e1dadfca3da0c23432302..1f7ec87db7d7369083895d596a979db460865d23 100644 (file)
@@ -41,13 +41,9 @@ struct perf_session {
         *        perf.data file.
         */
        struct hists            hists;
-       u64                     sample_type;
-       int                     sample_size;
        int                     fd;
        bool                    fd_pipe;
        bool                    repipe;
-       bool                    sample_id_all;
-       u16                     id_hdr_size;
        int                     cwdlen;
        char                    *cwd;
        struct ordered_samples  ordered_samples;
@@ -86,7 +82,7 @@ void perf_event__attr_swap(struct perf_event_attr *attr);
 
 int perf_session__create_kernel_maps(struct perf_session *self);
 
-void perf_session__update_sample_type(struct perf_session *self);
+void perf_session__set_id_hdr_size(struct perf_session *session);
 void perf_session__remove_thread(struct perf_session *self, struct thread *th);
 
 static inline
@@ -130,24 +126,6 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self,
 
 size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp);
 
-static inline int perf_session__parse_sample(struct perf_session *session,
-                                            const union perf_event *event,
-                                            struct perf_sample *sample)
-{
-       return perf_event__parse_sample(event, session->sample_type,
-                                       session->sample_size,
-                                       session->sample_id_all, sample,
-                                       session->header.needs_swap);
-}
-
-static inline int perf_session__synthesize_sample(struct perf_session *session,
-                                                 union perf_event *event,
-                                                 const struct perf_sample *sample)
-{
-       return perf_event__synthesize_sample(event, session->sample_type,
-                                            sample, session->header.needs_swap);
-}
-
 struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
                                            unsigned int type);
 
index 6783a2043555404f393bcb3bd41e6a13d3495bc6..95856ff3dda417276792c98df568a56ea0c86bd8 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-static struct str_node *str_node__new(const char *s, bool dupstr)
+static
+struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry)
 {
-       struct str_node *self = malloc(sizeof(*self));
+       const char *s = entry;
+       struct rb_node *rc = NULL;
+       struct strlist *strlist = container_of(rblist, struct strlist, rblist);
+       struct str_node *snode = malloc(sizeof(*snode));
 
-       if (self != NULL) {
-               if (dupstr) {
+       if (snode != NULL) {
+               if (strlist->dupstr) {
                        s = strdup(s);
                        if (s == NULL)
                                goto out_delete;
                }
-               self->s = s;
+               snode->s = s;
+               rc = &snode->rb_node;
        }
 
-       return self;
+       return rc;
 
 out_delete:
-       free(self);
+       free(snode);
        return NULL;
 }
 
@@ -37,36 +42,26 @@ static void str_node__delete(struct str_node *self, bool dupstr)
        free(self);
 }
 
-int strlist__add(struct strlist *self, const char *new_entry)
+static
+void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node)
 {
-       struct rb_node **p = &self->entries.rb_node;
-       struct rb_node *parent = NULL;
-       struct str_node *sn;
-
-       while (*p != NULL) {
-               int rc;
-
-               parent = *p;
-               sn = rb_entry(parent, struct str_node, rb_node);
-               rc = strcmp(sn->s, new_entry);
-
-               if (rc > 0)
-                       p = &(*p)->rb_left;
-               else if (rc < 0)
-                       p = &(*p)->rb_right;
-               else
-                       return -EEXIST;
-       }
+       struct strlist *slist = container_of(rblist, struct strlist, rblist);
+       struct str_node *snode = container_of(rb_node, struct str_node, rb_node);
 
-       sn = str_node__new(new_entry, self->dupstr);
-       if (sn == NULL)
-               return -ENOMEM;
+       str_node__delete(snode, slist->dupstr);
+}
 
-       rb_link_node(&sn->rb_node, parent, p);
-       rb_insert_color(&sn->rb_node, &self->entries);
-       ++self->nr_entries;
+static int strlist__node_cmp(struct rb_node *rb_node, const void *entry)
+{
+       const char *str = entry;
+       struct str_node *snode = container_of(rb_node, struct str_node, rb_node);
+
+       return strcmp(snode->s, str);
+}
 
-       return 0;
+int strlist__add(struct strlist *self, const char *new_entry)
+{
+       return rblist__add_node(&self->rblist, new_entry);
 }
 
 int strlist__load(struct strlist *self, const char *filename)
@@ -96,34 +91,20 @@ out:
        return err;
 }
 
-void strlist__remove(struct strlist *self, struct str_node *sn)
+void strlist__remove(struct strlist *slist, struct str_node *snode)
 {
-       rb_erase(&sn->rb_node, &self->entries);
-       str_node__delete(sn, self->dupstr);
+       str_node__delete(snode, slist->dupstr);
 }
 
-struct str_node *strlist__find(struct strlist *self, const char *entry)
+struct str_node *strlist__find(struct strlist *slist, const char *entry)
 {
-       struct rb_node **p = &self->entries.rb_node;
-       struct rb_node *parent = NULL;
-
-       while (*p != NULL) {
-               struct str_node *sn;
-               int rc;
-
-               parent = *p;
-               sn = rb_entry(parent, struct str_node, rb_node);
-               rc = strcmp(sn->s, entry);
-
-               if (rc > 0)
-                       p = &(*p)->rb_left;
-               else if (rc < 0)
-                       p = &(*p)->rb_right;
-               else
-                       return sn;
-       }
+       struct str_node *snode = NULL;
+       struct rb_node *rb_node = rblist__find(&slist->rblist, entry);
 
-       return NULL;
+       if (rb_node)
+               snode = container_of(rb_node, struct str_node, rb_node);
+
+       return snode;
 }
 
 static int strlist__parse_list_entry(struct strlist *self, const char *s)
@@ -156,9 +137,12 @@ struct strlist *strlist__new(bool dupstr, const char *slist)
        struct strlist *self = malloc(sizeof(*self));
 
        if (self != NULL) {
-               self->entries    = RB_ROOT;
+               rblist__init(&self->rblist);
+               self->rblist.node_cmp    = strlist__node_cmp;
+               self->rblist.node_new    = strlist__node_new;
+               self->rblist.node_delete = strlist__node_delete;
+
                self->dupstr     = dupstr;
-               self->nr_entries = 0;
                if (slist && strlist__parse_list(self, slist) != 0)
                        goto out_error;
        }
@@ -171,30 +155,18 @@ out_error:
 
 void strlist__delete(struct strlist *self)
 {
-       if (self != NULL) {
-               struct str_node *pos;
-               struct rb_node *next = rb_first(&self->entries);
-
-               while (next) {
-                       pos = rb_entry(next, struct str_node, rb_node);
-                       next = rb_next(&pos->rb_node);
-                       strlist__remove(self, pos);
-               }
-               self->entries = RB_ROOT;
-               free(self);
-       }
+       if (self != NULL)
+               rblist__delete(&self->rblist);
 }
 
-struct str_node *strlist__entry(const struct strlist *self, unsigned int idx)
+struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx)
 {
-       struct rb_node *nd;
+       struct str_node *snode = NULL;
+       struct rb_node *rb_node;
 
-       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
-               struct str_node *pos = rb_entry(nd, struct str_node, rb_node);
+       rb_node = rblist__entry(&slist->rblist, idx);
+       if (rb_node)
+               snode = container_of(rb_node, struct str_node, rb_node);
 
-               if (!idx--)
-                       return pos;
-       }
-
-       return NULL;
+       return snode;
 }
index 3ba839007d2c975c49e4f3f286e9d64eff3d3f60..dd9f922ec67c58845ff22b6d3fabe3eb888c21e6 100644 (file)
@@ -4,14 +4,15 @@
 #include <linux/rbtree.h>
 #include <stdbool.h>
 
+#include "rblist.h"
+
 struct str_node {
        struct rb_node rb_node;
        const char     *s;
 };
 
 struct strlist {
-       struct rb_root entries;
-       unsigned int   nr_entries;
+       struct rblist rblist;
        bool           dupstr;
 };
 
@@ -32,18 +33,18 @@ static inline bool strlist__has_entry(struct strlist *self, const char *entry)
 
 static inline bool strlist__empty(const struct strlist *self)
 {
-       return self->nr_entries == 0;
+       return rblist__empty(&self->rblist);
 }
 
 static inline unsigned int strlist__nr_entries(const struct strlist *self)
 {
-       return self->nr_entries;
+       return rblist__nr_entries(&self->rblist);
 }
 
 /* For strlist iteration */
 static inline struct str_node *strlist__first(struct strlist *self)
 {
-       struct rb_node *rn = rb_first(&self->entries);
+       struct rb_node *rn = rb_first(&self->rblist.entries);
        return rn ? rb_entry(rn, struct str_node, rb_node) : NULL;
 }
 static inline struct str_node *strlist__next(struct str_node *sn)
index fdad4eeeb429c1fce9ef90125aab3e4a288c6066..8b63b678e127ba5253477db6c65355e28ae49e66 100644 (file)
@@ -64,7 +64,7 @@ static enum dso_binary_type binary_type_symtab[] = {
        DSO_BINARY_TYPE__NOT_FOUND,
 };
 
-#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab)
+#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
 
 static enum dso_binary_type binary_type_data[] = {
        DSO_BINARY_TYPE__BUILD_ID_CACHE,
@@ -72,7 +72,7 @@ static enum dso_binary_type binary_type_data[] = {
        DSO_BINARY_TYPE__NOT_FOUND,
 };
 
-#define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data)
+#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data)
 
 int dso__name_len(const struct dso *dso)
 {
@@ -2875,6 +2875,7 @@ int machines__create_guest_kernel_maps(struct rb_root *machines)
        int i, items = 0;
        char path[PATH_MAX];
        pid_t pid;
+       char *endp;
 
        if (symbol_conf.default_guest_vmlinux_name ||
            symbol_conf.default_guest_modules ||
@@ -2891,7 +2892,14 @@ int machines__create_guest_kernel_maps(struct rb_root *machines)
                                /* Filter out . and .. */
                                continue;
                        }
-                       pid = atoi(namelist[i]->d_name);
+                       pid = (pid_t)strtol(namelist[i]->d_name, &endp, 10);
+                       if ((*endp != '\0') ||
+                           (endp == namelist[i]->d_name) ||
+                           (errno == ERANGE)) {
+                               pr_debug("invalid directory (%s). Skipping.\n",
+                                        namelist[i]->d_name);
+                               continue;
+                       }
                        sprintf(path, "%s/%s/proc/kallsyms",
                                symbol_conf.guestmount,
                                namelist[i]->d_name);
index 3f59c496e64c9035311389fb73e9468fb47e7889..051eaa68095e75a61b82aac4c479cf4c8101ef71 100644 (file)
@@ -110,7 +110,7 @@ int perf_target__strerror(struct perf_target *target, int errnum,
        int idx;
        const char *msg;
 
-       BUG_ON(buflen > 0);
+       BUG_ON(buflen == 0);
 
        if (errnum >= 0) {
                const char *err = strerror_r(errnum, buf, buflen);
index 246852397e301ee86ac5c40f653e4695eae659a8..d617f69131d7667d3847c7e0fc040a717625bf38 100644 (file)
@@ -1976,9 +1976,10 @@ static long kvm_vcpu_compat_ioctl(struct file *filp,
                        if (copy_from_user(&csigset, sigmask_arg->sigset,
                                           sizeof csigset))
                                goto out;
-               }
-               sigset_from_compat(&sigset, &csigset);
-               r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
+                       sigset_from_compat(&sigset, &csigset);
+                       r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
+               } else
+                       r = kvm_vcpu_ioctl_set_sigmask(vcpu, NULL);
                break;
        }
        default: